etcp: instance-level conn status callbacks (NEW/UP/DOWN/DELETE), fix member online in chatgui
- Add etcp_add_conn_status_cbk/remove/set — unified callback for all connections - 4 statuses: NEW, UP, DOWN, DELETE — one subscription covers all connections - Fire points in etcp.c: create→NEW, on_up→UP, on_down→DOWN, close→DELETE - chat_sync.c: replace cs_on_new_conn+per-conn subs with cs_on_conn_status - db_sync.c: same migration to instance-level callback - cs_is_peer_online: use conn->links_up instead of link->link_status (was 0 during INIT handshake)
This commit is contained in:
1 parent
ef27633a88
commit
aa1ed006d5
6 files changed
+84
-48
No files matched your search
+13
-25
@@ -21,7 +21,7 @@ struct DB_SYNC;
|
||||
struct DB_SYNC_INSTANCE;
|
||||
|
||||
static void db_sync_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry);
|
||||
static void db_sync_on_new_conn(struct ETCP_CONN* conn, void* arg);
|
||||
static void db_sync_on_conn_status(struct ETCP_CONN* conn, int status, void* arg);
|
||||
static void db_sync_on_conn_up(struct ETCP_CONN* conn, void* arg);
|
||||
static void db_sync_on_conn_down(struct ETCP_CONN* conn, void* arg);
|
||||
static void db_sync_peer_check_cb(void* arg);
|
||||
@@ -1094,6 +1094,15 @@ static void db_sync_recv_cb(struct ETCP_CONN* conn, struct ll_entry* entry)
|
||||
// Connection callbacks
|
||||
// ============================================================
|
||||
|
||||
static void db_sync_on_conn_status(struct ETCP_CONN* conn, int status, void* arg) {
|
||||
switch (status) {
|
||||
case ETCP_CONN_STATUS_UP: db_sync_on_conn_up(conn, arg); break;
|
||||
case ETCP_CONN_STATUS_DOWN: db_sync_on_conn_down(conn, arg); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* replaced by db_sync_on_conn_status */
|
||||
static void db_sync_on_new_conn(struct ETCP_CONN* conn, void* arg)
|
||||
{
|
||||
(void)arg;
|
||||
@@ -1102,6 +1111,7 @@ static void db_sync_on_new_conn(struct ETCP_CONN* conn, void* arg)
|
||||
etcp_conn_add_up_cbk(conn, db_sync_on_conn_up, NULL);
|
||||
etcp_conn_add_down_cbk(conn, db_sync_on_conn_down, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void db_sync_on_conn_up(struct ETCP_CONN* conn, void* arg)
|
||||
{
|
||||
@@ -1355,19 +1365,7 @@ int db_sync_init(struct UTUN_INSTANCE* inst)
|
||||
}
|
||||
|
||||
etcp_bind(inst, ETCP_RT_ID_DB_SYNC, db_sync_recv_cb);
|
||||
etcp_set_new_conn_cbk(inst, db_sync_on_new_conn, NULL);
|
||||
|
||||
{
|
||||
struct ll_entry* entry = inst->connections->head;
|
||||
while (entry) {
|
||||
struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data;
|
||||
if (ce && ce->conn) {
|
||||
etcp_conn_add_up_cbk(ce->conn, db_sync_on_conn_up, NULL);
|
||||
etcp_conn_add_down_cbk(ce->conn, db_sync_on_conn_down, NULL);
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
etcp_add_conn_status_cbk(inst, db_sync_on_conn_status, NULL);
|
||||
|
||||
if (db->enabled)
|
||||
db->peer_check_timer = uasync_set_timeout(inst->ua, DB_SYNC_PEER_CHECK_INTERVAL * 10000u,
|
||||
@@ -1394,17 +1392,7 @@ void db_sync_destroy(struct UTUN_INSTANCE* inst)
|
||||
if (si->peers) u_free(si->peers);
|
||||
}
|
||||
|
||||
{
|
||||
struct ll_entry* entry = inst->connections->head;
|
||||
while (entry) {
|
||||
struct conn_queue_entry* ce = (struct conn_queue_entry*)entry->data;
|
||||
if (ce && ce->conn) {
|
||||
etcp_conn_remove_up_cbk(ce->conn, db_sync_on_conn_up, NULL);
|
||||
etcp_conn_remove_down_cbk(ce->conn, db_sync_on_conn_down, NULL);
|
||||
}
|
||||
entry = entry->next;
|
||||
}
|
||||
}
|
||||
etcp_remove_conn_status_cbk(inst, db_sync_on_conn_status, NULL);
|
||||
|
||||
db_sqlite_close(db);
|
||||
if (db->instances) u_free(db->instances);
|
||||
|
||||
+12
@@ -46,6 +46,7 @@ static void wait_ack_cb(struct ll_queue* q, void* arg);
|
||||
static void send_ack_req_cb(struct ll_queue* q, void* arg);
|
||||
static void etcp_conn_process_send_queue(struct ETCP_CONN* etcp);
|
||||
static void etcp_connection_free_deferred(void* arg);
|
||||
static void etcp_fire_conn_status(struct ETCP_CONN* etcp, int status);
|
||||
struct ETCP_DGRAM* etcp_request_pkt(struct ETCP_CONN* etcp);
|
||||
|
||||
static void clear_queue(struct ll_queue* q) {
|
||||
@@ -279,16 +280,24 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n
|
||||
struct etcp_cbk_entry* cbe = instance->new_conn_cbks;
|
||||
while (cbe) { struct etcp_cbk_entry* n = cbe->next; cbe->fn(etcp, cbe->arg); cbe = n; }
|
||||
}
|
||||
etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_NEW);
|
||||
|
||||
return etcp;
|
||||
}
|
||||
|
||||
|
||||
static void etcp_fire_conn_status(struct ETCP_CONN* etcp, int status) {
|
||||
if (!etcp || !etcp->instance) return;
|
||||
struct etcp_status_cbk_entry* cbe = etcp->instance->conn_status_cbks;
|
||||
while (cbe) { struct etcp_status_cbk_entry* n = cbe->next; cbe->fn(etcp, status, cbe->arg); cbe = n; }
|
||||
}
|
||||
|
||||
static void etcp_on_up(struct ETCP_CONN* etcp) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "[%s] Connection UP (links_up=%d initialized=%d)", etcp->log_name, etcp->links_up, etcp->initialized);
|
||||
etcp->callbacks_running = 1;
|
||||
struct etcp_cbk_entry* cbe = etcp->up_cbks;
|
||||
while (cbe) { struct etcp_cbk_entry* n = cbe->next; cbe->fn(etcp, cbe->arg); cbe = n; }
|
||||
etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_UP);
|
||||
etcp->callbacks_running = 0;
|
||||
}
|
||||
|
||||
@@ -297,6 +306,7 @@ static void etcp_on_down(struct ETCP_CONN* etcp) {
|
||||
etcp->callbacks_running = 1;
|
||||
struct etcp_cbk_entry* cbe = etcp->down_cbks;
|
||||
while (cbe) { struct etcp_cbk_entry* n = cbe->next; cbe->fn(etcp, cbe->arg); cbe = n; }
|
||||
etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_DOWN);
|
||||
etcp->callbacks_running = 0;
|
||||
}
|
||||
|
||||
@@ -382,6 +392,8 @@ void etcp_connection_close(struct ETCP_CONN* etcp) {
|
||||
|
||||
etcp->state = 2; // deleted
|
||||
|
||||
etcp_fire_conn_status(etcp, ETCP_CONN_STATUS_DELETE);
|
||||
|
||||
// === PHASE 2: deferred resource cleanup (only if no outstanding refs) ===
|
||||
if (etcp->ref_count == 0)
|
||||
uasync_call_soon(etcp->instance->ua, etcp, etcp_connection_free_deferred);
|
||||
|
||||
@@ -69,6 +69,34 @@ void etcp_conn_remove_down_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg
|
||||
void etcp_add_new_conn_cbk(struct UTUN_INSTANCE* inst, etcp_cbk_fn fn, void* arg) { if (inst) etcp_cbk_add_to_chain(&inst->new_conn_cbks, fn, arg); }
|
||||
void etcp_remove_new_conn_cbk(struct UTUN_INSTANCE* inst, etcp_cbk_fn fn, void* arg) { if (inst) etcp_cbk_remove_from_chain(&inst->new_conn_cbks, fn, arg); }
|
||||
|
||||
static void etcp_status_cbk_add_chain(struct etcp_status_cbk_entry** head, etcp_conn_status_fn fn, void* arg) {
|
||||
if (!head || !fn) return;
|
||||
struct etcp_status_cbk_entry* e = u_malloc(sizeof(struct etcp_status_cbk_entry));
|
||||
if (!e) return;
|
||||
e->fn = fn; e->arg = arg; e->next = *head;
|
||||
*head = e;
|
||||
}
|
||||
static void etcp_status_cbk_remove_chain(struct etcp_status_cbk_entry** head, etcp_conn_status_fn fn, void* arg) {
|
||||
if (!head || !fn) return;
|
||||
struct etcp_status_cbk_entry** p = head;
|
||||
while (*p) {
|
||||
if ((*p)->fn == fn && (*p)->arg == arg) {
|
||||
struct etcp_status_cbk_entry* rm = *p;
|
||||
*p = rm->next; u_free(rm); return;
|
||||
}
|
||||
p = &(*p)->next;
|
||||
}
|
||||
}
|
||||
void etcp_add_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg) { if (inst) etcp_status_cbk_add_chain(&inst->conn_status_cbks, fn, arg); }
|
||||
void etcp_remove_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg) { if (inst) etcp_status_cbk_remove_chain(&inst->conn_status_cbks, fn, arg); }
|
||||
void etcp_set_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg) {
|
||||
if (!inst) return;
|
||||
struct etcp_status_cbk_entry* entry = inst->conn_status_cbks;
|
||||
while (entry) { struct etcp_status_cbk_entry* next = entry->next; u_free(entry); entry = next; }
|
||||
inst->conn_status_cbks = NULL;
|
||||
if (fn) etcp_status_cbk_add_chain(&inst->conn_status_cbks, fn, arg);
|
||||
}
|
||||
|
||||
void etcp_set_routing_exchange_state(struct ETCP_CONN* conn, uint8_t new_state) {
|
||||
if (!conn) return;
|
||||
conn->routing_exchange_active = new_state;
|
||||
|
||||
@@ -44,10 +44,23 @@ extern "C" {
|
||||
#define ETCP_RT_ID_CONN_MGR 0x11 // Connection Manager — management connections
|
||||
#define ETCP_RT_ID_NTP_TIME 0x12 // NTP time sync между узлами
|
||||
|
||||
// Connection status events (instance-level callback)
|
||||
#define ETCP_CONN_STATUS_NEW 0 // соединение создано
|
||||
#define ETCP_CONN_STATUS_UP 1 // соединение поднялось
|
||||
#define ETCP_CONN_STATUS_DOWN 2 // соединение упало
|
||||
#define ETCP_CONN_STATUS_DELETE 3 // соединение удалено
|
||||
|
||||
// Forward declarations
|
||||
struct ETCP_CONN;
|
||||
struct UTUN_INSTANCE;
|
||||
|
||||
typedef void (*etcp_conn_status_fn)(struct ETCP_CONN* conn, int status, void* arg);
|
||||
struct etcp_status_cbk_entry {
|
||||
etcp_conn_status_fn fn;
|
||||
void* arg;
|
||||
struct etcp_status_cbk_entry* next;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Тип коллбэка для приёма метрик от пира
|
||||
* @param user_ptr пользовательский указатель
|
||||
@@ -162,6 +175,10 @@ void etcp_conn_remove_down_cbk(struct ETCP_CONN* conn, etcp_cbk_fn fn, void* arg
|
||||
void etcp_add_new_conn_cbk(struct UTUN_INSTANCE* inst, etcp_cbk_fn fn, void* arg);
|
||||
void etcp_remove_new_conn_cbk(struct UTUN_INSTANCE* inst, etcp_cbk_fn fn, void* arg);
|
||||
|
||||
void etcp_add_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg);
|
||||
void etcp_remove_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg);
|
||||
void etcp_set_conn_status_cbk(struct UTUN_INSTANCE* inst, etcp_conn_status_fn fn, void* arg);
|
||||
|
||||
void etcp_set_routing_exchange_state(struct ETCP_CONN* conn, uint8_t new_state);
|
||||
|
||||
/**
|
||||
|
||||
@@ -102,6 +102,7 @@ struct UTUN_INSTANCE {
|
||||
|
||||
// Callback chain for new ETCP connections
|
||||
struct etcp_cbk_entry* new_conn_cbks;
|
||||
struct etcp_status_cbk_entry* conn_status_cbks; // instance-level: NEW/UP/DOWN/DELETE
|
||||
void* test_user_ptr; // Generic user pointer (used by tests)
|
||||
|
||||
struct memory_pool* data_pool;// для входных-выходных данных пакета
|
||||
|
||||
Reference in new issue
Block a user