Browse Source

route_connectivity: фикс UAF при удалении узла с влётными пробами; отмена TCP-пингов при teardown

- topo_nodeq_remove_node: единый хелпер удаления nq (cancel проб + free paths/subnets + remove + free), заменяет все free-сайты
- route_connectivity_cancel_all: итерация по всем группам + зануление ctx->nq + отмена standby-defer
- etcp_send_tcp_ping: out_cli — хендл stcp_client для досрочной отмены; conn_probe_ctx.tcp_cli
- conn_mgr: cand_tcp_pings[] — отмена влётных candidate TCP-пингов в conn_mgr_destroy
proxy
evgeny 6 days ago
parent
commit
08e8b2f1cc
  1. 8
      src/routing_layer/conn_mgr_core.c
  2. 17
      src/routing_layer/conn_mgr_monitor.c
  3. 2
      src/routing_layer/conn_mgr_priv.h
  4. 52
      src/routing_layer/route_connectivity.c
  5. 3
      src/routing_layer/route_connectivity.h
  6. 33
      src/routing_layer/topo_group.c
  7. 2
      src/routing_layer/topo_group_invite.c
  8. 12
      src/routing_layer/topo_node.c
  9. 3
      src/routing_layer/topo_node.h
  10. 5
      src/transport_layer/etcp_connections.c
  11. 5
      src/transport_layer/etcp_connections.h
  12. 4
      tests/test_stcp_ping.c

8
src/routing_layer/conn_mgr_core.c

