1
This commit is contained in:
1 parent
0e36d5993c
commit
1ee288fdeb
7 files changed
+113
-34
No files matched your search
+55
-1
@@ -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 и отправляем если надо.
|
||||
|
||||
+9
-2
@@ -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
|
||||
|
||||
+20
-12
@@ -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;
|
||||
|
||||
+5
-10
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
+15
-7
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
Reference in new issue
Block a user