Browse Source

connection: логировать только connect/reconnect/disconnect; фиксы конфига чатгуи

- категория connection теперь только жизненный цикл соединения; INIT/PING/keepalive
  переклассифицированы в ETCP/SOCKET/KEEPALIVE/REALITY/ROUTING, удалены дубли
- settingsdialog: устранён дубль my_node_name в конфиге (двухпроходная запись + только при изменении)
- storagesettingspage: канонические ключи storage_total_size/storage_unit_size с суффиксом M/G
- audiodevicesettingspage: compressor_max_gain_db min 0→1
- etcp_connections: %s-баг в логе TCP link (addr → sockaddr_storage_to_str)
- docs/sample: [chatserver], актуализированы ключи хранилища
v2
evgeny 3 weeks ago
parent
commit
b7da6547c1
  1. 10
      AGENTS.md
  2. 2
      lib/debug_config.h
  3. 14
      lib/getmyip.c
  4. 2
      src/routing_layer/conn_mgr_core.c
  5. 4
      src/transport_layer/etcp.c
  6. 246
      src/transport_layer/etcp_connections.c
  7. 8
      src/transport_layer/node_conn_direct.c
  8. 6
      tools/chatgui-android/AGENTS.md
  9. 2
      tools/chatgui/src/audiodevicesettingspage.cpp
  10. 59
      tools/chatgui/src/settingsdialog.cpp
  11. 4
      tools/chatgui/src/storagesettingspage.cpp
  12. 5
      utun.conf.sample

10
AGENTS.md

@ -221,7 +221,7 @@ sc_obfuscate_pubkey(salt, peer_pubkey_bin, my_pubkey_bin, obfuscated_output);
### Debug Levels ### Debug Levels
`none < error < warn < info < debug < trace` `none < error < warn < info < debug < trace`
trace - логируем заходы в функции и важные ветвления внутри функций trace - логируем заходы в функции и важные ветвления внутри функций
debug - всё что нужно для понимание сути происходящего (состояний, важных переменных) алгоритма. тоесть по уровню debug мы должны видеть все важные внутреннии нюансы работы функции включая состояния и переменные. debug - отладка: всё что нужно для понимание сути происходящего (состояний, важных переменных) алгоритма. тоесть по уровню debug мы должны видеть все важные внутреннии нюансы работы функции включая состояния и переменные.
info - сообщения для пользователя о работе. мы должны видеть в читаемом виде понятные и осмысленные сообщения о каких-либо значимых действиях с точки зрения логики работы модуля или приложения info - сообщения для пользователя о работе. мы должны видеть в читаемом виде понятные и осмысленные сообщения о каких-либо значимых действиях с точки зрения логики работы модуля или приложения
warn / error - ошибки и предупреждения (аномалии). должны быть во всех ошибочных ветках. Молча вываливаться с ошибкой нельзя, все ошибки и предупреждения должны логироваться. warn / error - ошибки и предупреждения (аномалии). должны быть во всех ошибочных ветках. Молча вываливаться с ошибкой нельзя, все ошибки и предупреждения должны логироваться.
@ -449,12 +449,12 @@ MEMBER_SYNC=27
## Config Rules ## Config Rules
- В серверном конфиге только собственные ключи и нет секций `[client]` - В серверном конфиге только собственные ключи и нет секций `[client]`
- В клиентском конфиге есть собственные ключи и pubkey каждого сервера в секции `[client]` - В клиентском конфиге есть собственные ключи и pubkey каждого сервера в секции `[client]`
- Chat-настройки хранятся в секции `[chat]`. Парсер вызывает `chat_setting_set(key, value)` для каждого ключа — неизвестные ключи вызывают ошибку. Пример: - Chat-настройки хранятся в секции `[chatserver]` (принимается также `[chat]`). Парсер вызывает `chat_setting_set(key, value)` для каждого ключа — неизвестные ключи вызывают ошибку. Пример:
```ini ```ini
[chat] [chatserver]
storage_autoload=1 storage_autoload=1
storage_autoload_maxsize_mb=10 storage_unit_size=10M
storage_maxsize_gb=1 storage_total_size=1G
opus_codec_preset=1 opus_codec_preset=1
compressor_enabled=0 compressor_enabled=0
compressor_max_gain_db=25 compressor_max_gain_db=25

2
lib/debug_config.h

@ -41,7 +41,7 @@ typedef int debug_category_t;
#define DEBUG_CATEGORY_NONE 0 #define DEBUG_CATEGORY_NONE 0
#define DEBUG_CATEGORY_SYS 1 // System: u_async, ll_queue, memory, timing #define DEBUG_CATEGORY_SYS 1 // System: u_async, ll_queue, memory, timing
// #define DEBUG_CATEGORY_LL_QUEUE 2 (merged into SYS) // #define DEBUG_CATEGORY_LL_QUEUE 2 (merged into SYS)
#define DEBUG_CATEGORY_CONNECTION 3 // Connection: links, keepalive, status events #define DEBUG_CATEGORY_CONNECTION 3 // Connection: connect/reconnect/disconnect events only
#define DEBUG_CATEGORY_ETCP 4 // ETCP: protocol, BBR, normalizer #define DEBUG_CATEGORY_ETCP 4 // ETCP: protocol, BBR, normalizer
#define DEBUG_CATEGORY_CRYPTO 5 // crypto operations #define DEBUG_CATEGORY_CRYPTO 5 // crypto operations
// #define DEBUG_CATEGORY_MEMORY 6 (merged into SYS) // #define DEBUG_CATEGORY_MEMORY 6 (merged into SYS)

14
lib/getmyip.c

@ -23,24 +23,24 @@ int get_outgoing_local_ip(const struct sockaddr_storage *local_addr,
struct sockaddr_storage *result) struct sockaddr_storage *result)
{ {
if (!local_addr || !remote_addr || !result) { if (!local_addr || !remote_addr || !result) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "get_outgoing_local_ip: NULL argument"); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "get_outgoing_local_ip: NULL argument");
return -1; return -1;
} }
int family = local_addr->ss_family; int family = local_addr->ss_family;
if (family != AF_INET && family != AF_INET6) { if (family != AF_INET && family != AF_INET6) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "get_outgoing_local_ip: unsupported family %d", family); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "get_outgoing_local_ip: unsupported family %d", family);
return -1; return -1;
} }
if (remote_addr->ss_family != family) { if (remote_addr->ss_family != family) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "get_outgoing_local_ip: family mismatch"); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "get_outgoing_local_ip: family mismatch");
return -1; return -1;
} }
socket_t sock = socket_create_udp(family); socket_t sock = socket_create_udp(family);
if (sock == SOCKET_INVALID) { if (sock == SOCKET_INVALID) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "get_outgoing_local_ip: socket_create_udp failed"); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "get_outgoing_local_ip: socket_create_udp failed");
return -1; return -1;
} }
@ -56,7 +56,7 @@ int get_outgoing_local_ip(const struct sockaddr_storage *local_addr,
socklen_t bind_len = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); socklen_t bind_len = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
if (bind(sock, (struct sockaddr *)&bind_addr, bind_len) != 0) { if (bind(sock, (struct sockaddr *)&bind_addr, bind_len) != 0) {
int err = socket_get_error(); int err = socket_get_error();
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "get_outgoing_local_ip: bind failed: %s", socket_strerror(err)); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "get_outgoing_local_ip: bind failed: %s", socket_strerror(err));
socket_close_wrapper(sock); socket_close_wrapper(sock);
return -1; return -1;
} }
@ -65,7 +65,7 @@ int get_outgoing_local_ip(const struct sockaddr_storage *local_addr,
socklen_t remote_len = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6); socklen_t remote_len = (family == AF_INET) ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
if (connect(sock, (struct sockaddr *)remote_addr, remote_len) != 0) { if (connect(sock, (struct sockaddr *)remote_addr, remote_len) != 0) {
int err = socket_get_error(); int err = socket_get_error();
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "get_outgoing_local_ip: connect failed: %s", socket_strerror(err)); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "get_outgoing_local_ip: connect failed: %s", socket_strerror(err));
socket_close_wrapper(sock); socket_close_wrapper(sock);
return -1; return -1;
} }
@ -75,7 +75,7 @@ int get_outgoing_local_ip(const struct sockaddr_storage *local_addr,
socklen_t local_len = sizeof(local); socklen_t local_len = sizeof(local);
if (getsockname(sock, (struct sockaddr *)&local, &local_len) != 0) { if (getsockname(sock, (struct sockaddr *)&local, &local_len) != 0) {
int err = socket_get_error(); int err = socket_get_error();
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "get_outgoing_local_ip: getsockname failed: %s", socket_strerror(err)); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "get_outgoing_local_ip: getsockname failed: %s", socket_strerror(err));
socket_close_wrapper(sock); socket_close_wrapper(sock);
return -1; return -1;
} }

2
src/routing_layer/conn_mgr_core.c

@ -740,7 +740,7 @@ void cm_handle_disconnect(struct CONN_MGR* mgr, uint64_t node_id) {
void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) { void conn_mgr_router_recv_handler(struct ETCP_CONN* conn, struct ll_entry* entry) {
if (!entry || !entry->dgram || entry->len < ROUTER_SVC_PAYLOAD_OFF + 2) return; if (!entry || !entry->dgram || entry->len < ROUTER_SVC_PAYLOAD_OFF + 2) return;
if (!conn || !conn->instance) { if (!conn || !conn->instance) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "conn_mgr_router_recv: conn=%p", (void*)conn); DEBUG_ERROR(DEBUG_CATEGORY_ROUTING, "conn_mgr_router_recv: conn=%p", (void*)conn);
return; return;
} }
uint8_t* d = entry->dgram + ROUTER_SVC_PAYLOAD_OFF; size_t len = entry->len - ROUTER_SVC_PAYLOAD_OFF; uint8_t sub = d[1]; uint8_t* d = entry->dgram + ROUTER_SVC_PAYLOAD_OFF; size_t len = entry->len - ROUTER_SVC_PAYLOAD_OFF; uint8_t sub = d[1];

4
src/transport_layer/etcp.c

@ -199,7 +199,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
struct ETCP_CONN* etcp = u_calloc(1, sizeof(struct ETCP_CONN)); struct ETCP_CONN* etcp = u_calloc(1, sizeof(struct ETCP_CONN));
if (!etcp) { if (!etcp) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "creating connection failed for instance %p", instance); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "creating connection failed for instance %p", instance);
return NULL; return NULL;
} }
@ -230,7 +230,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
if (!etcp->input_queue || !etcp->output_queue || !etcp->transit_queues || if (!etcp->input_queue || !etcp->output_queue || !etcp->transit_queues ||
!etcp->input_send_q || !etcp->recv_q || !etcp->ack_q || !etcp->input_send_q || !etcp->recv_q || !etcp->ack_q ||
!etcp->input_wait_ack || !etcp->inflight_pool || !etcp->io_pool) { !etcp->input_wait_ack || !etcp->inflight_pool || !etcp->io_pool) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "error - closing - input:%p output:%p send:%p wait:%x pool:%p", DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "error - closing - input:%p output:%p send:%p wait:%x pool:%p",
etcp->input_queue, etcp->output_queue, etcp->input_send_q, etcp->input_wait_ack, etcp->inflight_pool); etcp->input_queue, etcp->output_queue, etcp->input_send_q, etcp->input_wait_ack, etcp->inflight_pool);
etcp_connection_close(etcp); etcp_connection_close(etcp);
return NULL; return NULL;

246
src/transport_layer/etcp_connections.c

