ETCP: реализация keepalive пакетов для каждого линка
- Добавлены поля keepalive_timer и pkt_sent_since_keepalive в struct ETCP_LINK - Реализована отправка пустых keepalive пакетов (только timestamp) по таймеру - Keepalive пропускается если был отправлен другой пакет с момента последнего тика - Таймер запускается после инициализации линка (keepalive_interval из конфига) - Исправлен тест test_bgp_route_exchange: убран лишний htonl() при проверке маршрутов
This commit is contained in:
1 parent
232bd49309
commit
15a9521559
3 files changed
+99
-3
No files matched your search
+92
-1
@@ -36,6 +36,8 @@ static void packet_dump(const char* prefix, const uint8_t* data, size_t len, str
|
||||
static void etcp_link_send_init(struct ETCP_LINK* link);
|
||||
static int etcp_link_send_reset(struct ETCP_LINK* link);
|
||||
static void etcp_link_init_timer_cbk(void* arg);
|
||||
static void etcp_link_send_keepalive(struct ETCP_LINK* link);
|
||||
static void keepalive_timer_cb(void* arg);
|
||||
|
||||
#define INIT_TIMEOUT_INITIAL 500
|
||||
#define INIT_TIMEOUT_MAX 50000
|
||||
@@ -112,11 +114,69 @@ 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;
|
||||
|
||||
|
||||
link->init_timer = NULL;
|
||||
etcp_link_send_init(link);
|
||||
}
|
||||
|
||||
// Send empty keepalive packet (only timestamp, no sections)
|
||||
static void etcp_link_send_keepalive(struct ETCP_LINK* link) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!link || !link->etcp || !link->etcp->instance) return;
|
||||
|
||||
struct ETCP_DGRAM* dgram = malloc(sizeof(struct ETCP_DGRAM) + 2);
|
||||
if (!dgram) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_send_keepalive: malloc failed");
|
||||
return;
|
||||
}
|
||||
|
||||
dgram->link = link;
|
||||
dgram->data_len = 0; // Empty packet - only timestamp in header
|
||||
dgram->noencrypt_len = 0;
|
||||
dgram->timestamp = get_current_timestamp();
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Sending keepalive on link %p (local_id=%d)",
|
||||
link->etcp->log_name, link, link->local_link_id);
|
||||
|
||||
etcp_encrypt_send(dgram);
|
||||
free(dgram);
|
||||
}
|
||||
|
||||
// Keepalive timer callback
|
||||
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;
|
||||
|
||||
link->keepalive_timer = NULL;
|
||||
|
||||
// Skip if link is not initialized
|
||||
if (!link->initialized) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Keepalive skipped - link not initialized",
|
||||
link->etcp->log_name);
|
||||
goto restart_timer;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
// Reset flag for next interval
|
||||
link->pkt_sent_since_keepalive = 0;
|
||||
|
||||
restart_timer:
|
||||
// Restart timer
|
||||
if (link->keepalive_interval > 0) {
|
||||
link->keepalive_timer = uasync_set_timeout(link->etcp->instance->ua,
|
||||
link->keepalive_interval * 10,
|
||||
link, keepalive_timer_cb);
|
||||
}
|
||||
}
|
||||
|
||||
static int etcp_link_send_reset(struct ETCP_LINK* link) {
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "");
|
||||
if (!link) return -1;
|
||||
@@ -462,6 +522,12 @@ void etcp_link_close(struct ETCP_LINK* link) {
|
||||
link->shaper_timer = NULL;
|
||||
}
|
||||
|
||||
// Cancel keepalive timer if active
|
||||
if (link->keepalive_timer) {
|
||||
uasync_cancel_timeout(link->etcp->instance->ua, link->keepalive_timer);
|
||||
link->keepalive_timer = NULL;
|
||||
}
|
||||
|
||||
// универсальное удаление из односвязного списка
|
||||
struct ETCP_LINK **pp = &link->etcp->links;
|
||||
while (*pp) {
|
||||
@@ -482,6 +548,11 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) {
|
||||
// DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "etcp_encrypt_send called, link=%p", dgram ? dgram->link : NULL);
|
||||
// printf("[ETCP DEBUG] etcp_encrypt_send: ENTERING FUNCTION\n");
|
||||
|
||||
if (!dgram || !dgram->link) return -1;
|
||||
|
||||
// Mark that packet was sent (for keepalive logic)
|
||||
dgram->link->pkt_sent_since_keepalive = 1;
|
||||
|
||||
int errcode=0;
|
||||
sc_context_t* sc = &dgram->link->etcp->crypto_ctx;
|
||||
int len=dgram->data_len-dgram->noencrypt_len;// не забываем добавить timestamp (2 bytes)
|
||||
@@ -702,6 +773,16 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
|
||||
memory_pool_free(e_sock->instance->pkt_pool, pkt);
|
||||
link->initialized = 1;// получен init request (server), считаем линк уже готовым к работе
|
||||
|
||||
// Start keepalive timer
|
||||
if (!link->keepalive_timer && link->keepalive_interval > 0) {
|
||||
link->keepalive_timer = uasync_set_timeout(link->etcp->instance->ua,
|
||||
link->keepalive_interval * 10,
|
||||
link, keepalive_timer_cb);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Keepalive timer started on link %p (interval=%d ms)",
|
||||
link->etcp->log_name, link, link->keepalive_interval);
|
||||
}
|
||||
|
||||
loadbalancer_link_ready(link);
|
||||
|
||||
// Notify BGP about new connection to send routing table
|
||||
@@ -792,6 +873,16 @@ process_decrypted:
|
||||
// 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)
|
||||
|
||||
// Start keepalive timer
|
||||
if (!link->keepalive_timer && link->keepalive_interval > 0) {
|
||||
link->keepalive_timer = uasync_set_timeout(link->etcp->instance->ua,
|
||||
link->keepalive_interval * 10,
|
||||
link, keepalive_timer_cb);
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_CONNECTION, "[%s] Keepalive timer started on link %p (interval=%d ms)",
|
||||
link->etcp->log_name, link, link->keepalive_interval);
|
||||
}
|
||||
|
||||
loadbalancer_link_ready(link);
|
||||
|
||||
// Notify BGP about new connection to send routing table
|
||||
|
||||
@@ -90,6 +90,10 @@ struct ETCP_LINK {
|
||||
uint16_t nat_port; // NAT port (network byte order)
|
||||
uint32_t nat_changes_count; // Counter of NAT address changes
|
||||
uint32_t nat_hits_count; // Counter of NAT address matches (new init response with same IP:port)
|
||||
|
||||
// Keepalive state
|
||||
void* keepalive_timer; // Таймер для отправки keepalive пакетов
|
||||
uint8_t pkt_sent_since_keepalive; // Флаг: был ли отправлен пакет с последнего keepalive тика
|
||||
};
|
||||
|
||||
// INITIALIZATION (создаёт listen-сокеты и подключения из конфига)
|
||||
|
||||
Reference in new issue
Block a user