@ -16,6 +16,7 @@
#include "utun_instance.h"
#include "etcp.h"
#include "etcp_connections.h"
#include "stcp_client.h"
#include "etcp_router.h"
#include "config_parser.h"
#include "topo_node.h"
@ -237,9 +238,7 @@ void cm_cleanup_db_node(struct CONN_MGR_ENTRY* entry) {
return;
}
DEBUG_INFO(DEBUG_CATEGORY_GENERAL, "conn_mgr: removing db_node 0x%016llx from group (no paths)", (unsigned long long)entry->node_id);
queue_remove_data(group->nodes, &nq->ll);
topo_nodeq_free_group_fields(entry->mgr->instance->topo_groups, nq);
queue_entry_free(&nq->ll);
topo_nodeq_remove_node(group, nq);
}
/* ═══════ NCD коллбэки ═══════ */
@ -343,6 +342,9 @@ void conn_mgr_destroy(struct CONN_MGR* mgr) {
if (mgr->bg_ping_wait) { standby_wait_cancel(mgr->bg_ping_wait); mgr->bg_ping_wait = NULL; }
if (mgr->candidate_ping_wait) { standby_wait_cancel(mgr->candidate_ping_wait); mgr->candidate_ping_wait = NULL; }
#endif
/* Досрочно закрыть влётные candidate TCP-пинги — иначе их stcp_client утечёт до uasync_destroy. */
for (int i = 0; i < CONN_MGR_MAX_CANDIDATES; i++)
if (mgr->cand_tcp_pings[i]) { stcp_client_destroy(mgr->cand_tcp_pings[i]); mgr->cand_tcp_pings[i] = NULL; }
{ size_t ec = queue_entry_count(mgr->entries);
DEBUG_INFO(DEBUG_CATEGORY_SYS, "[CM_DESTROY] 3 entries count=%zu", ec);
struct ll_entry* e = mgr->entries->head;

17
src/routing_layer/conn_mgr_monitor.c

@ -59,6 +59,14 @@ void conn_mgr_update_best_candidates(struct CONN_MGR* mgr, uint64_t node_id, uin
static void cm_bg_ping_noop_cb(int s, uint16_t r, void* a, uint64_t n, const uint8_t* d, size_t l) { (void)s;(void)r;(void)a;(void)n;(void)d;(void)l; }
/* Candidate TCP-пинг: по завершении (успех/ошибка/таймаут) зануляет свой слот в
* mgr->cand_tcp_pings, чтобы conn_mgr_destroy не трогал уже освобождённый handle. */
static void cm_cand_tcp_ping_cb(int s, uint16_t r, void* arg, uint64_t n, const uint8_t* d, size_t l) {
(void)s;(void)r;(void)n;(void)d;(void)l;
struct stcp_client** slot = (struct stcp_client**)arg;
if (slot) *slot = NULL;
}
static void cm_bg_ping_to_node(struct CONN_MGR* mgr, struct TOPO_NODE* ni) {
for (const struct TOPO_ADDR4* a = ni->v4_addrs; a; a = a->next) {
if (a->type != TOPO_ADDR_NAT && a->type != TOPO_ADDR_INTERFACE) continue;
@ -179,9 +187,12 @@ void cm_candidate_ping_timer_cb(void* arg) {
struct TOPO_NODE* ni = topo_node_registry_find(mgr->instance->topo_groups, nq->node_id);
/* пир в SLEEP-фазе — прямое соединение живо, пинг будит его: пропускаем */
if (ni && dc && dc->links && !dc->peer_sleep_phase) {
if (dc->links->is_tcp)
etcp_send_tcp_ping(mgr->instance, ni->public_key, &dc->links->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_bg_ping_noop_cb, NULL);
else
if (dc->links->is_tcp) {
struct stcp_client** slot = NULL;
for (uint8_t i = 0; i < CONN_MGR_MAX_CANDIDATES; i++)
if (!mgr->cand_tcp_pings[i]) { slot = &mgr->cand_tcp_pings[i]; break; }
if (slot) etcp_send_tcp_ping(mgr->instance, ni->public_key, &dc->links->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_cand_tcp_ping_cb, slot, slot);
} else
etcp_send_ping(mgr->instance, ni->public_key, &dc->links->remote_addr, CONN_PROBE_TIMEOUT_MS, cm_bg_ping_noop_cb, NULL, NULL, 0);
}
} else route_connectivity_probe_node(mgr->instance, mgr->group, nq);

2
src/routing_layer/conn_mgr_priv.h

@ -17,6 +17,7 @@ struct ETCP_ROUTER_CONN;
struct TOPO_GROUP_NODE;
struct TOPO_GROUP;
struct stcp_link;
struct stcp_client;
/* ═══════ константы ═══════ */
@ -118,6 +119,7 @@ struct CONN_MGR {
void *bg_ping_wait, *candidate_ping_wait; /* standby_wait handle (Android) */
size_t bg_ping_cursor; uint64_t bg_ping_cycle_start_tb;
struct CONN_MGR_CANDIDATE best_candidates[CONN_MGR_MAX_CANDIDATES]; uint8_t best_candidate_count;
struct stcp_client* cand_tcp_pings[CONN_MGR_MAX_CANDIDATES]; /* влётные candidate TCP-пинги (для отмены при destroy) */
uint32_t next_request_id, direct_timeout_ms; uint8_t initialized;
struct cm_reverse_pending* reverse_pending;
struct cm_exchange_pending* exchange_pending;

52
src/routing_layer/route_connectivity.c

@ -13,6 +13,7 @@
#include "utun_instance.h"
#include "etcp.h"
#include "etcp_connections.h"
#include "stcp_client.h"
#include "topo_node.h"
#include "topo_group.h"
#include "route_connectivity.h"
@ -51,6 +52,7 @@ struct conn_probe_ctx {
uint16_t min_rtt; // min RTT в текущей серии
uint16_t timeout_ms;
void* ping_timer;
struct stcp_client* tcp_cli; // хендл влётного TCP-пинга (для отмены), NULL для UDP
};
// ---- forward ----
@ -145,7 +147,7 @@ static int conn_match_candidate_sockets(struct UTUN_INSTANCE* instance,
static int conn_probe_send(struct conn_probe_ctx* ctx) {
if (ctx->is_tcp) {
return etcp_send_tcp_ping(ctx->instance, ctx->peer_pubkey, &ctx->target_addr,
ctx->timeout_ms, conn_probe_single_cb, ctx);
ctx->timeout_ms, conn_probe_single_cb, ctx, &ctx->tcp_cli);
}
struct ETCP_SOCKET* sock = ctx->candidate_sockets[ctx->candidate_index];
return etcp_send_ping_to_socket(ctx->instance, sock, ctx->peer_pubkey,
@ -395,8 +397,11 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_G
}
}
void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance, struct TOPO_GROUP_NODE* nq) {
if (!instance || !nq) return;
/* Отсоединяет все влётные пробы узла: зануляет ctx->nq (чтобы conn_probe_finish не
* трогал освобождаемый nq) и досрочно закрывает влётные TCP-пинги. UDP-пробы не имеют
* хендла — они отсоединяются и освобождаются своим штатным ping_timeout/PONG. */
static void conn_probe_cancel_nq(struct TOPO_GROUP_NODE* nq) {
if (!nq) return;
#ifdef UTUN_HAVE_STANDBY
{ struct route_probe_defer* d = (struct route_probe_defer*)nq->connectivity.probe_deferred_wait;
if (d) {
@ -409,31 +414,36 @@ void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance, struct TOPO_
nq->connectivity.probe_status = PROBE_STATUS_NONE;
nq->connectivity.pending_count = 0;
struct conn_probe_ctx* ctx = (struct conn_probe_ctx*)nq->connectivity.probe_list;
while (ctx) { ctx->nq = NULL; ctx = ctx->next; }
nq->connectivity.probe_list = NULL;
while (ctx) {
struct conn_probe_ctx* next = ctx->next;
ctx->nq = NULL;
struct stcp_client* cli = ctx->tcp_cli;
if (cli) stcp_client_destroy(cli); // синхронно: ping_close_cb → conn_probe_finish → u_free(ctx)
ctx = next;
}
}
void route_connectivity_cancel_node(struct TOPO_GROUP_NODE* nq) {
if (!nq) return;
conn_probe_cancel_nq(nq);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "connectivity probe cancelled for node %016llx", (unsigned long long)nq->node_id);
}
void route_connectivity_cancel_all(struct UTUN_INSTANCE* instance) {
struct TOPO_GROUP* group = topo_groups_get_default(instance->topo_groups);
if (!instance || !group || !group->nodes) return;
if (!instance || !instance->topo_groups || !instance->topo_groups->group_list) return;
int count = 0;
struct ll_entry* e = group->nodes->head;
while (e) {
struct TOPO_GROUP_NODE* nq = (struct TOPO_GROUP_NODE*)e;
#ifdef UTUN_HAVE_STANDBY
{ struct route_probe_defer* d = (struct route_probe_defer*)nq->connectivity.probe_deferred_wait;
if (d) {
if (d->wait_handle) standby_wait_cancel(d->wait_handle);
u_free(d);
nq->connectivity.probe_deferred_wait = NULL;
}
struct ll_entry* ge = instance->topo_groups->group_list->head;
while (ge) {
struct TOPO_GROUP* group = (struct TOPO_GROUP*)ge;
struct ll_entry* e = group->nodes ? group->nodes->head : NULL;
while (e) {
struct TOPO_GROUP_NODE* nq = (struct TOPO_GROUP_NODE*)e;
conn_probe_cancel_nq(nq);
e = e->next;
count++;
}
#endif
nq->connectivity.probe_status = PROBE_STATUS_NONE;
nq->connectivity.pending_count = 0;
e = e->next;
count++;
ge = ge->next;
}
DEBUG_INFO(DEBUG_CATEGORY_BGP, "probe cancel ALL: %d nodes", count);
}

3
src/routing_layer/route_connectivity.h

@ -17,8 +17,7 @@ void route_connectivity_probe_node(struct UTUN_INSTANCE* instance, struct TOPO_G
struct TOPO_GROUP_NODE* nq);
// Отменяет все pending пробы для узла (при удалении / withdraw)
void route_connectivity_cancel_node(struct UTUN_INSTANCE* instance,
struct TOPO_GROUP_NODE* nq);
void route_connectivity_cancel_node(struct TOPO_GROUP_NODE* nq);
// Отменяет все pending пробы для всех узлов (при destroy)
void route_connectivity_cancel_all(struct UTUN_INSTANCE* instance);

33
src/routing_layer/topo_group.c

@ -392,13 +392,12 @@ static void topo_group_destroy(struct TOPO_GROUP* group) {
DEBUG_INFO(DEBUG_CATEGORY_SYS, "[GRP_DESTROY] 4 conn_mgr done");
if (group->nodes) {
struct ll_entry* e; int nc = 0;
while ((e = queue_data_get(group->nodes)) != NULL) {
struct TOPO_GROUP_NODE* nq = (struct TOPO_GROUP_NODE*)e;
route_connectivity_cancel_node(group->instance, nq);
if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; }
topo_nodeq_free_group_fields(group->instance->topo_groups, nq);
queue_entry_free(e); nc++;
int nc = 0;
struct ll_entry* e = group->nodes->head;
while (e) {
struct ll_entry* next = e->next;
topo_nodeq_remove_node(group, (struct TOPO_GROUP_NODE*)e);
e = next; nc++;
}
queue_free(group->nodes);
if (nc) DEBUG_INFO(DEBUG_CATEGORY_SYS, "[GRP_DESTROY] 4b nodes cleaned (%d)", nc);
@ -766,11 +765,7 @@ void topo_group_remove_conn(struct TOPO_GROUP* group, struct ETCP_CONN* conn) {
topo_fire_nodeinfo_cbk(conn->instance, group, nq);
if (group->group_type != TOPO_GROUP_TYPE_CHAT && rt) route_delete(rt, nq);
if (conn->instance && conn->instance->control_srv) control_server_notify_node_removed(conn->instance->control_srv, key);
route_connectivity_cancel_node(conn->instance, nq);
if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; }
topo_nodeq_free_group_fields(group->instance->topo_groups, nq);
struct ll_entry* entry = node_entry;
if (entry) { queue_remove_data(group->nodes, entry); queue_entry_free(entry); }
topo_nodeq_remove_node(group, nq);
nodes_removed++;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node removed from group: node=%016llx grp=%016llx type=%u ch=%s (link_down)",
(unsigned long long)key, (unsigned long long)group->group_id, group->group_type, group->channel_id);
@ -954,7 +949,6 @@ int topo_group_process_nodeinfo(struct TOPO_GROUP* group, struct ETCP_CONN* from
struct ll_queue* paths = NULL;
int is_new_node = 0;
if (nodeinfo1) {
topo_nodeq_free_group_fields(group->instance->topo_groups, nodeinfo1);
paths = nodeinfo1->paths; nodeinfo1->paths = NULL;
} else { is_new_node = 1; }
@ -966,7 +960,7 @@ int topo_group_process_nodeinfo(struct TOPO_GROUP* group, struct ETCP_CONN* from
uint16_t incoming_cumulative_rtt = 0;
if (topo_node_deserialize(group, ser_data, ser_len, &new_ni, &new_subnets, &new_hop_list, &new_hop_count, &incoming_cumulative_rtt) != 0) {
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "NODEINFO deserialize failed from %s nid=%016llx", from->log_name, (unsigned long long)node_id);
if (nodeinfo1) { queue_remove_data(group->nodes, &nodeinfo1->ll); queue_free(paths); queue_entry_free(&nodeinfo1->ll); }
if (nodeinfo1) { topo_nodeq_remove_node(group, nodeinfo1); queue_free(paths); }
return -1;
}
{ int v4c = topo_list_count((struct _topo_head*)new_ni->v4_addrs);
@ -980,7 +974,7 @@ int topo_group_process_nodeinfo(struct TOPO_GROUP* group, struct ETCP_CONN* from
(unsigned long long)node_id, from->log_name);
topo_node_destroy(group->instance->topo_groups, new_ni);
u_free(new_subnets); u_free(new_hop_list);
if (nodeinfo1) { queue_remove_data(group->nodes, &nodeinfo1->ll); queue_free(paths); queue_entry_free(&nodeinfo1->ll); }
if (nodeinfo1) { topo_nodeq_remove_node(group, nodeinfo1); queue_free(paths); }
return -1;
}
{
@ -996,7 +990,7 @@ int topo_group_process_nodeinfo(struct TOPO_GROUP* group, struct ETCP_CONN* from
(unsigned long long)node_id, ekchk, sig_len, from->log_name);
topo_node_destroy(group->instance->topo_groups, new_ni);
u_free(new_subnets); u_free(new_hop_list);
if (nodeinfo1) { queue_remove_data(group->nodes, &nodeinfo1->ll); queue_free(paths); queue_entry_free(&nodeinfo1->ll); }
if (nodeinfo1) { topo_nodeq_remove_node(group, nodeinfo1); queue_free(paths); }
return -1;
}
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "NODEINFO x25519_self_sig OK node=%016llx ed_pubkey=%016llx... sig_len=%d from=%s",
@ -1005,6 +999,7 @@ int topo_group_process_nodeinfo(struct TOPO_GROUP* group, struct ETCP_CONN* from
}
if (nodeinfo1) {
topo_nodeq_free_group_fields(group->instance->topo_groups, nodeinfo1);
{ struct TOPO_NODE* stored = topo_node_registry_store(group->instance->topo_groups, new_ni);
if (stored != new_ni) new_ni = stored; }
nodeinfo1->node_id = new_ni ? new_ni->node_id : 0;
@ -1118,11 +1113,7 @@ int topo_group_process_withdraw(struct TOPO_GROUP* group, struct ETCP_CONN* send
topo_fire_nodeinfo_cbk(group->instance, group, nq);
if (group->group_type != TOPO_GROUP_TYPE_CHAT && group->instance && group->instance->rt) route_delete(group->instance->rt, nq);
if (group->instance->control_srv) control_server_notify_node_removed(group->instance->control_srv, node_id);
route_connectivity_cancel_node(group->instance, nq);
if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; }
topo_nodeq_free_group_fields(group->instance->topo_groups, nq);
struct ll_entry* entry = queue_find_data_by_index(group->nodes, &node_id);
if (entry) { queue_remove_data(group->nodes, entry); queue_entry_free(entry); }
topo_nodeq_remove_node(group, nq);
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node removed from group: node=%016llx grp=%016llx type=%u ch=%s (withdraw)",
(unsigned long long)node_id, (unsigned long long)group->group_id, group->group_type, group->channel_id);
topo_group_broadcast_withdraw(group, node_id, wd_source, sender);

2
src/routing_layer/topo_group_invite.c

@ -404,7 +404,7 @@ static void tgi_cancel(struct tgi_pending* p) {
if (p->ncd_handle) { node_conn_direct_force_close(p->ncd_handle); p->ncd_handle = NULL; }
if (p->temp_nq) {
struct TOPO_GROUP* g = topo_groups_find(p->inst->topo_groups, p->group_id);
if (g) { queue_remove_data(g->nodes, &p->temp_nq->ll); topo_nodeq_free_group_fields(p->inst->topo_groups, p->temp_nq); queue_entry_free(&p->temp_nq->ll); }
if (g) topo_nodeq_remove_node(g, p->temp_nq);
p->temp_nq = NULL;
}
tgi_unlink(p);

12
src/routing_layer/topo_node.c

@ -11,6 +11,7 @@
#include "config_parser.h"
#include "topo_node.h"
#include "topo_group.h"
#include "route_connectivity.h"
#include "route_lib.h"
#include "etcp_debug.h"
#include "topo_node_sqlite.h"
@ -186,6 +187,17 @@ void topo_nodeq_free_group_fields(struct TOPO_GROUPS* groups, struct TOPO_GROUP_
nq->handle = NULL;
}
/* Полное удаление узла из группы: отмена влётных проб, освобождение paths/subnets,
* извлечение из group->nodes и освобождение самого nq. Единственный корректный способ удаления. */
void topo_nodeq_remove_node(struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* nq) {
if (!group || !nq) return;
route_connectivity_cancel_node(nq);
if (nq->paths) { queue_free(nq->paths); nq->paths = NULL; }
queue_remove_data(group->nodes, &nq->ll);
topo_nodeq_free_group_fields(group->instance ? group->instance->topo_groups : NULL, nq);
queue_entry_free(&nq->ll);
}
// ===== глобальный реестр TOPO_NODE =====
/* Ищет TOPO_NODE в глобальном реестре по node_id (NULL, если узла нет). */

3
src/routing_layer/topo_node.h

@ -226,6 +226,9 @@ void topo_node_destroy(struct TOPO_GROUPS* groups, struct TOPO_NODE* ni);
// API — per-group
struct TOPO_GROUP_NODE* topo_node_find_by_id(struct TOPO_GROUP* group, uint64_t node_id);
void topo_nodeq_free_group_fields(struct TOPO_GROUPS* groups, struct TOPO_GROUP_NODE* nq);
/* Полное удаление узла из группы: отменяет влётные пробы, освобождает paths/subnets,
* убирает из group->nodes и освобождает сам nq. Единственный корректный способ удаления узла. */
void topo_nodeq_remove_node(struct TOPO_GROUP* group, struct TOPO_GROUP_NODE* nq);
int topo_node_dyn_size(const struct TOPOMSG_NODE* msg);
int topo_node_serialize(struct TOPO_NODE* ni, struct TOPO_GROUP_NODE* nq,

5
src/transport_layer/etcp_connections.c

@ -1597,12 +1597,14 @@ static void tcp_ping_cb_adapter(int success, uint16_t rtt, void* arg) {
// TCP-пинг: STCP-хендшейк с пиром и замер RTT по handshake (через stcp_ping_send).
int etcp_send_tcp_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bin,
const struct sockaddr_storage* addr, int timeout_ms,
etcp_ping_callback_t cb, void* user_arg) {
etcp_ping_callback_t cb, void* user_arg,
struct stcp_client** out_cli) {
if (!instance || !peer_pubkey_bin || !addr || timeout_ms <= 0 || !cb) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "bad args: inst=%p pubkey=%p addr=%p timeout=%d cb=%p",
(void*)instance, (void*)peer_pubkey_bin, (void*)addr, timeout_ms, (void*)(uintptr_t)cb);
return -1;
}
if (out_cli) *out_cli = NULL;
char addr_str[INET6_ADDRSTRLEN];
uint16_t port;
if (addr->ss_family == AF_INET) {
@ -1637,6 +1639,7 @@ int etcp_send_tcp_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubke
instance->my_ed25519_pubkey, instance->client_type,
instance->keepalive_interval, timeout_ms, tcp_ping_cb_adapter, a, socks);
if (!cli) { u_free(a); return -4; }
if (out_cli) *out_cli = cli;
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "tcp ping to %s:%u timeout=%d", addr_str, (unsigned)port, timeout_ms);
return 0;
}

5
src/transport_layer/etcp_connections.h

@ -372,6 +372,7 @@ void tcp_socket_remove(struct ETCP_SOCKET* sock);
int etcp_create_server_socket(struct UTUN_INSTANCE* instance, struct CFG_SERVER* server, struct ETCP_SOCKET** out_sock);
struct stcp_link;
struct stcp_client;
void tcp_server_on_link(struct stcp_link *link, struct ETCP_SOCKET *tcp_sock);
// connection functions
@ -422,9 +423,11 @@ int etcp_send_ping_to_socket(struct UTUN_INSTANCE* instance, struct ETCP_SOCKET*
// TCP-ping: подключение к TCP-адресу peer + хендшейк с флагом PING. RTT меряется
// по хендшейку (send→response). cb вызывается один раз (success=1/rtt или success=0).
// out_cli (опционально) — возвращает хендл stcp_client для досрочной отмены (stcp_client_destroy).
int etcp_send_tcp_ping(struct UTUN_INSTANCE* instance, const uint8_t* peer_pubkey_bin,
const struct sockaddr_storage* addr, int timeout_ms,
etcp_ping_callback_t cb, void* user_arg);
etcp_ping_callback_t cb, void* user_arg,
struct stcp_client** out_cli);
void etcp_connections_read_callback_socket(socket_t sock, void* arg);

4
tests/test_stcp_ping.c

@ -69,7 +69,7 @@ int main(void) {
struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
sin->sin_family = AF_INET; sin->sin_addr.s_addr = htonl(0x7f000001); sin->sin_port = htons(port);
int rc = etcp_send_tcp_ping(cli, srv_pub, &addr, 2000, ping_cb, NULL);
int rc = etcp_send_tcp_ping(cli, srv_pub, &addr, 2000, ping_cb, NULL, NULL);
if (rc != 0) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "etcp_send_tcp_ping failed rc=%d", rc); return 1; }
int ticks = 0;
@ -82,7 +82,7 @@ int main(void) {
struct sockaddr_storage bad_addr; memset(&bad_addr, 0, sizeof(bad_addr));
struct sockaddr_in *bsin = (struct sockaddr_in *)&bad_addr;
bsin->sin_family = AF_INET; bsin->sin_addr.s_addr = htonl(0x7f000001); bsin->sin_port = htons(port + 5000);
rc = etcp_send_tcp_ping(cli, srv_pub, &bad_addr, 1000, ping_cb, NULL);
rc = etcp_send_tcp_ping(cli, srv_pub, &bad_addr, 1000, ping_cb, NULL, NULL);
ticks = 0;
while (ping_ok < 0 && ticks < 3000) { uasync_poll(ua, 10); ticks++; }
if (ping_ok != 0) { DEBUG_ERROR(DEBUG_CATEGORY_GENERAL, "=== FAILED (failure path): success=%d rtt=%u rc=%d ===", ping_ok, ping_rtt, rc); return 1; }

Loading…
Cancel
Save