@ -143,14 +143,14 @@ static void burst_resp_timeout_cb(void* arg) {
#define INIT_TIMEOUT_MAX 50000 #define INIT_TIMEOUT_MAX 50000
static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset, uint8_t collision) { static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset, uint8_t collision) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "link=%p, is_server=%d, reset=%d, collision=%d", link, link ? link->is_server : -1, reset, collision); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "link=%p, is_server=%d, reset=%d, collision=%d", link, link ? link->is_server : -1, reset, collision);
if (!link || !link->etcp || !link->etcp->instance) return; if (!link || !link->etcp || !link->etcp->instance) return;
if (link->is_tcp) return; // TCP uses STCP handshake instead of ETCP INIT if (link->is_tcp) return; // TCP uses STCP handshake instead of ETCP INIT
struct ETCP_DGRAM* dgram = u_malloc(PACKET_DATA_SIZE); struct ETCP_DGRAM* dgram = u_malloc(PACKET_DATA_SIZE);
if (!dgram) { if (!dgram) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "malloc failed"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "malloc failed");
return; return;
} }
@ -246,7 +246,7 @@ static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset, uint8_t c
} }
static void etcp_link_init_timer_cbk(void* arg) { static void etcp_link_init_timer_cbk(void* arg) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
struct ETCP_LINK* link = (struct ETCP_LINK*)arg; struct ETCP_LINK* link = (struct ETCP_LINK*)arg;
if (!link || !link->etcp || !link->etcp->instance) return; if (!link || !link->etcp || !link->etcp->instance) return;
@ -265,14 +265,14 @@ static void etcp_link_init_timer_cbk(void* arg) {
} }
void etcp_link_restart_init_timer(struct ETCP_LINK* link) { void etcp_link_restart_init_timer(struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (link->init_timer) uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer); if (link->init_timer) uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer);
link->init_timeout = INIT_TIMEOUT_INITIAL; link->init_timeout = INIT_TIMEOUT_INITIAL;
link->init_timer = uasync_set_timeout(link->etcp->instance->ua, link->init_timeout, link, etcp_link_init_timer_cbk, "link_init"); link->init_timer = uasync_set_timeout(link->etcp->instance->ua, link->init_timeout, link, etcp_link_init_timer_cbk, "link_init");
} }
void etcp_link_enter_init(struct ETCP_LINK* link) {// void etcp_link_enter_init(struct ETCP_LINK* link) {//
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!link) return; if (!link) return;
int old_state = link->link_state; int old_state = link->link_state;
link->link_state = LINK_STATE_HANDSHAKE; // handshake link->link_state = LINK_STATE_HANDSHAKE; // handshake
@ -284,7 +284,7 @@ void etcp_link_enter_init(struct ETCP_LINK* link) {//
} }
void etcp_link_enter_reinit(struct ETCP_LINK* link) { void etcp_link_enter_reinit(struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!link) return; if (!link) return;
int old_state = link->link_state; int old_state = link->link_state;
link->link_state = LINK_STATE_TRY_RECONNECT; // reconnect link->link_state = LINK_STATE_TRY_RECONNECT; // reconnect
@ -322,7 +322,7 @@ static void sockaddr_to_key(struct sockaddr_storage* addr, uint8_t key[LINK_ADDR
// find_link_index, realloc_links, insert_link, remove_link — УДАЛЕНЫ. Заменены на ll_queue с хеш-индексом. // find_link_index, realloc_links, insert_link, remove_link — УДАЛЕНЫ. Заменены на ll_queue с хеш-индексом.
static int insert_link_queue(struct ETCP_SOCKET* e_sock, struct ETCP_LINK* link) { static int insert_link_queue(struct ETCP_SOCKET* e_sock, struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!e_sock || !link || !e_sock->links_queue) return -1; if (!e_sock || !link || !e_sock->links_queue) return -1;
uint8_t key[LINK_ADDR_KEY_SIZE]; uint8_t key[LINK_ADDR_KEY_SIZE];
@ -336,7 +336,7 @@ static int insert_link_queue(struct ETCP_SOCKET* e_sock, struct ETCP_LINK* link)
uint64_t new_qkey = 0, old_qkey = 0; uint64_t new_qkey = 0, old_qkey = 0;
if (new_c->conn_queue_entry) new_qkey = ((struct conn_queue_entry*)new_c->conn_queue_entry->data)->peer_node_id; if (new_c->conn_queue_entry) new_qkey = ((struct conn_queue_entry*)new_c->conn_queue_entry->data)->peer_node_id;
if (old_c->conn_queue_entry) old_qkey = ((struct conn_queue_entry*)old_c->conn_queue_entry->data)->peer_node_id; if (old_c->conn_queue_entry) old_qkey = ((struct conn_queue_entry*)old_c->conn_queue_entry->data)->peer_node_id;
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, DEBUG_ERROR(DEBUG_CATEGORY_ETCP,
"!!!!!!!!!!!! LINK ADDR COLLISION !!!!!!!!!!!! addr=%s " "!!!!!!!!!!!! LINK ADDR COLLISION !!!!!!!!!!!! addr=%s "
"new: conn=%p [%s] peer=0x%016llx state=%d init=%d up=%d srv=%d tcp=%d qkey=0x%016llx " "new: conn=%p [%s] peer=0x%016llx state=%d init=%d up=%d srv=%d tcp=%d qkey=0x%016llx "
"old: conn=%p [%s] peer=0x%016llx state=%d init=%d up=%d srv=%d tcp=%d qkey=0x%016llx", "old: conn=%p [%s] peer=0x%016llx state=%d init=%d up=%d srv=%d tcp=%d qkey=0x%016llx",
@ -350,14 +350,14 @@ static int insert_link_queue(struct ETCP_SOCKET* e_sock, struct ETCP_LINK* link)
(unsigned long long)old_qkey); (unsigned long long)old_qkey);
return -1; return -1;
} }
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "insert_link_queue: replacing stale DUP addr in [%s] old_link=%p", e_sock->name, dup_lqe->link); DEBUG_WARN(DEBUG_CATEGORY_ETCP, "insert_link_queue: replacing stale DUP addr in [%s] old_link=%p", e_sock->name, dup_lqe->link);
if (dup_lqe->link) dup_lqe->link->link_queue_entry = NULL; if (dup_lqe->link) dup_lqe->link->link_queue_entry = NULL;
queue_remove_data(e_sock->links_queue, dup_qe); queue_remove_data(e_sock->links_queue, dup_qe);
queue_entry_free(dup_qe); queue_entry_free(dup_qe);
} }
struct ll_entry* qe = queue_entry_new(sizeof(struct link_queue_entry)); struct ll_entry* qe = queue_entry_new(sizeof(struct link_queue_entry));
if (!qe) { DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "queue_entry_new failed"); return -1; } if (!qe) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "queue_entry_new failed"); return -1; }
struct link_queue_entry* lqe = (struct link_queue_entry*)qe->data; struct link_queue_entry* lqe = (struct link_queue_entry*)qe->data;
memcpy(lqe->key, key, LINK_ADDR_KEY_SIZE); memcpy(lqe->key, key, LINK_ADDR_KEY_SIZE);
lqe->link = link; lqe->link = link;
@ -367,7 +367,7 @@ static int insert_link_queue(struct ETCP_SOCKET* e_sock, struct ETCP_LINK* link)
} }
static void remove_link_from_queue(struct ETCP_LINK* link) { static void remove_link_from_queue(struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!link || !link->link_queue_entry) return; if (!link || !link->link_queue_entry) return;
if (!link->conn || !link->conn->links_queue) return; if (!link->conn || !link->conn->links_queue) return;
queue_remove_data(link->conn->links_queue, link->link_queue_entry); queue_remove_data(link->conn->links_queue, link->link_queue_entry);
@ -391,7 +391,7 @@ static int sockaddr_equal(const struct sockaddr_storage* a, const struct sockadd
} }
struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sockaddr_storage* addr, int is_tcp) { struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sockaddr_storage* addr, int is_tcp) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!e_sock || !addr || !e_sock->links_queue) return NULL; if (!e_sock || !addr || !e_sock->links_queue) return NULL;
uint8_t key[LINK_ADDR_KEY_SIZE]; uint8_t key[LINK_ADDR_KEY_SIZE];
sockaddr_to_key(addr, key, is_tcp); sockaddr_to_key(addr, key, is_tcp);
@ -407,18 +407,18 @@ static void etcp_link_update_remote_addr(struct ETCP_LINK* link, struct ETCP_SOC
const struct sockaddr_storage* new_addr) { const struct sockaddr_storage* new_addr) {
if (!link || !e_sock || !new_addr) return; if (!link || !e_sock || !new_addr) return;
if (link->is_tcp) { if (link->is_tcp) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] update_remote_addr: TCP link skip", link->etcp->log_name); DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] update_remote_addr: TCP link skip", link->etcp->log_name);
return; return;
} }
if (link->conn != e_sock) { if (link->conn != e_sock) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] update_remote_addr: link socket [%s] != recv socket [%s], skip", DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] update_remote_addr: link socket [%s] != recv socket [%s], skip",
link->etcp->log_name, link->conn ? link->conn->name : "-", e_sock->name); link->etcp->log_name, link->conn ? link->conn->name : "-", e_sock->name);
return; return;
} }
remove_link_from_queue(link); remove_link_from_queue(link);
memcpy(&link->remote_addr, new_addr, sizeof(struct sockaddr_storage)); memcpy(&link->remote_addr, new_addr, sizeof(struct sockaddr_storage));
if (insert_link_queue(e_sock, link) < 0) if (insert_link_queue(e_sock, link) < 0)
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "[%s] update_remote_addr: re-index FAILED at %s", DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "[%s] update_remote_addr: re-index FAILED at %s",
link->etcp->log_name, sockaddr_storage_to_str(new_addr).str); link->etcp->log_name, sockaddr_storage_to_str(new_addr).str);
} }
@ -436,7 +436,7 @@ struct ETCP_LINK* etcp_select_collision_link(struct ETCP_CONN* conn, const struc
} }
struct ETCP_LINK* etcp_link_find_by_remote_id(struct ETCP_CONN* conn, uint8_t remote_link_id) { struct ETCP_LINK* etcp_link_find_by_remote_id(struct ETCP_CONN* conn, uint8_t remote_link_id) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!conn || remote_link_id == 0) return NULL; if (!conn || remote_link_id == 0) return NULL;
struct ETCP_LINK* l = conn->links; struct ETCP_LINK* l = conn->links;
while (l) { while (l) {
@ -447,7 +447,7 @@ struct ETCP_LINK* etcp_link_find_by_remote_id(struct ETCP_CONN* conn, uint8_t re
} }
int etcp_find_free_local_link_id(struct ETCP_CONN* etcp) { int etcp_find_free_local_link_id(struct ETCP_CONN* etcp) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!etcp) return -1; if (!etcp) return -1;
// Битовый массив для 256 id (32 байта * 8 бит = 256) // Битовый массив для 256 id (32 байта * 8 бит = 256)
@ -478,7 +478,7 @@ int etcp_find_free_local_link_id(struct ETCP_CONN* etcp) {
// =============================== // ===============================
struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server) { struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!instance || !server) return NULL; if (!instance || !server) return NULL;
struct sockaddr_storage* ip = &server->ip; struct sockaddr_storage* ip = &server->ip;
@ -509,7 +509,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
if (netif_index == 0) { if (netif_index == 0) {
netif_index = get_default_route_netif_index(AF_INET6); netif_index = get_default_route_netif_index(AF_INET6);
if (netif_index == 0) { if (netif_index == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Cannot determine default route interface for IPv6 socket %s", name); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "Cannot determine default route interface for IPv6 socket %s", name);
u_free(e_sock); u_free(e_sock);
return NULL; return NULL;
} }
@ -517,7 +517,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
int temp = (server->ipv6_mode == CFG_IPV6_MODE_TEMPORARY) ? 1 : 0; int temp = (server->ipv6_mode == CFG_IPV6_MODE_TEMPORARY) ? 1 : 0;
uint8_t v6addr[16]; uint8_t v6addr[16];
if (get_interface_ipv6_addr_nl(netif_index, !temp, v6addr) != 0) { if (get_interface_ipv6_addr_nl(netif_index, !temp, v6addr) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to get %s IPv6 from netif_index=%u for socket %s", DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "Failed to get %s IPv6 from netif_index=%u for socket %s",
temp ? "temporary" : "permanent", netif_index, name); temp ? "temporary" : "permanent", netif_index, name);
u_free(e_sock); u_free(e_sock);
return NULL; return NULL;
@ -531,7 +531,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
family = ip->ss_family; family = ip->ss_family;
e_sock->netif_index = netif_index; e_sock->netif_index = netif_index;
if (family != AF_INET && family != AF_INET6) { if (family != AF_INET && family != AF_INET6) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Unsupported address family: %d", family); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "Unsupported address family: %d", family);
u_free(e_sock); u_free(e_sock);
return NULL; return NULL;
} }
@ -539,7 +539,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
e_sock->fd = socket_create_udp(family); e_sock->fd = socket_create_udp(family);
if (e_sock->fd == SOCKET_INVALID) { if (e_sock->fd == SOCKET_INVALID) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to create socket: %s", DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "Failed to create socket: %s",
socket_strerror(socket_get_error())); socket_strerror(socket_get_error()));
u_free(e_sock); u_free(e_sock);
return NULL; return NULL;
@ -552,13 +552,13 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
socket_set_buffers(e_sock->fd, 4 * 1024 * 1024, 4 * 1024 * 1024); socket_set_buffers(e_sock->fd, 4 * 1024 * 1024, 4 * 1024 * 1024);
if (socket_set_nonblocking(e_sock->fd) != 0) { if (socket_set_nonblocking(e_sock->fd) != 0) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to set non-blocking mode"); DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "Failed to set non-blocking mode");
} }
if (family == AF_INET6) { if (family == AF_INET6) {
int v6only = 1; int v6only = 1;
if (setsockopt(e_sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) < 0) { if (setsockopt(e_sock->fd, IPPROTO_IPV6, IPV6_V6ONLY, &v6only, sizeof(v6only)) < 0) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to set IPV6_V6ONLY: %s", socket_strerror(socket_get_error())); DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "Failed to set IPV6_V6ONLY: %s", socket_strerror(socket_get_error()));
} }
} }
@ -571,7 +571,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
#ifdef __FreeBSD__ #ifdef __FreeBSD__
if (fib > 0) { if (fib > 0) {
if (setsockopt(e_sock->fd, SOL_SOCKET, SO_SETFIB, &fib, sizeof(fib)) < 0) { if (setsockopt(e_sock->fd, SOL_SOCKET, SO_SETFIB, &fib, sizeof(fib)) < 0) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to set FIB %d: %s", fib, strerror(errno)); DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "Failed to set FIB %d: %s", fib, strerror(errno));
} }
} }
#endif #endif
@ -606,7 +606,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
rem_sin->sin_port = htons(53); rem_sin->sin_port = htons(53);
inet_pton(AF_INET, "8.8.8.8", &rem_sin->sin_addr); inet_pton(AF_INET, "8.8.8.8", &rem_sin->sin_addr);
if (get_outgoing_local_ip(ip, &remote, &e_sock->interface_addr) != 0) { if (get_outgoing_local_ip(ip, &remote, &e_sock->interface_addr) != 0) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "Failed to detect outgoing local IP for socket %s", e_sock->name); DEBUG_WARN(DEBUG_CATEGORY_SOCKET, "Failed to detect outgoing local IP for socket %s", e_sock->name);
} }
} }
} else if (ip->ss_family == AF_INET6) { } else if (ip->ss_family == AF_INET6) {
@ -705,7 +705,7 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
e_sock->only_local = only_local; e_sock->only_local = only_local;
e_sock->links_queue = queue_new(instance->ua, 256, offsetof(struct link_queue_entry, key), LINK_ADDR_KEY_SIZE, "links"); e_sock->links_queue = queue_new(instance->ua, 256, offsetof(struct link_queue_entry, key), LINK_ADDR_KEY_SIZE, "links");
if (!e_sock->links_queue) { if (!e_sock->links_queue) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to create links_queue for socket %s", e_sock->name); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "Failed to create links_queue for socket %s", e_sock->name);
socket_close_wrapper(e_sock->fd); socket_close_wrapper(e_sock->fd);
u_free(e_sock); u_free(e_sock);
return NULL; return NULL;
@ -715,18 +715,17 @@ struct ETCP_SOCKET* etcp_socket_add(struct UTUN_INSTANCE* instance, struct CFG_S
instance->etcp_sockets = e_sock; instance->etcp_sockets = e_sock;
e_sock->socket_id = uasync_add_socket_t(instance->ua, e_sock->fd, etcp_connections_read_callback_socket, NULL, NULL, e_sock); e_sock->socket_id = uasync_add_socket_t(instance->ua, e_sock->fd, etcp_connections_read_callback_socket, NULL, NULL, e_sock);
if (!e_sock->socket_id) { if (!e_sock->socket_id) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Failed to register socket with uasync"); DEBUG_ERROR(DEBUG_CATEGORY_SOCKET, "Failed to register socket with uasync");
socket_close_wrapper(e_sock->fd); socket_close_wrapper(e_sock->fd);
u_free(e_sock); u_free(e_sock);
return NULL; return NULL;
} }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "Registered ETCP socket with uasync");
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Socket %p registered and active", e_sock); DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Socket %p registered and active", e_sock);
return e_sock; return e_sock;
} }
void etcp_socket_remove(struct ETCP_SOCKET* conn) { void etcp_socket_remove(struct ETCP_SOCKET* conn) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!conn) return; if (!conn) return;
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Removing socket %p, socket_id=%p", conn, conn->socket_id); DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[ETCP] Removing socket %p, socket_id=%p", conn, conn->socket_id);
@ -865,14 +864,14 @@ void tcp_socket_remove(struct ETCP_SOCKET* sock) {
} }
struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn, struct sockaddr_storage* remote_addr, uint8_t is_server) { struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn, struct sockaddr_storage* remote_addr, uint8_t is_server) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!etcp) { DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "null etcp"); return NULL; } if (!etcp) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "null etcp"); return NULL; }
if (etcp->state == 2) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] link_new on deleted conn", etcp->log_name); return NULL; } if (etcp->state == 2) { DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] link_new on deleted conn", etcp->log_name); return NULL; }
int is_tcp = (conn == NULL) || conn->is_tcp; int is_tcp = (conn == NULL) || conn->is_tcp;
struct ETCP_LINK* link = u_calloc(1, sizeof(struct ETCP_LINK)); struct ETCP_LINK* link = u_calloc(1, sizeof(struct ETCP_LINK));
if (!link) { if (!link) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "calloc failed - out of memory or pool exhausted"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "calloc failed - out of memory or pool exhausted");
return NULL; return NULL;
} }
@ -930,7 +929,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
// Выделяем свободный local_link_id // Выделяем свободный local_link_id
int free_id = etcp_find_free_local_link_id(etcp); int free_id = etcp_find_free_local_link_id(etcp);
if (free_id <= 0) { if (free_id <= 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "no free local_link_id available"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "no free local_link_id available");
u_free(link); u_free(link);
return NULL; return NULL;
} }
@ -947,7 +946,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
link->total_retransmissions = 0; link->total_retransmissions = 0;
if (!is_tcp && insert_link_queue(conn, link) < 0) { if (!is_tcp && insert_link_queue(conn, link) < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Can not insert link to socket"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Can not insert link to socket");
u_free(link); u_free(link);
return NULL; return NULL;
} }
@ -991,7 +990,7 @@ static void etcp_inflight_nullify_link(struct ll_queue* q, struct ETCP_LINK* dea
} }
void etcp_link_close(struct ETCP_LINK* link) { void etcp_link_close(struct ETCP_LINK* link) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!link) return; if (!link) return;
if (link->etcp && link->etcp->last_rr_link == link) link->etcp->last_rr_link = NULL; if (link->etcp && link->etcp->last_rr_link == link) link->etcp->last_rr_link = NULL;
@ -1126,7 +1125,7 @@ void etcp_tcp_link_start_connect(struct ETCP_LINK *link, struct sockaddr_storage
link->tcp_link = sl; link->tcp_link = sl;
if (link->is_server == 0) stcp_link_set_on_close(sl, tcp_link_close_cb, link); if (link->is_server == 0) stcp_link_set_on_close(sl, tcp_link_close_cb, link);
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] TCP link %d → stcp_link_connect %s:%u rc=%p bind=%s", DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] TCP link %d → stcp_link_connect %s:%u rc=%p bind=%s",
link->etcp->log_name, link->local_link_id, addr, port, (void*)sl, link->etcp->log_name, link->local_link_id, sockaddr_storage_to_str(addr).str, port, (void*)sl,
link->conn ? sockaddr_storage_to_str(&link->conn->interface_addr).str : "auto"); link->conn ? sockaddr_storage_to_str(&link->conn->interface_addr).str : "auto");
} }
@ -1200,10 +1199,10 @@ ssize_t etcp_udp_send(struct ETCP_LINK* link, socket_t fd, const void* buf, size
} }
int etcp_encrypt_send(struct ETCP_DGRAM* dgram) { int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
if (!dgram || !dgram->link) { DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Null pointer"); return -1; } if (!dgram || !dgram->link) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Null pointer"); return -1; }
if (dgram->link->is_tcp) return etcp_tcp_send(dgram); if (dgram->link->is_tcp) return etcp_tcp_send(dgram);
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Send rk=%d lk=%d up=%d", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] Send rk=%d lk=%d up=%d",
dgram->link->etcp->log_name, dgram->link->recv_keepalive, dgram->link->remote_keepalive, dgram->link->link_status); dgram->link->etcp->log_name, dgram->link->recv_keepalive, dgram->link->remote_keepalive, dgram->link->link_status);
// Mark that packet was sent (for keepalive logic) // Mark that packet was sent (for keepalive logic)
@ -1224,10 +1223,10 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_CRYPTO)) log_dump(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_CRYPTO, "Before encryption", dgram->data, dgram->data_len); if (debug_should_output(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_CRYPTO)) log_dump(DEBUG_LEVEL_DEBUG, DEBUG_CATEGORY_CRYPTO, "Before encryption", dgram->data, dgram->data_len);
sc_encrypt(sc, (uint8_t*)&dgram->timestamp, 3 + len, enc_buf, &enc_buf_len); sc_encrypt(sc, (uint8_t*)&dgram->timestamp, 3 + len, enc_buf, &enc_buf_len);
if (enc_buf_len == 0) { if (enc_buf_len == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "eencryption failed for node %016llx", (unsigned long long)dgram->link->etcp->instance->node_id); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "eencryption failed for node %016llx", (unsigned long long)dgram->link->etcp->instance->node_id);
dgram->link->send_errors++; errcode=2; goto es_err; } dgram->link->send_errors++; errcode=2; goto es_err; }
if (enc_buf_len + dgram->noencrypt_len > (size_t)(dgram->link->mtu - udp_ov)) { if (enc_buf_len + dgram->noencrypt_len > (size_t)(dgram->link->mtu - udp_ov)) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "packet too long enc=%zu ne=%d mtu=%d", enc_buf_len, dgram->noencrypt_len, dgram->link->mtu); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "packet too long enc=%zu ne=%d mtu=%d", enc_buf_len, dgram->noencrypt_len, dgram->link->mtu);
dgram->link->send_errors++; errcode=3; goto es_err; } dgram->link->send_errors++; errcode=3; goto es_err; }
memcpy(enc_buf+enc_buf_len, dgram->data+len, dgram->noencrypt_len); memcpy(enc_buf+enc_buf_len, dgram->data+len, dgram->noencrypt_len);
@ -1239,24 +1238,24 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
ssize_t sent = etcp_udp_send(dgram->link, dgram->link->conn->fd, enc_buf, enc_buf_len + dgram->noencrypt_len, ssize_t sent = etcp_udp_send(dgram->link, dgram->link->conn->fd, enc_buf, enc_buf_len + dgram->noencrypt_len,
(struct sockaddr*)addr, addr_len); (struct sockaddr*)addr, addr_len);
if (sent < 0) { if (sent < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "sendto failed, sock_err=%d dst=%s fd=%d", DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "sendto failed, sock_err=%d dst=%s fd=%d",
socket_get_error(), sockaddr_storage_to_str(addr).str, dgram->link->conn->fd); socket_get_error(), sockaddr_storage_to_str(addr).str, dgram->link->conn->fd);
dgram->link->send_errors++; errcode=4; goto es_err; dgram->link->send_errors++; errcode=4; goto es_err;
} }
return (int)sent; return (int)sent;
es_err: es_err:
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "error %d", errcode); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "error %d", errcode);
return -1; return -1;
} }
static int etcp_send_ping_raw(struct ETCP_DGRAM* dgram, socket_t fd, sc_context_t* sc, const struct sockaddr_storage* addr) { static int etcp_send_ping_raw(struct ETCP_DGRAM* dgram, socket_t fd, sc_context_t* sc, const struct sockaddr_storage* addr) {
if (!dgram || !sc || !addr) { if (!dgram || !sc || !addr) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Null pointer in ping send"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Null pointer in ping send");
return -1; return -1;
} }
int len = dgram->data_len - dgram->noencrypt_len; int len = dgram->data_len - dgram->noencrypt_len;
if (len < 0 || len > PACKET_DATA_SIZE - IP_UDP_OVERHEAD_V4) { if (len < 0 || len > PACKET_DATA_SIZE - IP_UDP_OVERHEAD_V4) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "ping packet data invalid len=%d", len); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "ping packet data invalid len=%d", len);
return -1; return -1;
} }
uint8_t enc_buf[1600]; uint8_t enc_buf[1600];
@ -1265,11 +1264,11 @@ static int etcp_send_ping_raw(struct ETCP_DGRAM* dgram, socket_t fd, sc_context_
dgram->flag_up = 1; dgram->flag_up = 1;
sc_encrypt(sc, (uint8_t*)&dgram->timestamp, 3 + len, enc_buf, &enc_buf_len); sc_encrypt(sc, (uint8_t*)&dgram->timestamp, 3 + len, enc_buf, &enc_buf_len);
if (enc_buf_len == 0) { if (enc_buf_len == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "encryption failed for ping"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "encryption failed for ping");
return -1; return -1;
} }
if (enc_buf_len + dgram->noencrypt_len > (size_t)(PACKET_DATA_SIZE - IP_UDP_OVERHEAD_V4)) { if (enc_buf_len + dgram->noencrypt_len > (size_t)(PACKET_DATA_SIZE - IP_UDP_OVERHEAD_V4)) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "ping packet too long enc=%zu ne=%d", enc_buf_len, dgram->noencrypt_len); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "ping packet too long enc=%zu ne=%d", enc_buf_len, dgram->noencrypt_len);
return -1; return -1;
} }
memcpy(enc_buf + enc_buf_len, dgram->data + len, dgram->noencrypt_len); memcpy(enc_buf + enc_buf_len, dgram->data + len, dgram->noencrypt_len);
@ -1279,10 +1278,10 @@ static int etcp_send_ping_raw(struct ETCP_DGRAM* dgram, socket_t fd, sc_context_
//xaddr[0]=192; xaddr[1]=168; xaddr[2]=10; xaddr[3]=1; //xaddr[0]=192; xaddr[1]=168; xaddr[2]=10; xaddr[3]=1;
sent = socket_sendto(fd, enc_buf, enc_buf_len + dgram->noencrypt_len, (struct sockaddr*)addr, addr_len); sent = socket_sendto(fd, enc_buf, enc_buf_len + dgram->noencrypt_len, (struct sockaddr*)addr, addr_len);
if (sent < 0) { if (sent < 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "sendto failed for ping, err=%d addr=%s fd=%d len=%d", socket_get_error(), sockaddr_storage_to_str(addr).str, fd, enc_buf_len + dgram->noencrypt_len); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "sendto failed for ping, err=%d addr=%s fd=%d len=%d", socket_get_error(), sockaddr_storage_to_str(addr).str, fd, enc_buf_len + dgram->noencrypt_len);
return -1; return -1;
} }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "ping sendto succeeded to %s sent=%zd bytes fd=%d", sockaddr_storage_to_str(addr).str, sent, fd); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "ping sendto succeeded to %s sent=%zd bytes fd=%d", sockaddr_storage_to_str(addr).str, sent, fd);
return (int)sent; return (int)sent;
} }
@ -1318,21 +1317,21 @@ int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET*
const uint8_t* user_data, size_t user_data_len, const uint8_t* user_data, size_t user_data_len,
uint8_t flags) { uint8_t flags) {
if (!instance || !e_sock || !peer_pubkey_bin || !addr || timeout_ms <= 0 || !cb) { if (!instance || !e_sock || !peer_pubkey_bin || !addr || timeout_ms <= 0 || !cb) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "bad args"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "bad args");
return -1; return -1;
} }
if (e_sock->is_tcp || e_sock->fd == SOCKET_INVALID) { if (e_sock->is_tcp || e_sock->fd == SOCKET_INVALID) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "ping on non-UDP socket name=%s is_tcp=%d fd=%d", DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "ping on non-UDP socket name=%s is_tcp=%d fd=%d",
e_sock->name, e_sock->is_tcp, (int)e_sock->fd); e_sock->name, e_sock->is_tcp, (int)e_sock->fd);
return -2; return -2;
} }
if (user_data_len > PACKET_DATA_SIZE - 24 - 2 - SC_PUBKEY_ENC_SIZE) { if (user_data_len > PACKET_DATA_SIZE - 24 - 2 - SC_PUBKEY_ENC_SIZE) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "user_data too long"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "user_data too long");
return -2; return -2;
} }
struct PING_CONTEXT* ctx = u_malloc(sizeof(struct PING_CONTEXT)); struct PING_CONTEXT* ctx = u_malloc(sizeof(struct PING_CONTEXT));
if (!ctx) { if (!ctx) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "malloc ctx"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "malloc ctx");
return -3; return -3;
} }
ctx->next = NULL; ctx->next = NULL;
@ -1348,7 +1347,7 @@ int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET*
ctx->user_data = u_malloc(user_data_len); ctx->user_data = u_malloc(user_data_len);
if (!ctx->user_data) { if (!ctx->user_data) {
u_free(ctx); u_free(ctx);
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "malloc user_data"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "malloc user_data");
return -3; return -3;
} }
memcpy(ctx->user_data, user_data, user_data_len); memcpy(ctx->user_data, user_data, user_data_len);
@ -1359,7 +1358,7 @@ int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET*
if (!dgram) { if (!dgram) {
if (ctx->user_data) u_free(ctx->user_data); if (ctx->user_data) u_free(ctx->user_data);
u_free(ctx); u_free(ctx);
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "malloc dgram"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "malloc dgram");
return -4; return -4;
} }
dgram->link = NULL; dgram->link = NULL;
@ -1394,7 +1393,7 @@ int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET*
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "set key failed"); DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "set key failed");
return -5; return -5;
} }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "ping send nonce=%016llx timeout=%d ulen=%zu", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "ping send nonce=%016llx timeout=%d ulen=%zu",
(unsigned long long)ctx->nonce, timeout_ms, user_data_len); (unsigned long long)ctx->nonce, timeout_ms, user_data_len);
int send_rc = etcp_send_ping_raw(dgram, e_sock->fd, &sc, addr); int send_rc = etcp_send_ping_raw(dgram, e_sock->fd, &sc, addr);
u_free(dgram); u_free(dgram);
@ -1419,7 +1418,7 @@ int etcp_send_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bi
etcp_ping_callback_t cb, void* user_arg, etcp_ping_callback_t cb, void* user_arg,
const uint8_t* user_data, size_t user_data_len) { const uint8_t* user_data, size_t user_data_len) {
if (!instance || !peer_pubkey_bin || !addr || timeout_ms <= 0 || !cb) { if (!instance || !peer_pubkey_bin || !addr || timeout_ms <= 0 || !cb) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "bad args: inst=%p pubkey=%p addr=%p timeout=%d cb=%p udata=%p udata_len=%zu", DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "bad args: inst=%p pubkey=%p addr=%p timeout=%d cb=%p udata=%p udata_len=%zu",
(void*)instance, (void*)peer_pubkey_bin, (void*)addr, timeout_ms, (void*)instance, (void*)peer_pubkey_bin, (void*)addr, timeout_ms,
(void*)(uintptr_t)cb, (void*)user_data, user_data_len); (void*)(uintptr_t)cb, (void*)user_data, user_data_len);
return -1; return -1;
@ -1427,10 +1426,10 @@ int etcp_send_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bi
struct ETCP_SOCKET* e_sock = instance->etcp_sockets; struct ETCP_SOCKET* e_sock = instance->etcp_sockets;
while (e_sock && e_sock->local_addr.ss_family != addr->ss_family) e_sock = e_sock->next; while (e_sock && e_sock->local_addr.ss_family != addr->ss_family) e_sock = e_sock->next;
if (!e_sock) { if (!e_sock) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "no socket for addr_family=%d", addr->ss_family); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "no socket for addr_family=%d", addr->ss_family);
return -2; return -2;
} }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "ping N1 [%s]", sockaddr_storage_to_str(addr).str); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "ping N1 [%s]", sockaddr_storage_to_str(addr).str);
return etcp_send_ping_to_socket(instance, e_sock, peer_pubkey_bin, addr, timeout_ms, return etcp_send_ping_to_socket(instance, e_sock, peer_pubkey_bin, addr, timeout_ms,
cb, user_arg, user_data, user_data_len, 0); cb, user_arg, user_data, user_data_len, 0);
} }
@ -1450,7 +1449,7 @@ int etcp_send_tcp_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubke
const struct sockaddr_storage* addr, int timeout_ms, const struct sockaddr_storage* addr, int timeout_ms,
etcp_ping_callback_t cb, void* user_arg) { etcp_ping_callback_t cb, void* user_arg) {
if (!instance || !peer_pubkey_bin || !addr || timeout_ms <= 0 || !cb) { if (!instance || !peer_pubkey_bin || !addr || timeout_ms <= 0 || !cb) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "bad args: inst=%p pubkey=%p addr=%p timeout=%d cb=%p", DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "bad args: inst=%p pubkey=%p addr=%p timeout=%d cb=%p",
(void*)instance, (void*)peer_pubkey_bin, (void*)addr, timeout_ms, (void*)(uintptr_t)cb); (void*)instance, (void*)peer_pubkey_bin, (void*)addr, timeout_ms, (void*)(uintptr_t)cb);
return -1; return -1;
} }
@ -1465,17 +1464,17 @@ int etcp_send_tcp_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubke
snprintf(addr_str, sizeof(addr_str), "%s", ip_to_str(&sin6->sin6_addr, AF_INET6).str); snprintf(addr_str, sizeof(addr_str), "%s", ip_to_str(&sin6->sin6_addr, AF_INET6).str);
port = ntohs(sin6->sin6_port); port = ntohs(sin6->sin6_port);
} else { } else {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "unsupported addr family=%d", addr->ss_family); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "unsupported addr family=%d", addr->ss_family);
return -2; return -2;
} }
struct tcp_ping_adapter* a = u_malloc(sizeof(struct tcp_ping_adapter)); struct tcp_ping_adapter* a = u_malloc(sizeof(struct tcp_ping_adapter));
if (!a) { DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "malloc adapter"); return -3; } if (!a) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "malloc adapter"); return -3; }
a->cb = cb; a->arg = user_arg; a->cb = cb; a->arg = user_arg;
struct stcp_client* cli = stcp_ping_send(instance->ua, addr_str, port, &instance->my_keys, peer_pubkey_bin, struct stcp_client* cli = stcp_ping_send(instance->ua, addr_str, port, &instance->my_keys, peer_pubkey_bin,
instance->my_ed25519_pubkey, instance->client_type, instance->my_ed25519_pubkey, instance->client_type,
instance->keepalive_interval, timeout_ms, tcp_ping_cb_adapter, a); instance->keepalive_interval, timeout_ms, tcp_ping_cb_adapter, a);
if (!cli) { u_free(a); return -4; } if (!cli) { u_free(a); return -4; }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "tcp ping to %s:%u timeout=%d", addr_str, (unsigned)port, timeout_ms); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "tcp ping to %s:%u timeout=%d", addr_str, (unsigned)port, timeout_ms);
return 0; return 0;
} }
@ -1483,7 +1482,7 @@ int etcp_send_tcp_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubke
static int handle_ping(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const struct sockaddr_storage* addr, const uint8_t* decrypted_pubkey, size_t pkt_len) { static int handle_ping(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const struct sockaddr_storage* addr, const uint8_t* decrypted_pubkey, size_t pkt_len) {
if (pkt_len < 23) { if (pkt_len < 23) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "PING too short: pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(addr).str); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "PING too short: pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(addr).str);
return 7; return 7;
} }
uint8_t flags = pkt->data[1]; uint8_t flags = pkt->data[1];
@ -1495,7 +1494,7 @@ static int handle_ping(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
if ((flags & ETCP_PING_FLAG_SEND_RTT) && ulen >= 2) { if ((flags & ETCP_PING_FLAG_SEND_RTT) && ulen >= 2) {
uint16_t rtt_val = be16toh(*(uint16_t*)udata); uint16_t rtt_val = be16toh(*(uint16_t*)udata);
topo_node_ping_update_rtt(e_sock->instance->topo_groups, peer_id, rtt_val); topo_node_ping_update_rtt(e_sock->instance->topo_groups, peer_id, rtt_val);
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "PING rtt=%u from peer=%016llx", (unsigned)rtt_val, (unsigned long long)peer_id); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "PING rtt=%u from peer=%016llx", (unsigned)rtt_val, (unsigned long long)peer_id);
} }
uint8_t pong_flags = 0; uint8_t pong_flags = 0;
@ -1527,7 +1526,7 @@ static int handle_ping(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
sc_context_t resp_sc; sc_context_t resp_sc;
sc_init_ctx(&resp_sc, &e_sock->instance->my_keys); sc_init_ctx(&resp_sc, &e_sock->instance->my_keys);
if (sc_set_peer_public_key(&resp_sc, decrypted_pubkey, SC_PEER_PUBKEY_BIN) == SC_OK) { if (sc_set_peer_public_key(&resp_sc, decrypted_pubkey, SC_PEER_PUBKEY_BIN) == SC_OK) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "PONG send nonce=%016llx flags=%02x to=%s fd=%d", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "PONG send nonce=%016llx flags=%02x to=%s fd=%d",
(unsigned long long)nonce, (unsigned)pong_flags, sockaddr_storage_to_str(addr).str, e_sock->fd); (unsigned long long)nonce, (unsigned)pong_flags, sockaddr_storage_to_str(addr).str, e_sock->fd);
etcp_send_ping_raw(resp, e_sock->fd, &resp_sc, addr); etcp_send_ping_raw(resp, e_sock->fd, &resp_sc, addr);
} }
@ -1544,7 +1543,7 @@ static void rtt_send_ping_cb(int success, uint16_t rtt, void* arg, uint64_t nonc
static int handle_pong(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const struct sockaddr_storage* addr, size_t pkt_len) { static int handle_pong(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const struct sockaddr_storage* addr, size_t pkt_len) {
if (pkt_len < 23) { if (pkt_len < 23) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "PONG too short: pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(addr).str); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "PONG too short: pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(addr).str);
return 7; return 7;
} }
uint8_t flags = pkt->data[1]; uint8_t flags = pkt->data[1];
@ -1557,7 +1556,7 @@ static int handle_pong(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
udata = pkt->data + 20; udata = pkt->data + 20;
} }
} }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "PONG recv nonce=%016llx flags=%02x data_len=%u from=%s socket=%s", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "PONG recv nonce=%016llx flags=%02x data_len=%u from=%s socket=%s",
(unsigned long long)nonce, (unsigned)flags, (unsigned)pkt->data_len, (unsigned long long)nonce, (unsigned)flags, (unsigned)pkt->data_len,
sockaddr_storage_to_str(addr).str, e_sock->name); sockaddr_storage_to_str(addr).str, e_sock->name);
struct PING_CONTEXT* ctx = e_sock->instance->pending_pings; struct PING_CONTEXT* ctx = e_sock->instance->pending_pings;
@ -1574,7 +1573,7 @@ static int handle_pong(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
} }
uint64_t now = get_time_tb(); uint64_t now = get_time_tb();
uint16_t rtt = (now >= ctx->send_time) ? (uint16_t)(now - ctx->send_time) : 0; uint16_t rtt = (now >= ctx->send_time) ? (uint16_t)(now - ctx->send_time) : 0;
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "PONG matched nonce=%016llx rtt=%u want_rtt=%d", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "PONG matched nonce=%016llx rtt=%u want_rtt=%d",
(unsigned long long)nonce, (unsigned)rtt, (flags & ETCP_PING_FLAG_WANT_RTT) ? 1 : 0); (unsigned long long)nonce, (unsigned)rtt, (flags & ETCP_PING_FLAG_WANT_RTT) ? 1 : 0);
uint64_t pong_peer_id = be64toh(*(uint64_t*)(pkt->data + 2)); uint64_t pong_peer_id = be64toh(*(uint64_t*)(pkt->data + 2));
@ -1597,7 +1596,7 @@ static int handle_pong(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt, const
ctx = ctx->next; ctx = ctx->next;
} }
if (!found) { if (!found) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "PONG nonce=%016llx NOT FOUND in pending (timeout?)", DEBUG_WARN(DEBUG_CATEGORY_ETCP, "PONG nonce=%016llx NOT FOUND in pending (timeout?)",
(unsigned long long)nonce); (unsigned long long)nonce);
} }
memory_pool_free(e_sock->instance->pkt_pool, pkt); memory_pool_free(e_sock->instance->pkt_pool, pkt);
@ -1610,10 +1609,10 @@ static void send_init_response(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pk
// Set response code: 0x03 (with reset) or 0x05 (without reset) // Set response code: 0x03 (with reset) or 0x05 (without reset)
// response with init (0x03) only if reinit was actually done on server side // response with init (0x03) only if reinit was actually done on server side
if (send_reset != 0) { if (send_reset != 0) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "send init_response with reset"); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "send init_response with reset");
resp->code = ETCP_INIT_RESPONSE; // 0x03 - with reset resp->code = ETCP_INIT_RESPONSE; // 0x03 - with reset
} else { } else {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "send init_response without reset"); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "send init_response without reset");
resp->code = ETCP_INIT_RESPONSE_NOINIT; // 0x05 - without reset resp->code = ETCP_INIT_RESPONSE_NOINIT; // 0x05 - without reset
} }
*(uint64_t*)resp->node_id = htobe64(e_sock->instance->node_id); *(uint64_t*)resp->node_id = htobe64(e_sock->instance->node_id);
@ -1752,7 +1751,7 @@ static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_D
struct ETCP_INIT_RESPONSE_PKT* resp = (struct ETCP_INIT_RESPONSE_PKT*)pkt->data; struct ETCP_INIT_RESPONSE_PKT* resp = (struct ETCP_INIT_RESPONSE_PKT*)pkt->data;
uint64_t server_node_id = be64toh(*(uint64_t*)resp->node_id); uint64_t server_node_id = be64toh(*(uint64_t*)resp->node_id);
uint64_t resp_reset_id = be64toh(*(uint64_t*)resp->reset_id); uint64_t resp_reset_id = be64toh(*(uint64_t*)resp->reset_id);
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "INIT_RESPONSE rid=%016llx", (unsigned long long)resp_reset_id); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "INIT_RESPONSE rid=%016llx", (unsigned long long)resp_reset_id);
etcp_conn_apply_peer_reset_id(link->etcp, resp_reset_id); etcp_conn_apply_peer_reset_id(link->etcp, resp_reset_id);
link->mtu_remote = be16toh(*(uint16_t*)resp->mtu); link->mtu_remote = be16toh(*(uint16_t*)resp->mtu);
if (link->mtu_remote > PACKET_DATA_MAX_MTU) link->mtu_remote = PACKET_DATA_MAX_MTU; if (link->mtu_remote > PACKET_DATA_MAX_MTU) link->mtu_remote = PACKET_DATA_MAX_MTU;
@ -1811,7 +1810,7 @@ static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_D
} }
} else { } else {
// Legacy format without NAT info // Legacy format without NAT info
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Received legacy INIT_RESPONSE without NAT info", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] Received legacy INIT_RESPONSE without NAT info",
link->etcp->log_name); link->etcp->log_name);
} }
@ -1855,7 +1854,7 @@ static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_D
} }
void etcp_connections_read_callback_socket(socket_t sock, void* arg) { void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "etcp_connections_read_callback fd=%d, socket=%p", fd, arg); // DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "etcp_connections_read_callback fd=%d, socket=%p", fd, arg);
// !!!!!! DANGER: в этой функции ПРЕДЕЛЬНАЯ АККУРАТНОСТЬ. Если кажется что не туда указатель то невнимательно аланизировал !!!!! // !!!!!! DANGER: в этой функции ПРЕДЕЛЬНАЯ АККУРАТНОСТЬ. Если кажется что не туда указатель то невнимательно аланизировал !!!!!
// НЕ РУИНИТЬ (uint8_t*)&pkt->timestamp - это правильно !!!! // НЕ РУИНИТЬ (uint8_t*)&pkt->timestamp - это правильно !!!!
@ -1928,7 +1927,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
// This handles: no link found, or link without session, or normal decrypt failed // This handles: no link found, or link without session, or normal decrypt failed
if (recv_len <= SC_PUBKEY_ENC_SIZE + UDP_SC_HDR_SIZE) { if (recv_len <= SC_PUBKEY_ENC_SIZE + UDP_SC_HDR_SIZE) {
if (e_sock->pkt_format_errors < 2) if (e_sock->pkt_format_errors < 2)
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "packet too small for init, size=%zd from %s", recv_len, sockaddr_storage_to_str(&addr).str); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "packet too small for init, size=%zd from %s", recv_len, sockaddr_storage_to_str(&addr).str);
errorcode=1; errorcode=1;
goto ec_fr; goto ec_fr;
} }
@ -1972,12 +1971,12 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
// INIT decryption succeeded - process packet // INIT decryption succeeded - process packet
if (pkt_len<3) { if (pkt_len<3) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "too short packet, from %s", sockaddr_storage_to_str(&addr).str); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "too short packet, from %s", sockaddr_storage_to_str(&addr).str);
errorcode=7; errorcode=7;
goto ec_fr; goto ec_fr;
} }
if (pkt_len<15) { if (pkt_len<15) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "decrypted packet too short for INIT header, pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(&addr).str); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "decrypted packet too short for INIT header, pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(&addr).str);
errorcode=7; errorcode=7;
goto ec_fr; goto ec_fr;
} }
@ -1987,38 +1986,38 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
uint8_t code = pkt->data[0]; uint8_t code = pkt->data[0];
uint64_t peer_id = be64toh(*(uint64_t*)(pkt->data + 2)); uint64_t peer_id = be64toh(*(uint64_t*)(pkt->data + 2));
if (code == ETCP_PING) { if (code == ETCP_PING) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "X25519 decrypted: PING from peer=0x%016llx src=%s", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "X25519 decrypted: PING from peer=0x%016llx src=%s",
(unsigned long long)peer_id, sockaddr_storage_to_str(&addr).str); (unsigned long long)peer_id, sockaddr_storage_to_str(&addr).str);
int ret = handle_ping(e_sock, pkt, &addr, decrypted_pubkey, pkt_len); int ret = handle_ping(e_sock, pkt, &addr, decrypted_pubkey, pkt_len);
if (ret) { errorcode = ret; goto ec_fr; } if (ret) { errorcode = ret; goto ec_fr; }
return; return;
} }
if (code == ETCP_PONG) { if (code == ETCP_PONG) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "X25519 decrypted: PONG from peer=0x%016llx src=%s", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "X25519 decrypted: PONG from peer=0x%016llx src=%s",
(unsigned long long)peer_id, sockaddr_storage_to_str(&addr).str); (unsigned long long)peer_id, sockaddr_storage_to_str(&addr).str);
int ret = handle_pong(e_sock, pkt, &addr, pkt_len); int ret = handle_pong(e_sock, pkt, &addr, pkt_len);
if (ret) { errorcode = ret; goto ec_fr; } if (ret) { errorcode = ret; goto ec_fr; }
return; return;
} }
if (code!=ETCP_INIT_REQUEST && code!=ETCP_INIT_REQUEST_NOINIT) { if (code!=ETCP_INIT_REQUEST && code!=ETCP_INIT_REQUEST_NOINIT) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "not an init packet: code=0x%02x (expected 0x02/0x04) from %s — packet dropped", DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "not an init packet: code=0x%02x (expected 0x02/0x04) from %s — packet dropped",
code, sockaddr_storage_to_str(&addr).str); code, sockaddr_storage_to_str(&addr).str);
errorcode=4; errorcode=4;
goto ec_fr; goto ec_fr;
}// не init }// не init
if (e_sock->type == CFG_SERVER_TYPE_PRIVATE) { if (e_sock->type == CFG_SERVER_TYPE_PRIVATE) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "INIT rejected: socket %s (type=PRIVATE) does not accept incoming connections", e_sock->name); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "INIT rejected: socket %s (type=PRIVATE) does not accept incoming connections", e_sock->name);
errorcode=8; errorcode=8;
goto ec_fr; goto ec_fr;
} }
if (pkt_len < ETCP_INIT_REQ_SIZE) { if (pkt_len < ETCP_INIT_REQ_SIZE) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "INIT REQUEST too short: pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(&addr).str); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "INIT REQUEST too short: pkt_len=%zu from %s", pkt_len, sockaddr_storage_to_str(&addr).str);
errorcode=7; errorcode=7;
goto ec_fr; goto ec_fr;
} }
if (link) if (link)
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "INIT packet on existing link from=%s log=%s link_state=%d", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "INIT packet on existing link from=%s log=%s link_state=%d",
sockaddr_storage_to_str(&addr).str, sockaddr_storage_to_str(&addr).str,
link->etcp ? link->etcp->log_name : "null", link->link_state); link->etcp ? link->etcp->log_name : "null", link->link_state);
@ -2026,7 +2025,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
struct global_config *global = &e_sock->instance->config->global; struct global_config *global = &e_sock->instance->config->global;
if (!global->allowed_keys_allow_all) { if (!global->allowed_keys_allow_all) {
if (global->allowed_keys_count == 0) { if (global->allowed_keys_count == 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Connection rejected: no allowed_keys configured, allow_all=0"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Connection rejected: no allowed_keys configured, allow_all=0");
errorcode=8; errorcode=8;
goto ec_fr; goto ec_fr;
} }
@ -2040,7 +2039,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
ak = ak->next; ak = ak->next;
} }
if (!found) { if (!found) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "Connection rejected: peer public key not in allowed_keys list"); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Connection rejected: peer public key not in allowed_keys list");
errorcode=8; errorcode=8;
goto ec_fr; goto ec_fr;
} }
@ -2065,7 +2064,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
struct conn_queue_entry* ce = (struct conn_queue_entry*)ol->etcp->conn_queue_entry->data; struct conn_queue_entry* ce = (struct conn_queue_entry*)ol->etcp->conn_queue_entry->data;
if (ce->peer_node_id == 0) { if (ce->peer_node_id == 0) {
conn = ol->etcp; conn = ol->etcp;
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] reusing unindexed outbound conn (q_key=0, peer=0x%016llx) for incoming INIT from %s", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] reusing unindexed outbound conn (q_key=0, peer=0x%016llx) for incoming INIT from %s",
conn->log_name, (unsigned long long)peer_id, sockaddr_storage_to_str(&addr).str); conn->log_name, (unsigned long long)peer_id, sockaddr_storage_to_str(&addr).str);
} }
} }
@ -2075,7 +2074,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
if (!conn || conn->peer_node_id!=peer_id) {// создаём новое подключение [new etcp] if (!conn || conn->peer_node_id!=peer_id) {// создаём новое подключение [new etcp]
new_conn=1; new_conn=1;
conn=etcp_connection_create(e_sock->instance,""); conn=etcp_connection_create(e_sock->instance,"");
if (!conn) { errorcode=55; DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "failed to create connection"); goto ec_fr; } if (!conn) { errorcode=55; DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "failed to create connection"); goto ec_fr; }
memcpy(&conn->crypto_ctx, &sc, sizeof(sc)); memcpy(&conn->crypto_ctx, &sc, sizeof(sc));
DEBUG_DEBUG(DEBUG_CATEGORY_CRYPTO, "CRYPTO_CTX_INIT: log=%s seskey=%02x%02x%02x%02x peer_pub=%02x%02x%02x%02x my_priv=%02x%02x%02x%02x", DEBUG_DEBUG(DEBUG_CATEGORY_CRYPTO, "CRYPTO_CTX_INIT: log=%s seskey=%02x%02x%02x%02x peer_pub=%02x%02x%02x%02x my_priv=%02x%02x%02x%02x",
conn->log_name, conn->log_name,
@ -2090,9 +2089,6 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
conn->peer_node_id = peer_id; conn->peer_node_id = peer_id;
etcp_update_log_name(conn); etcp_update_log_name(conn);
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "New connection received on socket %s: log_name=%s peer_id=%lu peer:%s", e_sock->name, conn->log_name, (unsigned long)peer_id, sockaddr_storage_to_str(&addr).str); DEBUG_INFO(DEBUG_CATEGORY_ETCP, "New connection received on socket %s: log_name=%s peer_id=%lu peer:%s", e_sock->name, conn->log_name, (unsigned long)peer_id, sockaddr_storage_to_str(&addr).str);
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "New connection from %s peer_id=%ld etcp=%p total=%d",
ip_to_str(&addr, addr.ss_family).str, peer_id, conn,
queue_entry_count(e_sock->instance->connections));
} }
else {// check keys если существующее подключение else {// check keys если существующее подключение
if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) { if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) {
@ -2109,7 +2105,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
} }
if (conn->fin_wait) { if (conn->fin_wait) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] received INIT during fin_wait, clearing", conn->log_name); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] received INIT during fin_wait, clearing", conn->log_name);
conn->fin_wait = 0; conn->fin_wait = 0;
if (conn->fin_wait_clear_cb) { conn->fin_wait_clear_cb(conn, conn->fin_wait_clear_arg); conn->fin_wait_clear_cb = NULL; conn->fin_wait_clear_arg = NULL; } if (conn->fin_wait_clear_cb) { conn->fin_wait_clear_cb(conn, conn->fin_wait_clear_arg); conn->fin_wait_clear_cb = NULL; conn->fin_wait_clear_arg = NULL; }
} }
@ -2140,7 +2136,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] remote addr updated: id=%u -> %s", DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] remote addr updated: id=%u -> %s",
conn->log_name, existing_link->remote_link_id, sockaddr_storage_to_str(&addr).str); conn->log_name, existing_link->remote_link_id, sockaddr_storage_to_str(&addr).str);
} else { } else {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] addr %s busy (up/foreign) — link id=%u left as-is", DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] addr %s busy (up/foreign) — link id=%u left as-is",
conn->log_name, sockaddr_storage_to_str(&addr).str, existing_link->remote_link_id); conn->log_name, sockaddr_storage_to_str(&addr).str, existing_link->remote_link_id);
} }
} }
@ -2149,7 +2145,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
existing_link = etcp_link_find_by_addr(e_sock, &addr, 0); existing_link = etcp_link_find_by_addr(e_sock, &addr, 0);
if (existing_link && existing_link->etcp == conn) { if (existing_link && existing_link->etcp == conn) {
if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) { if (memcmp(conn->crypto_ctx.peer_public_key, sc.peer_public_key, SC_PUBKEY_SIZE)) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] link address match but pubkey mismatch, firing node_changed", conn->log_name); DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] link address match but pubkey mismatch, firing node_changed", conn->log_name);
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "pubkey mismatch on reused link for node %016llx", (unsigned long long)peer_id); DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "pubkey mismatch on reused link for node %016llx", (unsigned long long)peer_id);
conn->callbacks_running = 1; conn->callbacks_running = 1;
etcp_cbk_fire(conn, ETCP_CBK_EVENT_NODE_CHANGED); etcp_cbk_fire(conn, ETCP_CBK_EVENT_NODE_CHANGED);
@ -2157,11 +2153,11 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
errorcode = 67; errorcode = 67;
goto ec_fr; goto ec_fr;
} }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] found existing outbound link by addr for incoming INIT, reusing link=%p", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] found existing outbound link by addr for incoming INIT, reusing link=%p",
conn->log_name, existing_link); conn->log_name, existing_link);
} else if (existing_link) { } else if (existing_link) {
struct ETCP_CONN* old_conn = existing_link->etcp; struct ETCP_CONN* old_conn = existing_link->etcp;
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] conflicting link at %s belongs to %s, firing node_changed", DEBUG_WARN(DEBUG_CATEGORY_ETCP, "[%s] conflicting link at %s belongs to %s, firing node_changed",
conn->log_name, sockaddr_storage_to_str(&addr).str, old_conn->log_name); conn->log_name, sockaddr_storage_to_str(&addr).str, old_conn->log_name);
DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "link address conflict for node %016llx, firing node_changed callbacks on %s", DEBUG_ERROR(DEBUG_CATEGORY_CRYPTO, "link address conflict for node %016llx, firing node_changed callbacks on %s",
(unsigned long long)peer_id, old_conn->log_name); (unsigned long long)peer_id, old_conn->log_name);
@ -2178,10 +2174,10 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
uint8_t send_reset = 0; uint8_t send_reset = 0;
if (existing_link && existing_link->etcp == conn) {// существующий линк if (existing_link && existing_link->etcp == conn) {// существующий линк
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] found existing link for id=%d, socket=[%s]", conn->log_name, req->link_id, e_sock->name); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] found existing link for id=%d, socket=[%s]", conn->log_name, req->link_id, e_sock->name);
link = existing_link; link = existing_link;
if (!sockaddr_equal(&link->remote_addr, &addr)) { if (!sockaddr_equal(&link->remote_addr, &addr)) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] IP:port changed for remote_link_id=%d socket:[%s] — closing old link, creating new", DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] IP:port changed for remote_link_id=%d socket:[%s] — closing old link, creating new",
conn->log_name, req->link_id, e_sock->name); conn->log_name, req->link_id, e_sock->name);
etcp_link_close(link); etcp_link_close(link);
goto create_new_link; goto create_new_link;
@ -2194,7 +2190,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
// ── Collision handling ── // ── Collision handling ──
if (req->collision) { if (req->collision) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] INIT collision=1 from peer=%016llx — remote is master, becoming slave", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] INIT collision=1 from peer=%016llx — remote is master, becoming slave",
conn->log_name, (unsigned long long)peer_id); conn->log_name, (unsigned long long)peer_id);
etcp_conn_reinit(conn, "collision yield"); etcp_conn_reinit(conn, "collision yield");
send_reset = 1; send_reset = 1;
@ -2203,13 +2199,13 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
struct ETCP_LINK* ml = etcp_select_collision_link(conn, &addr); struct ETCP_LINK* ml = etcp_select_collision_link(conn, &addr);
if (ml) { if (ml) {
if (conn->instance->node_id < peer_id) { if (conn->instance->node_id < peer_id) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] COLLISION: we=master node_id=%016llx < peer=%016llx — sending collision INIT", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] COLLISION: we=master node_id=%016llx < peer=%016llx — sending collision INIT",
conn->log_name, (unsigned long long)conn->instance->node_id, (unsigned long long)peer_id); conn->log_name, (unsigned long long)conn->instance->node_id, (unsigned long long)peer_id);
memory_pool_free(e_sock->instance->pkt_pool, pkt); memory_pool_free(e_sock->instance->pkt_pool, pkt);
etcp_link_send_init(ml, 0, 1); etcp_link_send_init(ml, 0, 1);
return; return;
} }
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] COLLISION: peer smaller, yielding master, processing as slave", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] COLLISION: peer smaller, yielding master, processing as slave",
conn->log_name); conn->log_name);
if (ml->init_timer) { uasync_cancel_timeout(conn->instance->ua, ml->init_timer); ml->init_timer = NULL; } if (ml->init_timer) { uasync_cancel_timeout(conn->instance->ua, ml->init_timer); ml->init_timer = NULL; }
} }
@ -2233,10 +2229,10 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
} }
} else { } else {
create_new_link: create_new_link:
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] NO existing link for id=%d, socket=[%s]", conn->log_name, req->link_id, e_sock->name); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] NO existing link for id=%d, socket=[%s]", conn->log_name, req->link_id, e_sock->name);
// Create new link // Create new link
link = etcp_link_new(conn, e_sock, &addr, 1); link = etcp_link_new(conn, e_sock, &addr, 1);
if (!link) { if (new_conn) etcp_connection_close(conn); errorcode=66; DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "failed to create link for connection"); goto ec_fr; }// облом if (!link) { if (new_conn) etcp_connection_close(conn); errorcode=66; DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "failed to create link for connection"); goto ec_fr; }// облом
link->remote_link_id = req->link_id; link->remote_link_id = req->link_id;
link->remote_socket_id = req->socket_id; link->remote_socket_id = req->socket_id;
link->remote_only_local = req->only_local; link->remote_only_local = req->only_local;
@ -2244,7 +2240,7 @@ create_new_link:
// ── Collision handling ── // ── Collision handling ──
if (req->collision) { if (req->collision) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] INIT collision=1 from peer=%016llx — remote is master, becoming slave", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] INIT collision=1 from peer=%016llx — remote is master, becoming slave",
conn->log_name, (unsigned long long)peer_id); conn->log_name, (unsigned long long)peer_id);
etcp_conn_reinit(conn, "collision yield"); etcp_conn_reinit(conn, "collision yield");
send_reset = 1; send_reset = 1;
@ -2252,7 +2248,7 @@ create_new_link:
// Check if WE have an outbound (master) link // Check if WE have an outbound (master) link
struct ETCP_LINK* ml = etcp_select_collision_link(conn, &addr); struct ETCP_LINK* ml = etcp_select_collision_link(conn, &addr);
if (ml && conn->instance->node_id < peer_id) { if (ml && conn->instance->node_id < peer_id) {
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] COLLISION: we=master node_id=%016llx < peer=%016llx — sending collision INIT", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] COLLISION: we=master node_id=%016llx < peer=%016llx — sending collision INIT",
conn->log_name, (unsigned long long)conn->instance->node_id, (unsigned long long)peer_id); conn->log_name, (unsigned long long)conn->instance->node_id, (unsigned long long)peer_id);
memory_pool_free(e_sock->instance->pkt_pool, pkt); memory_pool_free(e_sock->instance->pkt_pool, pkt);
etcp_link_send_init(ml, 0, 1); etcp_link_send_init(ml, 0, 1);
@ -2311,7 +2307,7 @@ int etcp_packet_decrypted(struct ETCP_SOCKET* e_sock, struct ETCP_DGRAM* pkt,
link->remote_keepalive = pkt->flag_up; link->remote_keepalive = pkt->flag_up;
if (link->recv_keepalive != 1) { if (link->recv_keepalive != 1) {
link->recv_keepalive = 1; link->recv_keepalive = 1;
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Link %d recv_keepalive restored to 1 (was 0) link_status=%d remote_ka=%d state=%d init=%d links_up=%d", DEBUG_DEBUG(DEBUG_CATEGORY_KEEPALIVE, "[%s] Link %d recv_keepalive restored to 1 (was 0) link_status=%d remote_ka=%d state=%d init=%d links_up=%d",
link->etcp->log_name, link->local_link_id, link->link_status, link->remote_keepalive, link->link_state, link->initialized, link->etcp->links_up); link->etcp->log_name, link->local_link_id, link->link_status, link->remote_keepalive, link->link_state, link->initialized, link->etcp->links_up);
} }
@ -2399,7 +2395,7 @@ int etcp_create_server_socket(struct UTUN_INSTANCE* instance, struct CFG_SERVER*
} }
int init_sockets(struct UTUN_INSTANCE* instance) { int init_sockets(struct UTUN_INSTANCE* instance) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!instance || !instance->config) return -1; if (!instance || !instance->config) return -1;
if (instance->etcp_sockets || instance->stcp_servers) { if (instance->etcp_sockets || instance->stcp_servers) {
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Sockets already initialized, skipping"); DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Sockets already initialized, skipping");
@ -2485,7 +2481,7 @@ int init_sockets(struct UTUN_INSTANCE* instance) {
} }
success_count++; success_count++;
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "Initialized server %s on %s (links: %d)", DEBUG_INFO(DEBUG_CATEGORY_ETCP, "Initialized server %s on %s (links: %d)",
server->name, sockaddr_storage_to_str(&server->ip).str, queue_entry_count(sock->links_queue)); server->name, sockaddr_storage_to_str(&server->ip).str, queue_entry_count(sock->links_queue));
server = server->next; server = server->next;
} }
@ -2511,7 +2507,7 @@ struct NODE_CONN_DIRECT* etcp_config_client_reality(struct UTUN_INSTANCE* instan
struct NODE_CONN_DIRECT* handle = NULL; struct NODE_CONN_DIRECT* handle = NULL;
int r = node_conn_direct_open_node(instance, node_id, NULL, NULL, &handle, &ni_tmp, NULL); int r = node_conn_direct_open_node(instance, node_id, NULL, NULL, &handle, &ni_tmp, NULL);
if (r == NCD_ERR || !handle) { if (r == NCD_ERR || !handle) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "client %s reality: ncd open failed node=0x%016llx", client->name, (unsigned long long)node_id); DEBUG_ERROR(DEBUG_CATEGORY_REALITY, "client %s reality: ncd open failed node=0x%016llx", client->name, (unsigned long long)node_id);
return NULL; return NULL;
} }
struct ETCP_CONN* conn = node_conn_direct_get_conn(handle); struct ETCP_CONN* conn = node_conn_direct_get_conn(handle);
@ -2520,32 +2516,32 @@ struct NODE_CONN_DIRECT* etcp_config_client_reality(struct UTUN_INSTANCE* instan
int link_count = 0; int link_count = 0;
for (struct CFG_CLIENT_LINK* cl = client->links; cl; cl = cl->next) { for (struct CFG_CLIENT_LINK* cl = client->links; cl; cl = cl->next) {
if (cl->remote_addr.ss_family != AF_INET && cl->remote_addr.ss_family != AF_INET6) { if (cl->remote_addr.ss_family != AF_INET && cl->remote_addr.ss_family != AF_INET6) {
DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "client %s reality: link without remote addr, skipping", client->name); DEBUG_WARN(DEBUG_CATEGORY_REALITY, "client %s reality: link without remote addr, skipping", client->name);
continue; continue;
} }
struct ETCP_SOCKET* bind_sock = NULL; struct ETCP_SOCKET* bind_sock = NULL;
if (cl->local_srv) { if (cl->local_srv) {
for (struct ETCP_SOCKET* s = instance->etcp_sockets; s; s = s->next) for (struct ETCP_SOCKET* s = instance->etcp_sockets; s; s = s->next)
if (strcmp(cl->local_srv->name, s->name) == 0) { bind_sock = s; break; } if (strcmp(cl->local_srv->name, s->name) == 0) { bind_sock = s; break; }
if (!bind_sock) DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "client %s reality: bind socket '%s' not found, using auto", client->name, cl->local_srv->name); if (!bind_sock) DEBUG_WARN(DEBUG_CATEGORY_REALITY, "client %s reality: bind socket '%s' not found, using auto", client->name, cl->local_srv->name);
else if (!bind_sock->is_tcp) { DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "client %s reality: bind socket '%s' is not TCP, ignoring bind", client->name, cl->local_srv->name); bind_sock = NULL; } else if (!bind_sock->is_tcp) { DEBUG_ERROR(DEBUG_CATEGORY_REALITY, "client %s reality: bind socket '%s' is not TCP, ignoring bind", client->name, cl->local_srv->name); bind_sock = NULL; }
} }
struct ETCP_LINK* tlink = etcp_link_new(conn, bind_sock, &cl->remote_addr, 0); struct ETCP_LINK* tlink = etcp_link_new(conn, bind_sock, &cl->remote_addr, 0);
if (!tlink) { DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "client %s reality: etcp_link_new failed", client->name); continue; } if (!tlink) { DEBUG_ERROR(DEBUG_CATEGORY_REALITY, "client %s reality: etcp_link_new failed", client->name); continue; }
tlink->is_tcp = 1; tlink->is_tcp = 1;
tlink->reality = client->reality; tlink->reality_set = 1; tlink->reality = client->reality; tlink->reality_set = 1;
etcp_tcp_link_start_connect(tlink, &cl->remote_addr, 0); etcp_tcp_link_start_connect(tlink, &cl->remote_addr, 0);
link_count++; link_count++;
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "client %s reality: TCP link %d → %s sn=%s bind=%s", DEBUG_INFO(DEBUG_CATEGORY_REALITY, "client %s reality: TCP link %d → %s sn=%s bind=%s",
client->name, tlink->local_link_id, sockaddr_storage_to_str(&cl->remote_addr).str, client->name, tlink->local_link_id, sockaddr_storage_to_str(&cl->remote_addr).str,
client->reality.server_name, bind_sock ? bind_sock->name : "auto"); client->reality.server_name, bind_sock ? bind_sock->name : "auto");
} }
if (link_count == 0) DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "client %s reality: no links created", client->name); if (link_count == 0) DEBUG_WARN(DEBUG_CATEGORY_REALITY, "client %s reality: no links created", client->name);
return handle; return handle;
} }
int init_connections(struct UTUN_INSTANCE* instance) { int init_connections(struct UTUN_INSTANCE* instance) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!instance || !instance->config) return -1; if (!instance || !instance->config) return -1;
struct utun_config* config = instance->config; struct utun_config* config = instance->config;
@ -2569,7 +2565,7 @@ int init_connections(struct UTUN_INSTANCE* instance) {
// Initialize clients via node_conn_direct // Initialize clients via node_conn_direct
struct CFG_CLIENT* client = config->clients; struct CFG_CLIENT* client = config->clients;
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "init_connections: clients=%p total_conns=%d", config->clients, queue_entry_count(instance->connections)); DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "init_connections: clients=%p total_conns=%d", config->clients, queue_entry_count(instance->connections));
while (client) { while (client) {
if (strlen(client->peer_public_key_hex) == 0) { if (strlen(client->peer_public_key_hex) == 0) {
DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "no peer public key configured for client %s", client->name); DEBUG_WARN(DEBUG_CATEGORY_CONFIG, "no peer public key configured for client %s", client->name);
@ -2577,11 +2573,11 @@ int init_connections(struct UTUN_INSTANCE* instance) {
} }
uint8_t pubkey_bin[SC_PUBKEY_SIZE]; uint8_t pubkey_bin[SC_PUBKEY_SIZE];
if (sc_hex_to_binary(client->peer_public_key_hex, pubkey_bin, SC_PUBKEY_SIZE) != 0) { if (sc_hex_to_binary(client->peer_public_key_hex, pubkey_bin, SC_PUBKEY_SIZE) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "invalid peer pubkey hex for client %s", client->name); DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "invalid peer pubkey hex for client %s", client->name);
client = client->next; continue; client = client->next; continue;
} }
uint64_t node_id = sc_derive_node_id_from_pubkey(pubkey_bin); uint64_t node_id = sc_derive_node_id_from_pubkey(pubkey_bin);
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "client %s node_id=0x%016llx", client->name, (unsigned long long)node_id); DEBUG_INFO(DEBUG_CATEGORY_ETCP, "client %s node_id=0x%016llx", client->name, (unsigned long long)node_id);
if (client->reality_enabled) { if (client->reality_enabled) {
struct NODE_CONN_DIRECT* rhandle = etcp_config_client_reality(instance, client, pubkey_bin, node_id); struct NODE_CONN_DIRECT* rhandle = etcp_config_client_reality(instance, client, pubkey_bin, node_id);
@ -2590,7 +2586,7 @@ int init_connections(struct UTUN_INSTANCE* instance) {
if (ch) { ch->node_id = node_id; strncpy(ch->name, client->name, MAX_CONN_NAME_LEN - 1); if (ch) { ch->node_id = node_id; strncpy(ch->name, client->name, MAX_CONN_NAME_LEN - 1);
ch->handle = rhandle; ch->next = instance->config_conn_handles; ch->handle = rhandle; ch->next = instance->config_conn_handles;
instance->config_conn_handles = ch; instance->config_conn_handles = ch;
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "client %s saved reality handle to config_conn_handles", client->name); } DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "client %s saved reality handle to config_conn_handles", client->name); }
} }
client = client->next; continue; client = client->next; continue;
} }
@ -2632,11 +2628,11 @@ int init_connections(struct UTUN_INSTANCE* instance) {
break; break;
} }
conn = node_conn_direct_get_conn(handle); conn = node_conn_direct_get_conn(handle);
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "client %s ncd handle=%p conn=%p %s sock=%s", DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "client %s ncd handle=%p conn=%p %s sock=%s",
client->name, handle, conn, r == NCD_NEW ? "NEW" : "REUSED", sock->name); client->name, handle, conn, r == NCD_NEW ? "NEW" : "REUSED", sock->name);
} else { } else {
struct ETCP_LINK* link = etcp_link_new(conn, sock, &cl->remote_addr, 0); struct ETCP_LINK* link = etcp_link_new(conn, sock, &cl->remote_addr, 0);
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "client %s added link link_id=%d sock=%s", client->name, link ? link->local_link_id : -1, sock->name); DEBUG_INFO(DEBUG_CATEGORY_ETCP, "client %s added link link_id=%d sock=%s", client->name, link ? link->local_link_id : -1, sock->name);
} }
} }
@ -2645,7 +2641,7 @@ int init_connections(struct UTUN_INSTANCE* instance) {
if (ch) { ch->node_id = node_id; strncpy(ch->name, client->name, MAX_CONN_NAME_LEN - 1); if (ch) { ch->node_id = node_id; strncpy(ch->name, client->name, MAX_CONN_NAME_LEN - 1);
ch->handle = handle; ch->next = instance->config_conn_handles; ch->handle = handle; ch->next = instance->config_conn_handles;
instance->config_conn_handles = ch; instance->config_conn_handles = ch;
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "client %s saved handle to config_conn_handles", client->name); } DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "client %s saved handle to config_conn_handles", client->name); }
} }
client = client->next; client = client->next;

