diff --git a/src/etcp_connections.c b/src/etcp_connections.c index a484678..a322365 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -34,12 +34,12 @@ static void keepalive_timer_cb(void* arg); static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); - DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_init link=%p, is_server=%d, reset=%d", link, link ? link->is_server : -1, reset); + DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "link=%p, is_server=%d, reset=%d", link, link ? link->is_server : -1, reset); if (!link || !link->etcp || !link->etcp->instance) return; struct ETCP_DGRAM* dgram = u_malloc(sizeof(struct ETCP_DGRAM) + 100); if (!dgram) { - DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_init: malloc failed"); + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "malloc failed"); return; } @@ -96,29 +96,55 @@ static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset) { u_free(dgram); link->init_retry_count++; - - if (!link->init_timer && link->is_server == 0) { - 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); - } else if (link->init_timer) { - if ((link->init_retry_count % 10) == 0 && link->init_timeout < INIT_TIMEOUT_MAX) { - link->init_timeout *= 2; - if (link->init_timeout > INIT_TIMEOUT_MAX) link->init_timeout = INIT_TIMEOUT_MAX; - } - uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer); - link->init_timer = uasync_set_timeout(link->etcp->instance->ua, link->init_timeout, link, etcp_link_init_timer_cbk); - } } static void etcp_link_init_timer_cbk(void* arg) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); struct ETCP_LINK* link = (struct ETCP_LINK*)arg; - if (!link || link->initialized || link->is_server != 0) return; + if (!link) return; - link->init_timer = NULL; - etcp_link_send_init(link,1); + if ((link->init_retry_count % 10) == 0 && link->init_timeout < INIT_TIMEOUT_MAX) { + link->init_timeout += link->init_timeout/4 +1; + if (link->init_timeout > INIT_TIMEOUT_MAX) link->init_timeout = INIT_TIMEOUT_MAX; + } + link->init_timer = uasync_set_timeout(link->etcp->instance->ua, link->init_timeout, link, etcp_link_init_timer_cbk); + + if (link->link_state == 1) etcp_link_send_init(link,1);// init (with etcp reset) + else etcp_link_send_init(link,0);// no etcp reset (reinit) +} + +void etcp_link_restart_init_timer(struct ETCP_LINK* link) { + DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); + if (link->init_timer) uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer); + 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); } +void etcp_link_enter_init(struct ETCP_LINK* link) {// + DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); + if (!link) return; + link->link_state = 1; // handshake + if (link->is_server != 0) return; + etcp_link_send_init(link,1);// init with reset + etcp_link_restart_init_timer(link); +} + +void etcp_link_enter_reinit(struct ETCP_LINK* link) { + DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); + if (!link) return; + link->link_state = 2; // reconnect + if (link->is_server != 0) return; + etcp_link_send_init(link,0);// init without reset + + if (link->keepalive_timer) {// keepalive заменяяется reinit запросами + uasync_cancel_timeout(link->etcp->instance->ua, link->keepalive_timer); + link->keepalive_timer = NULL; + } + + etcp_link_restart_init_timer(link); +} + + // Send empty keepalive packet (only timestamp, no sections) static void etcp_link_send_keepalive(struct ETCP_LINK* link) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); @@ -159,22 +185,6 @@ static int etcp_all_links_down(struct ETCP_CONN* etcp) { return 1; // All links are down } -// Start link recovery process - send CHANNEL_INIT (0x04) on all links -static void etcp_start_link_recovery(struct ETCP_LINK* link) { - if (!link) return; - - DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] Starting link recovery - all links are down", link->etcp->log_name ? link->etcp->log_name : "????→????"); - - struct ETCP_CONN* etcp = link->etcp; - if (link->is_server == 0) { // Only client links - // Send CHANNEL_INIT (0x04) without reset - etcp_link_send_init(link, 0); - DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "[%s] Sent CHANNEL_INIT on link %p for recovery", - etcp->log_name, link); - } - link = link->next; -} - // Cancel init_timer for all links of an ETCP_CONN static void etcp_cancel_all_init_timers(struct ETCP_CONN* etcp) { if (!etcp) return; @@ -195,16 +205,17 @@ static void etcp_cancel_all_init_timers(struct ETCP_CONN* etcp) { static void keepalive_timer_cb(void* arg) { DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, ""); struct ETCP_LINK* link = (struct ETCP_LINK*)arg; - if (!link || !link->etcp || !link->etcp->instance) return; + if (!link || !link->etcp || !link->etcp->instance) { + DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "KEEPALIVE NULL !!!!!!!!"); + return; + } link->keepalive_timer = NULL; // Check if all links are down and start recovery if needed (client only) if (link->is_server == 0 && etcp_all_links_down(link->etcp)) { DEBUG_WARN(DEBUG_CATEGORY_CONNECTION, "[%s] All links are down, starting recovery", link->etcp->log_name); - etcp_start_link_recovery(link); - if (link->recovery_interval==0) link->recovery_interval=link->keepalive_interval*10; - link->keepalive_timer = uasync_set_timeout(link->etcp->instance->ua, link->recovery_interval, link, keepalive_timer_cb); + etcp_link_enter_reinit(link);// keepalive timr после reinit не нужен return; } @@ -238,14 +249,7 @@ static void keepalive_timer_cb(void* arg) { } // Send keepalive only if no packets were sent since last tick - if (!link->pkt_sent_since_keepalive) { - etcp_link_send_keepalive(link); - } else { -// DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Keepalive skipped - packet sent since last tick", link->etcp->log_name); - link->recovery_interval=0; - } - - // Reset flag for next interval + if (!link->pkt_sent_since_keepalive) etcp_link_send_keepalive(link); link->pkt_sent_since_keepalive = 0; restart_timer: @@ -598,7 +602,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn if (is_server == 0) { DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "etcp_link_new: client link, calling etcp_link_send_init"); - etcp_link_send_init(link,1); + etcp_link_enter_init(link); } return link; @@ -1078,10 +1082,23 @@ process_decrypted: link->etcp->peer_node_id = server_node_id; // If not set etcp_update_log_name(link->etcp); // Update log_name with peer_node_id + // Cancel init timer if exists + if (link->init_timer) { + uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer); + link->init_timer = NULL; + } + + if (link->keepalive_timer) { + uasync_cancel_timeout(link->etcp->instance->ua, link->keepalive_timer); + link->keepalive_timer = NULL; + } + // Mark link as initialized // DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "Setting link->initialized=1, link=%p, is_server=%d", link, link->is_server); link->initialized = 1;// получен init response (client) // link->link_status = 1; // Link is up after successful initialization + link->link_state = 3; // connected + if (link->etcp->initialized == 0) { etcp_conn_ready(link->etcp); } @@ -1092,24 +1109,16 @@ process_decrypted: // Start keepalive timer etcp_link_send_keepalive(link); - if (!link->keepalive_timer && link->keepalive_interval > 0) { - DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Keepalive timer started on link %p (interval=%d ms)", - link->etcp->log_name, link, link->keepalive_interval); - link->keepalive_timer = uasync_set_timeout(link->etcp->instance->ua, - link->keepalive_interval * 10, - link, keepalive_timer_cb); + + if (link->keepalive_interval > 0) { + DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Keepalive timer started on link %p (interval=%d ms)", link->etcp->log_name, link, link->keepalive_interval); + link->keepalive_timer = uasync_set_timeout(link->etcp->instance->ua, link->keepalive_interval * 10, link, keepalive_timer_cb); } loadbalancer_link_ready(link); DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "etcp client: Link initialized successfully! Server node_id=%016llx, mtu=%d, local_link_id=%d, remote_link_id=%d", (unsigned long long)server_node_id, link->mtu, link->local_link_id, link->remote_link_id); - // Cancel init timer if exists - if (link->init_timer) { - uasync_cancel_timeout(link->etcp->instance->ua, link->init_timer); - link->init_timer = NULL; - } - memory_pool_free(e_sock->instance->pkt_pool, pkt); return; // INIT_RESPONSE is handled, no further processing needed } diff --git a/src/etcp_connections.h b/src/etcp_connections.h index 02cfb61..4311abf 100644 --- a/src/etcp_connections.h +++ b/src/etcp_connections.h @@ -72,6 +72,7 @@ struct ETCP_LINK { uint8_t recv_keepalive; // 1 - up, 0 - down (принимаются ли пакеты) uint8_t remote_keepalive; // 1 - up, 0 - down (удаленная сторона сообщает - принимаются ли у нее пакеты) uint8_t link_status; // 1 - up, 0 - down (итоговый статус - если есть проблемы на любой стороне - линк down) + uint8_t link_state; // 0 - just init, 1 - handshake, 2 - try reconnect, 3 - connected // Состояние установки соединения (только для клиентов) void* init_timer; // Таймер для повторов INIT (NULL=не подключается) diff --git a/src/etcp_send_test.txt b/src/etcp_send_test.txt index 917f63f..8a4fd95 100644 --- a/src/etcp_send_test.txt +++ b/src/etcp_send_test.txt @@ -5,4 +5,28 @@ 2. вписываешь в link_ready_for_send_fn свою функцию 3. в тесте открываешь ответный сокет 4. добавляешь линк к etcp -5. \ No newline at end of file +5. + + + + +link initialization: + +client: + +1. init timer: + - шлём init with reset + +Получили response: + - отменяем init, переходим в обычный режим + keepalive + +link не отвечает: + - шлём init without reset + +server: + - просто ждёт init request. + как получил init, делает линк инициализированным. + +общая логика keepalive (client+server): + далее на init линках шлём keepalive со статусом remote keepalive. + если remote keepalive =0 - значит на другой стороне всё плохо и не шлём данные (только keepalive) diff --git a/src/utun.c b/src/utun.c index c32d6a3..209fd16 100644 --- a/src/utun.c +++ b/src/utun.c @@ -385,6 +385,7 @@ int main(int argc, char *argv[]) { } DEBUG_INFO(DEBUG_CATEGORY_MEMORY, "Run mainloop"); + DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "Run mainloop"); while (instance && instance->running) { uasync_poll(ua, 100); diff --git a/src/utun_instance.c b/src/utun_instance.c index 155102e..1d30f5c 100644 --- a/src/utun_instance.c +++ b/src/utun_instance.c @@ -400,6 +400,7 @@ int utun_instance_init(struct UTUN_INSTANCE *instance) { // Start the main loop instance->running = 1; + DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "Connections initialized successfully"); return 0; }