Browse Source

1

nodeinfo-routing-update
jeka 2 weeks ago
parent
commit
1ee288fdeb
  1. 56
      src/etcp.c
  2. 11
      src/etcp.h
  3. 32
      src/etcp_api.c
  4. 15
      src/etcp_api.h
  5. 10
      src/etcp_connections.c
  6. 22
      src/route_bgp.c
  7. 1
      src/route_bgp.h

56
src/etcp.c

@ -96,6 +96,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
etcp->io_pool = memory_pool_init(sizeof(struct ETCP_FRAGMENT));
etcp->optimal_inflight=10000;
etcp->initialized=0;
etcp->links_up=0;
etcp->name = u_strdup(name);
// Initialize log_name with local node_id (peer will be updated later when known)
snprintf(etcp->log_name, sizeof(etcp->log_name), "%04X->???? [%s]", (uint16_t)instance->node_id, etcp->name);
@ -144,11 +145,25 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
}
static void etcp_on_up(struct ETCP_CONN* etcp) {
if (etcp->up_cbk) etcp->up_cbk(etcp, etcp->up_arg);
}
static void etcp_on_down(struct ETCP_CONN* etcp) {
if (etcp->down_cbk) etcp->down_cbk(etcp, etcp->down_arg);
}
// Close connection with NULL pointer safety (prevents double free)
void etcp_connection_close(struct ETCP_CONN* etcp) {
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!etcp) return;
if (etcp->links_up!=0) {
etcp->links_up=0;
etcp_on_down(etcp);
}
// Cancel active timers to prevent memory leaks
if (etcp->retrans_timer) {
uasync_cancel_timeout(etcp->instance->ua, etcp->retrans_timer);
@ -273,6 +288,24 @@ void etcp_conn_reset(struct ETCP_CONN* etcp) {
etcp->tx_state=ETCP_TX_STATE_DATA_WAIT;
int up=0;
struct ETCP_LINK* link = etcp->links;
while (link) {
if (link->link_status) up=1;
link = link->next;
}
if (up) {
if (etcp->links_up==0) {
etcp->links_up=1;
etcp_on_up(etcp);
} else {
etcp_on_down(etcp);
etcp_on_up(etcp);
}
}
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "end");
}
@ -296,7 +329,7 @@ void etcp_conn_reinit(struct ETCP_CONN* etcp) {// Если сбой в обме
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "end");
}
// внутренняя функция. Вызывается стеком etcp когда соединение установлено (можно передавать данные)
// внутренняя функция. Вызывается один раз когда первый линк готов.
void etcp_conn_ready(struct ETCP_CONN* conn) {
if (!conn) return;
@ -583,13 +616,34 @@ static void send_ack_req_cb(struct ll_queue* q, void* arg) {// etcp->ack_q data
if (etcp->tx_state==ETCP_TX_STATE_DATA_WAIT) queue_resume_callback(etcp->ack_q);
}
void etcp_on_link_down(struct ETCP_CONN* etcp) {
// scan all links ->
int up=0;
struct ETCP_LINK* link = etcp->links;
while (link) {
if (link->link_status) up=1;
link = link->next;
}
etcp->links_up=up;
if (up==0 && etcp->links_up!=0) {
etcp->links_up=0;
etcp_on_down(etcp);
}
}
static void etcp_link_ready_callback(struct ETCP_CONN* etcp) {
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "");
if (!etcp) return;
if (etcp->tx_state!=ETCP_TX_STATE_LINK_WAIT) return;
etcp->tx_state = ETCP_TX_STATE_DATA_WAIT;
queue_resume_callback(etcp->input_send_q);
queue_resume_callback(etcp->ack_q);
if (etcp->links_up==0) {
etcp->links_up=1;
etcp_on_up(etcp);
}
}
static void ack_response_timer_cb(void* arg) {// проверяем неотправленные ack response и отправляем если надо.

11
src/etcp.h

@ -149,10 +149,15 @@ struct ETCP_CONN {
uint8_t got_initial_pkt; //
uint8_t initialized; // 0 - только созданный ETCP, 1 - хотя бы один линк проинициалзирован (обмен ключами произведен)
uint8_t tx_state; // 0 - n/a, 1 - data_wait (queues empty), 2 - link_wait (link busy)
uint8_t links_up; // 0 - канал не готов для передачи, 1 - канал готов для передачи (хотя бы один линк не down)
// Callback for ready notification
etcp_on_conn_ready ready_cbk; // callback при готовности соединения
void* ready_arg; // аргумент для ready_cbk
etcp_on_conn_ready ready_cbk; // callback при готовности соединения
void* ready_arg; // аргумент для ready_cbk
etcp_on_conn_ready up_cbk; // callback при готовности соединения
void* up_arg; // аргумент для ready_cbk
etcp_on_conn_ready down_cbk; // callback при готовности соединения
void* down_arg; // аргумент для ready_cbk
uint32_t cnt_ack_hit_inf; // счетчик удлений из inflight
uint32_t cnt_ack_hit_sndq; // счетчик удалений inflight пакетов из sndq
@ -199,6 +204,8 @@ void etcp_update_log_name(struct ETCP_CONN* etcp);
// Вызывается стеком etcp когда соединение установлено (можно передавать данные)
void etcp_conn_ready(struct ETCP_CONN* conn);
void etcp_on_link_down(struct ETCP_CONN* etcp);
#ifdef __cplusplus
}
#endif

32
src/etcp_api.c

@ -12,27 +12,35 @@
#include "route_lib.h"
#include "route_bgp.h"
typedef void (*etcp_on_conn_ready)(struct ETCP_CONN* conn, void* arg);
#define DEBUG_CATEGORY_ETCP_API 1
#define ETCP_MAX_BINDINGS 256 /**< Максимальное количество bindings (по одному на каждый ID 0-255) */
// после создания подключения надо выждать conn_ready. только после этого можно передавать сообщения. Иначе сообщения могут потеряться.
// conn_ready может вызваться несколько раз (после каждого переподключения - например когда удаленный узел перегрузился или возникла неустранимая ошибка).
void etcp_conn_set_ready_cbk(struct ETCP_CONN* conn, etcp_on_conn_ready callback_fn, void* arg) {
if (!conn) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP_API, "etcp_conn_set_ready_cbk: NULL conn");
return;
}
conn->ready_cbk = callback_fn;
conn->ready_arg = arg;
DEBUG_TRACE(DEBUG_CATEGORY_ETCP_API, "etcp_conn_set_ready_cbk: conn=%p cbk=%p arg=%p",
(void*)conn, (void*)callback_fn, arg);
void etcp_conn_set_ready_cbk(struct ETCP_CONN* etcp, etcp_cbk_fn callback_fn, void* arg) {
if (!etcp) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP_API, "NULL conn"); return; }
etcp->ready_cbk = callback_fn;
etcp->ready_arg = arg;
DEBUG_TRACE(DEBUG_CATEGORY_ETCP_API, "conn=%s cbk=%p arg=%p", etcp->log_name, (void*)callback_fn, arg);
}
void etcp_conn_set_up_cbk(struct ETCP_CONN* etcp, etcp_cbk_fn callback_fn, void* arg) {
if (!etcp) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP_API, "NULL conn"); return; }
etcp->up_cbk = callback_fn;
etcp->up_arg = arg;
DEBUG_TRACE(DEBUG_CATEGORY_ETCP_API, "conn=%s cbk=%p arg=%p", etcp->log_name, (void*)callback_fn, arg);
}
void etcp_conn_set_down_cbk(struct ETCP_CONN* etcp, etcp_cbk_fn callback_fn, void* arg) {
if (!etcp) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP_API, "NULL conn"); return; }
etcp->down_cbk = callback_fn;
etcp->down_arg = arg;
DEBUG_TRACE(DEBUG_CATEGORY_ETCP_API, "conn=%s cbk=%p arg=%p", etcp->log_name, (void*)callback_fn, arg);
}
// Установить callback при создании нового ETCP соединения
void etcp_set_new_conn_cbk(struct UTUN_INSTANCE* instance, etcp_new_conn_fn callback_fn, void* arg) {
void etcp_set_new_conn_cbk(struct UTUN_INSTANCE* instance, etcp_cbk_fn callback_fn, void* arg) {
if (!instance) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP_API, "etcp_set_new_conn_cbk: NULL instance");
return;

15
src/etcp_api.h

@ -41,14 +41,7 @@ typedef void (*etcp_recv_fn)(struct ETCP_CONN* conn, struct ll_entry* entry);
// Forward declaration
struct ETCP_CONN;
struct UTUN_INSTANCE;
typedef void (*etcp_new_conn_fn)(struct ETCP_CONN* conn, void* arg);
/**
* @brief Тип коллбэка для уведомления о готовности соединения к передаче данных
* @param conn ETCP соединение которое стало готово
* @param arg Пользовательский аргумент
*/
typedef void (*etcp_on_conn_ready)(struct ETCP_CONN* conn, void* arg);
typedef void (*etcp_cbk_fn)(struct ETCP_CONN* conn, void* arg);
/**
* @brief Установить callback при создании нового ETCP соединения
@ -57,7 +50,7 @@ typedef void (*etcp_on_conn_ready)(struct ETCP_CONN* conn, void* arg);
* @param callback_fn Коллбэк который будет вызван при создании нового соединения
* @param arg Аргумент для коллбэка
*/
void etcp_set_new_conn_cbk(struct UTUN_INSTANCE* instance, etcp_new_conn_fn callback_fn, void* arg);
void etcp_set_new_conn_cbk(struct UTUN_INSTANCE* instance, etcp_cbk_fn callback_fn, void* arg);
/**
* @brief Структура bindings для ETCP API (per-instance)
@ -111,7 +104,9 @@ int etcp_unbind(struct UTUN_INSTANCE* inst, uint8_t id);
* @param callback_fn Коллбэк который будет вызван при готовности
* @param arg Аргумент для коллбэка
*/
void etcp_conn_set_ready_cbk(struct ETCP_CONN* conn, etcp_on_conn_ready callback_fn, void* arg);
void etcp_conn_set_ready_cbk(struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg);
void etcp_conn_set_up_cbk (struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg);
void etcp_conn_set_down_cbk (struct ETCP_CONN* conn, etcp_cbk_fn callback_fn, void* arg);
/**
* @brief Внутренняя функция etcp: Коллбэк для очередей output ll_queue normalizer

10
src/etcp_connections.c

@ -142,6 +142,7 @@ void etcp_link_enter_reinit(struct ETCP_LINK* link) {
}
etcp_link_restart_init_timer(link);
etcp_on_link_down(link->etcp);
}
@ -522,6 +523,7 @@ struct ETCP_LINK* etcp_link_new(struct ETCP_CONN* etcp, struct ETCP_SOCKET* conn
DEBUG_ERROR(DEBUG_CATEGORY_CONNECTION, "etcp_link_new: calloc failed");
return NULL;
}
DEBUG_INFO(DEBUG_CATEGORY_CONNECTION, "NEW link: etcp=[%s] link=%p etcp=%p", etcp->log_name, link, etcp);
link->conn = conn;
link->etcp = etcp;
@ -849,6 +851,7 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
send_reset = 0; // Link is up, respond without reset
} else {
send_reset = 1; // INIT_REQUEST (0x02) or uninitialized link - send reset
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "do reinit");
etcp_conn_reinit(conn);
}
@ -866,6 +869,7 @@ static void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
// For new links: INIT_REQUEST (0x02) causes reset, CHANNEL_INIT (0x04) does not
if (ack_hdr->code == ETCP_INIT_REQUEST || new_conn) {
send_reset = 1; // INIT_REQUEST (0x02) or uninitialized link - send reset
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "do reinit 2");
etcp_conn_reinit(conn);
}
link->keepalive_interval=(ack_hdr->keepalive[0]<<8) | ack_hdr->keepalive[1];
@ -977,7 +981,6 @@ process_decrypted:
// Parse response
// ETCP_INIT_RESPONSE (0x03) - reset entire ETCP_CONN
// ETCP_INIT_RESPONSE_NOINIT (0x05) - no reset
if (code == ETCP_INIT_RESPONSE) etcp_conn_reinit(link->etcp);
uint64_t server_node_id = 0;
for (int i = 0; i < 8; i++) {
server_node_id = (server_node_id << 8) | pkt->data[offset++];
@ -1047,6 +1050,11 @@ process_decrypted:
// link->link_status = 1; // Link is up after successful initialization
link->link_state = 3; // connected
if (code == ETCP_INIT_RESPONSE) {
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "do reinit 3 %p", link->etcp);
etcp_conn_reinit(link->etcp);
}
if (link->etcp->initialized == 0) {
etcp_conn_ready(link->etcp);
}

22
src/route_bgp.c

@ -293,20 +293,32 @@ static void route_bgp_receive_cbk(struct ETCP_CONN* from_conn, struct ll_entry*
// ============================================================================
// Callback для готовности ETCP соединения - отправляет маршруты
static void route_bgp_on_conn_ready(struct ETCP_CONN* conn, void* arg) {
static void route_bgp_on_conn_up(struct ETCP_CONN* conn, void* arg) {
(void)arg;
//printf ("on Up: %s\n", conn->log_name);
if (conn && conn->instance && conn->instance->bgp) {
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "Connection %s ready ", conn->log_name);
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "Connection %s on up ", conn->log_name);
route_bgp_new_conn(conn);
}
}
static void route_bgp_on_conn_down(struct ETCP_CONN* conn, void* arg) {
(void)arg;
//printf ("on Dn\n");
if (conn && conn->instance && conn->instance->bgp) {
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "Connection %s on down ", conn->log_name);
route_bgp_remove_conn(conn);
}
}
// Callback для новых ETCP соединений - устанавливает ready callback
static void route_bgp_etcp_conn_cbk(struct ETCP_CONN* conn, void* arg) {
(void)arg;
if (conn && conn->instance && conn->instance->bgp) {
DEBUG_TRACE(DEBUG_CATEGORY_BGP, "Set ETCP ready callback for connection %s", conn->log_name);
etcp_conn_set_ready_cbk(conn, route_bgp_on_conn_ready, conn->instance->bgp);
//printf ("on evt set\n");
etcp_conn_set_up_cbk(conn, route_bgp_on_conn_up, conn->instance->bgp);
etcp_conn_set_down_cbk(conn, route_bgp_on_conn_down, conn->instance->bgp);
}
}
@ -464,7 +476,3 @@ void route_bgp_remove_conn(struct ETCP_CONN* conn) {
DEBUG_INFO(DEBUG_CATEGORY_BGP, "Connection removed, routes updated via route_remove_conn");
}
void route_bgp_close_conn(struct ETCP_CONN* conn) {
route_bgp_remove_conn(conn);
}

1
src/route_bgp.h

@ -54,6 +54,5 @@ void route_bgp_destroy(struct UTUN_INSTANCE* instance);
void route_bgp_new_conn(struct ETCP_CONN* conn);
void route_bgp_remove_conn(struct ETCP_CONN* conn);
void route_bgp_close_conn(struct ETCP_CONN* conn); // deprecated
#endif // ROUTE_BGP_H

Loading…
Cancel
Save