8
src/transport_layer/node_conn_direct.c

@ -169,9 +169,9 @@ static int ncd_create_links(struct ncd_entry* entry, struct TOPO_NODE* ni,
/* ---- IPv4 ---- */ /* ---- IPv4 ---- */
for (const struct TOPO_ADDR4* a = ni->v4_addrs; a; a = a->next) { for (const struct TOPO_ADDR4* a = ni->v4_addrs; a; a = a->next) {
v4_addrs++; v4_addrs++;
if (a->port == 0 || !(a->protocol & (TOPO_PROTO_UDP | TOPO_PROTO_TCP))) { DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[ncd] v4 skip proto=%02x port=%d node=0x%016llx", a->protocol, (int)a->port, (unsigned long long)nid); v4_skip++; continue; } if (a->port == 0 || !(a->protocol & (TOPO_PROTO_UDP | TOPO_PROTO_TCP))) { DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[ncd] v4 skip proto=%02x port=%d node=0x%016llx", a->protocol, (int)a->port, (unsigned long long)nid); v4_skip++; continue; }
int zero = 1; for (int j = 0; j < 4; j++) if (a->addr[j] != 0) { zero = 0; break; } int zero = 1; for (int j = 0; j < 4; j++) if (a->addr[j] != 0) { zero = 0; break; }
if (zero) { DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[ncd] v4 skip zero-addr node=0x%016llx", (unsigned long long)nid); continue; } if (zero) { DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[ncd] v4 skip zero-addr node=0x%016llx", (unsigned long long)nid); continue; }
struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; struct sockaddr_in sin; memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET;
memcpy(&sin.sin_addr.s_addr, a->addr, 4); sin.sin_port = htons(a->port); memcpy(&sin.sin_addr.s_addr, a->addr, 4); sin.sin_port = htons(a->port);
struct sockaddr_storage sa; memcpy(&sa, &sin, sizeof(sin)); struct sockaddr_storage sa; memcpy(&sa, &sin, sizeof(sin));
@ -198,9 +198,9 @@ static int ncd_create_links(struct ncd_entry* entry, struct TOPO_NODE* ni,
/* ---- IPv6 ---- */ /* ---- IPv6 ---- */
for (const struct TOPO_ADDR6* a = ni->v6_addrs; a; a = a->next) { for (const struct TOPO_ADDR6* a = ni->v6_addrs; a; a = a->next) {
v6_addrs++; v6_addrs++;
if (a->port == 0 || !(a->protocol & (TOPO_PROTO_UDP | TOPO_PROTO_TCP))) { DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[ncd] v6 skip proto=%02x port=%d node=0x%016llx", a->protocol, (int)a->port, (unsigned long long)nid); v6_skip++; continue; } if (a->port == 0 || !(a->protocol & (TOPO_PROTO_UDP | TOPO_PROTO_TCP))) { DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[ncd] v6 skip proto=%02x port=%d node=0x%016llx", a->protocol, (int)a->port, (unsigned long long)nid); v6_skip++; continue; }
int zero = 1; for (int j = 0; j < 16; j++) if (a->addr[j] != 0) { zero = 0; break; } int zero = 1; for (int j = 0; j < 16; j++) if (a->addr[j] != 0) { zero = 0; break; }
if (zero) { DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[ncd] v6 skip zero-addr node=0x%016llx", (unsigned long long)nid); continue; } if (zero) { DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[ncd] v6 skip zero-addr node=0x%016llx", (unsigned long long)nid); continue; }
int is_ll = (a->addr[0] == 0xfe && (a->addr[1] & 0xc0) == 0x80); int is_ll = (a->addr[0] == 0xfe && (a->addr[1] & 0xc0) == 0x80);
struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; struct sockaddr_in6 sin6; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6;
memcpy(&sin6.sin6_addr, a->addr, 16); sin6.sin6_port = htons(a->port); memcpy(&sin6.sin6_addr, a->addr, 16); sin6.sin6_port = htons(a->port);

6
tools/chatgui-android/AGENTS.md

@ -203,10 +203,10 @@ allow_all=yes
[ntp] [ntp]
enabled=no enabled=no
[chat] [chatserver]
storage_autoload=1 storage_autoload=1
storage_autoload_maxsize_mb=10 storage_unit_size=10M
storage_maxsize_gb=1 storage_total_size=1G
opus_codec_preset=1 opus_codec_preset=1
compressor_enabled=0 compressor_enabled=0
compressor_max_gain_db=25 compressor_max_gain_db=25

2
tools/chatgui/src/audiodevicesettingspage.cpp

@ -345,7 +345,7 @@ void AudioDeviceSettingsPage::buildCompressorUI(QVBoxLayout* layout) {
}; };
makeSliderRow("Max gain:", m_compressorMaxGainSlider, m_compressorMaxGainLabel, makeSliderRow("Max gain:", m_compressorMaxGainSlider, m_compressorMaxGainLabel,
0, 50, 1); 1, 50, 1);
makeSliderRow("Rise rate (x/sec):", m_compressorRiseRateSlider, m_compressorRiseRateLabel, makeSliderRow("Rise rate (x/sec):", m_compressorRiseRateSlider, m_compressorRiseRateLabel,
2, 10, 1); 2, 10, 1);

59
tools/chatgui/src/settingsdialog.cpp

@ -214,39 +214,50 @@ void SettingsDialog::onCategoryChanged(int row) {
void SettingsDialog::onSave() { void SettingsDialog::onSave() {
QString newName = m_nicknameEdit->text().trimmed(); QString newName = m_nicknameEdit->text().trimmed();
bool nameChanged = (newName != m_oldNickname);
/* update name in uTun if changed */ /* update name in uTun if changed */
if (newName != m_oldNickname) { if (nameChanged) {
char* name_copy = u_strdup(newName.toUtf8().constData()); char* name_copy = u_strdup(newName.toUtf8().constData());
if (name_copy) gui_bridge_post_uasync_fn(chat_core_update_my_name_trampoline, name_copy); if (name_copy) gui_bridge_post_uasync_fn(chat_core_update_my_name_trampoline, name_copy);
m_oldNickname = newName; m_oldNickname = newName;
} }
// Save nickname to config /* Save nickname to config — только при изменении имени, иначе перезапись плодит дубли */
QFile f(m_configPath); if (nameChanged) {
if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { accept(); return; } QFile f(m_configPath);
QString content = f.readAll(); if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
f.close(); QString content = f.readAll();
f.close();
QTextStream ts(&content);
QStringList lines; QTextStream ts(&content);
while (!ts.atEnd()) lines << ts.readLine(); QStringList lines;
while (!ts.atEnd()) lines << ts.readLine();
bool found = false;
for (int i = 0; i < lines.size(); i++) { bool found = false;
if (lines[i].trimmed().startsWith("my_node_name=")) { for (int i = 0; i < lines.size(); i++) {
lines[i] = "my_node_name=" + newName; if (lines[i].trimmed().startsWith("my_node_name=")) {
found = true; if (!found) { lines[i] = "my_node_name=" + newName; found = true; }
} else if (!found && lines[i].trimmed() == "[global]") { else lines.removeAt(i--); /* дубль — удалить */
lines.insert(i + 1, "my_node_name=" + newName); }
found = true; }
if (!found) {
for (int i = 0; i < lines.size(); i++) {
if (lines[i].trimmed() == "[global]") {
lines.insert(i + 1, "my_node_name=" + newName);
found = true;
break;
}
}
if (!found) lines << "my_node_name=" + newName;
}
if (f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text)) {
f.write(lines.join('\n').toUtf8());
f.close();
}
} }
} }
if (!found) lines << "my_node_name=" + newName;
f.open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Text);
f.write(lines.join('\n').toUtf8());
f.close();
m_networkPage->saveToConfig(m_configPath); m_networkPage->saveToConfig(m_configPath);

4
tools/chatgui/src/storagesettingspage.cpp

@ -106,7 +106,7 @@ void StorageSettingsPage::applyAndSave() {
if (!m_configPath.isEmpty()) { if (!m_configPath.isEmpty()) {
postChatSetting(m_configPath, "storage_autoload", autoload); postChatSetting(m_configPath, "storage_autoload", autoload);
postChatSetting(m_configPath, "storage_autoload_maxsize_mb", autoloadMaxSize); config_update_option(m_configPath, "chatserver", "storage_unit_size", QString::number(autoloadMaxSize) + "M", CONFIG_UPDATE_REPLACE);
postChatSetting(m_configPath, "storage_maxsize_gb", maxGb); config_update_option(m_configPath, "chatserver", "storage_total_size", QString::number(maxGb) + "G", CONFIG_UPDATE_REPLACE);
} }
} }

