Browse Source

Fix unaligned uint64_t access in packed struct causing garbage request_id

- Changed request_id from uint64_t to uint32_t in BGP_PING_REQUEST/RESPONSE
- Added uint16_t reserved field after subcmd for proper alignment
- Updated next_ping_req_id from uint64_t to uint32_t in ROUTE_BGP
- Fixed all log format strings from %016llx to %08x
- All 26 tests passing
congestion
Evgeny 5 months ago
parent
commit
ae1c59f3a9
  1. 2
      src/route_bgp.h
  2. 28
      src/route_ping.c
  3. 6
      src/route_ping.h

2
src/route_bgp.h

@ -85,7 +85,7 @@ struct ROUTE_BGP {
struct ll_queue* nodes; struct ll_queue* nodes;
struct NODEINFO_Q* local_node; struct NODEINFO_Q* local_node;
struct route_ping_pending* ping_pending; struct route_ping_pending* ping_pending;
uint64_t next_ping_req_id; uint32_t next_ping_req_id;
uint8_t allow_nat_check_local; // 1 = разрешить NAT check для локальных подсетей (для тестов) uint8_t allow_nat_check_local; // 1 = разрешить NAT check для локальных подсетей (для тестов)
}; };

28
src/route_ping.c

@ -21,7 +21,7 @@
struct route_ping_series_ctx { struct route_ping_series_ctx {
struct ETCP_CONN* reply_conn; struct ETCP_CONN* reply_conn;
uint64_t request_id; uint32_t request_id;
struct sockaddr_storage target_addr; struct sockaddr_storage target_addr;
uint8_t pubkey[SC_PUBKEY_SIZE]; uint8_t pubkey[SC_PUBKEY_SIZE];
struct ETCP_SOCKET* local_sock; struct ETCP_SOCKET* local_sock;
@ -37,7 +37,7 @@ struct route_ping_series_ctx {
struct route_ping_pending { struct route_ping_pending {
struct route_ping_pending* next; struct route_ping_pending* next;
struct ROUTE_BGP* bgp; struct ROUTE_BGP* bgp;
uint64_t request_id; uint32_t request_id;
route_ping_callback_t callback; route_ping_callback_t callback;
void* arg; void* arg;
void* timeout_timer; void* timeout_timer;
@ -76,8 +76,8 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn,
return; return;
} }
const struct BGP_PING_RESPONSE* resp = (const struct BGP_PING_RESPONSE*)data; const struct BGP_PING_RESPONSE* resp = (const struct BGP_PING_RESPONSE*)data;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "from=%s request_id=%016llx sent=%u ok=%u avg_rtt=%u", DEBUG_INFO(DEBUG_CATEGORY_BGP, "from=%s request_id=%08x sent=%u ok=%u avg_rtt=%u",
from_conn->log_name, (unsigned long long)resp->request_id, from_conn->log_name, (unsigned)resp->request_id,
(unsigned)resp->count_sent, (unsigned)resp->count_ok, (unsigned)resp->avg_rtt); (unsigned)resp->count_sent, (unsigned)resp->count_ok, (unsigned)resp->avg_rtt);
struct route_ping_pending** cur = &bgp->ping_pending; struct route_ping_pending** cur = &bgp->ping_pending;
@ -98,8 +98,8 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn,
} }
cur = &(*cur)->next; cur = &(*cur)->next;
} }
DEBUG_WARN(DEBUG_CATEGORY_BGP, "request_id=%016llx not found in pending list", DEBUG_WARN(DEBUG_CATEGORY_BGP, "request_id=%08x not found in pending list",
(unsigned long long)resp->request_id); (unsigned)resp->request_id);
} }
void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) { void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) {
@ -119,7 +119,7 @@ void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) {
struct nat_check_arg* na = (struct nat_check_arg*)p->arg; struct nat_check_arg* na = (struct nat_check_arg*)p->arg;
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, " checking pending req_id=%016llx via=%s link->etcp=%s", DEBUG_DEBUG(DEBUG_CATEGORY_BGP, " checking pending req_id=%016llx via=%s link->etcp=%s",
(unsigned long long)p->request_id, (unsigned)p->request_id,
p->via_conn ? p->via_conn->log_name : "NULL", p->via_conn ? p->via_conn->log_name : "NULL",
(na && na->link && na->link->etcp) ? na->link->etcp->log_name : "NULL"); (na && na->link && na->link->etcp) ? na->link->etcp->log_name : "NULL");
@ -134,7 +134,7 @@ void route_ping_cancel_for_conn(struct ROUTE_BGP* bgp, struct ETCP_CONN* conn) {
u_free(p); u_free(p);
cancelled++; cancelled++;
DEBUG_INFO(DEBUG_CATEGORY_BGP, "cancel_for_conn: cancelled req_id=%016llx", DEBUG_INFO(DEBUG_CATEGORY_BGP, "cancel_for_conn: cancelled req_id=%016llx",
(unsigned long long)p->request_id); (unsigned)p->request_id);
} else { } else {
cur = &(*cur)->next; cur = &(*cur)->next;
} }
@ -207,8 +207,8 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn,
pending->timeout_timer = uasync_set_timeout(bgp->instance->ua, wait_timeout_ms * 10, pending, route_ping_pending_timeout, "route_ping"); pending->timeout_timer = uasync_set_timeout(bgp->instance->ua, wait_timeout_ms * 10, pending, route_ping_pending_timeout, "route_ping");
DEBUG_INFO(DEBUG_CATEGORY_BGP, "request_id=%016llx ip=%s port=%u pubkey=%s", DEBUG_INFO(DEBUG_CATEGORY_BGP, "request_id=%08x ip=%s port=%u pubkey=%s",
(unsigned long long)pending->request_id, (unsigned)pending->request_id,
ip_to_str(&target_ip, AF_INET).str, (unsigned)target_port, pubkey ? "yes" : "no"); ip_to_str(&target_ip, AF_INET).str, (unsigned)target_port, pubkey ? "yes" : "no");
return 0; return 0;
} }
@ -241,9 +241,9 @@ static void route_ping_series_finish(struct route_ping_series_ctx* ctx) {
e->len = sizeof(struct BGP_PING_RESPONSE); e->len = sizeof(struct BGP_PING_RESPONSE);
etcp_send(ctx->reply_conn, e); etcp_send(ctx->reply_conn, e);
DEBUG_INFO(DEBUG_CATEGORY_BGP, DEBUG_INFO(DEBUG_CATEGORY_BGP,
"PING series done %s request_id=%016llx sent=%u ok=%u avg_rtt=%u", "PING series done %s request_id=%08x sent=%u ok=%u avg_rtt=%u",
ctx->reply_conn->log_name, ctx->reply_conn->log_name,
(unsigned long long)ctx->request_id, (unsigned)ctx->request_id,
(unsigned)ctx->count_sent, (unsigned)ctx->count_sent,
(unsigned)ctx->count_ok, (unsigned)ctx->count_ok,
(unsigned)avg_rtt); (unsigned)avg_rtt);
@ -366,8 +366,8 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
} }
DEBUG_INFO(DEBUG_CATEGORY_BGP, DEBUG_INFO(DEBUG_CATEGORY_BGP,
"PING series start request_id=%016llx target=%s:%u count=%u timeout=%u", "PING series start request_id=%08x target=%s:%u count=%u timeout=%u",
(unsigned long long)ctx->request_id, (unsigned)ctx->request_id,
ip_to_str(&sin->sin_addr, AF_INET).str, ip_to_str(&sin->sin_addr, AF_INET).str,
ntohs(sin->sin_port), ntohs(sin->sin_port),
(unsigned)ctx->count_total, (unsigned)ctx->count_total,

6
src/route_ping.h

@ -11,7 +11,8 @@
struct BGP_PING_REQUEST { struct BGP_PING_REQUEST {
uint8_t cmd; // ETCP_ID_ROUTE_ENTRY uint8_t cmd; // ETCP_ID_ROUTE_ENTRY
uint8_t subcmd; // ROUTE_SUBCMD_PING_REQ uint8_t subcmd; // ROUTE_SUBCMD_PING_REQ
uint64_t request_id; // для корреляции uint16_t reserved; // padding для выравнивания request_id
uint32_t request_id; // для корреляции
uint8_t count; // число пингов uint8_t count; // число пингов
uint8_t socket_id; // id сокета пингуемого узла uint8_t socket_id; // id сокета пингуемого узла
uint16_t interval_ms; // интервал между пингами uint16_t interval_ms; // интервал между пингами
@ -24,7 +25,8 @@ struct BGP_PING_REQUEST {
struct BGP_PING_RESPONSE { struct BGP_PING_RESPONSE {
uint8_t cmd; uint8_t cmd;
uint8_t subcmd; // ROUTE_SUBCMD_PING_RESP uint8_t subcmd; // ROUTE_SUBCMD_PING_RESP
uint64_t request_id; uint16_t reserved; // padding для выравнивания
uint32_t request_id;
uint8_t count_sent; uint8_t count_sent;
uint8_t count_ok; uint8_t count_ok;
uint16_t avg_rtt; // средний RTT в 0.1ms uint16_t avg_rtt; // средний RTT в 0.1ms

Loading…
Cancel
Save