5
utun.conf.sample

@ -156,7 +156,12 @@ allow=all
#db_path=/var/lib/utun # путь к SQLite базе данных (обязательно) #db_path=/var/lib/utun # путь к SQLite базе данных (обязательно)
#join_password=secret123 # пароль входа в группы (будет в invite-ссылке) #join_password=secret123 # пароль входа в группы (будет в invite-ссылке)
#allowed_groups=all # "all" или hex-ID через запятую #allowed_groups=all # "all" или hex-ID через запятую
#headless_control_bind=127.0.0.1:9999 # TCP control-socket для headless chat CLI
#storage_total_size=500M # общий лимит медиакеша (0=безлимит) #storage_total_size=500M # общий лимит медиакеша (0=безлимит)
#storage_unit_size=50M # лимит одного медиафайла (0=отключено) #storage_unit_size=50M # лимит одного медиафайла (0=отключено)
#storage_autoload=1 # автозагрузка медиавложений (0/1) #storage_autoload=1 # автозагрузка медиавложений (0/1)
#media_download_max_peers=3 # макс. одновременных пиров для загрузки #media_download_max_peers=3 # макс. одновременных пиров для загрузки
#opus_codec_preset=1 # пресет Opus (0..4)
#compressor_enabled=0 # компрессор голосовых сообщений (0/1)
#compressor_max_gain_db=25 # макс. gain компрессора, дБ (1..100)
#compressor_rise_rate=10 # скорость нарастания компрессора (1..100)

Loading…
Cancel
Save