WIP: debug byte order diagnostics
This commit is contained in:
1 parent
6a971389b6
commit
77fd7c19de
21 files changed
+1389
-131
No files matched your search
@@ -0,0 +1,6 @@
|
||||
Есть 2 типа подключений - обычные (роутятся через подключения в конфиге) - по ним распространяется bgp и сигнальные пакеты
|
||||
|
||||
А для передачи данных между узлами можно установить прямое подключение (или подключение через лучший промежуточный узел).
|
||||
|
||||
Как работает:
|
||||
в nodeinfo
|
||||
+19
-5
@@ -308,6 +308,11 @@ void route_bgp_destroy(struct UTUN_INSTANCE* instance) {
|
||||
instance->bgp = NULL;
|
||||
}
|
||||
|
||||
void route_bgp_set_nat_check_local(struct ROUTE_BGP* bgp, int allow) {
|
||||
if (!bgp) return;
|
||||
bgp->allow_nat_check_local = allow ? 1 : 0;
|
||||
}
|
||||
|
||||
void route_bgp_new_conn(struct ETCP_CONN* conn) {
|
||||
if (!conn) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "route_bgp_new_conn: conn is NULL");
|
||||
@@ -549,8 +554,8 @@ struct nat_check_arg {
|
||||
};
|
||||
|
||||
static void nat_link_check_cb(int success, uint16_t avg_rtt, uint8_t count_sent, uint8_t count_ok,
|
||||
uint32_t recv_ip, uint16_t recv_port, void* arg) {
|
||||
(void)avg_rtt; (void)count_sent; (void)count_ok; (void)recv_ip; (void)recv_port;
|
||||
void* arg) {
|
||||
(void)avg_rtt; (void)count_sent; (void)count_ok;
|
||||
struct nat_check_arg* na = (struct nat_check_arg*)arg;
|
||||
if (!na || !na->link) { u_free(na); return; }
|
||||
struct ETCP_LINK* link = na->link;
|
||||
@@ -614,7 +619,10 @@ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LI
|
||||
target_port = ntohs(sin->sin_port);
|
||||
}
|
||||
|
||||
if (is_local_subnet(target_ip)) { DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "local connection: %s, skip nat check", ip_to_str(&target_ip, AF_INET).str); return; }
|
||||
if (!bgp->allow_nat_check_local && is_local_subnet(target_ip)) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "local connection: %s, skip nat check", ip_to_str(&target_ip, AF_INET).str);
|
||||
return;
|
||||
}
|
||||
|
||||
// Allocate callback arg
|
||||
struct nat_check_arg* arg = u_calloc(1, sizeof(struct nat_check_arg));
|
||||
@@ -630,7 +638,7 @@ static void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LI
|
||||
return;
|
||||
}
|
||||
// Send ping via third node - embed peer pubkey for NAT detection
|
||||
int ret = route_ping_send_req_addr(bgp, third_conn, link->etcp->peer_node_id, target_ip, target_port,
|
||||
int ret = route_ping_send_req_addr(bgp, third_conn, target_ip, target_port,
|
||||
3, 500, 1000, 5000, nat_link_check_cb, arg,
|
||||
pubkey);
|
||||
if (ret == 0) {
|
||||
@@ -875,8 +883,11 @@ static void route_bgp_handle_nat_info(struct ROUTE_BGP* bgp, struct ETCP_CONN* f
|
||||
const struct BGP_NAT_INFO* info = (const struct BGP_NAT_INFO*)data;
|
||||
uint32_t nat_ip = (info->nat_ip[0] << 24) | (info->nat_ip[1] << 16) |
|
||||
(info->nat_ip[2] << 8) | info->nat_ip[3];
|
||||
uint16_t nat_port = ((info->nat_port >> 8) & 0xFF) | ((info->nat_port & 0xFF) << 8);
|
||||
uint16_t nat_port = ntohs(info->nat_port);
|
||||
uint8_t socket_id = info->socket_id;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO recv: ip_bytes=0x%02x%02x%02x%02x ip_host=0x%08x port_net=%u port_host=%u",
|
||||
info->nat_ip[0], info->nat_ip[1], info->nat_ip[2], info->nat_ip[3],
|
||||
nat_ip, info->nat_port, nat_port);
|
||||
|
||||
uint8_t* dynamic = (uint8_t*)&bgp->local_node->node + sizeof(struct NODEINFO);
|
||||
dynamic += bgp->local_node->node.node_name_len;
|
||||
@@ -982,6 +993,9 @@ void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t
|
||||
pkt->nat_ip[3] = nat_ip & 0xFF;
|
||||
pkt->nat_port = htons(nat_port);
|
||||
pkt->nat_type = nat_type;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO send: ip_host=0x%08x ip_bytes=0x%02x%02x%02x%02x port_host=%u port_net=%u",
|
||||
nat_ip, pkt->nat_ip[0], pkt->nat_ip[1], pkt->nat_ip[2], pkt->nat_ip[3],
|
||||
nat_port, pkt->nat_port);
|
||||
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
if (!e) {
|
||||
|
||||
@@ -84,6 +84,7 @@ struct ROUTE_BGP {
|
||||
struct NODEINFO_Q* local_node;
|
||||
struct route_ping_pending* ping_pending;
|
||||
uint64_t next_ping_req_id;
|
||||
uint8_t allow_nat_check_local; // 1 = разрешить NAT check для локальных подсетей (для тестов)
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -186,4 +187,10 @@ void route_bgp_send_nat_info(struct ETCP_CONN* conn, uint8_t socket_id, uint32_t
|
||||
*/
|
||||
void route_bgp_send_nat_check_req(struct ETCP_CONN* conn, uint8_t socket_id);
|
||||
|
||||
/**
|
||||
* @brief Разрешить/запретить NAT check для локальных подсетей (127.0.0.1, 10.x.x.x и т.д.)
|
||||
* По умолчанию запрещено. Полезно для тестов.
|
||||
*/
|
||||
void route_bgp_set_nat_check_local(struct ROUTE_BGP* bgp, int allow);
|
||||
|
||||
#endif // ROUTE_BGP_H
|
||||
@@ -0,0 +1,71 @@
|
||||
подсистема роутинга
|
||||
utun - это сеть узлов. у каждого узла есть собственные локальные подсети.
|
||||
глобальная задача: создать у каждого узла полную таблицу маршрутизации.
|
||||
Узлы преимущественно создают связь напрямую друг с другом. Но если это не получается отправляют трафик транзитом через доступные узлы.
|
||||
Иногда бывает что через транзитные узлы метрики лучше чем напрямую. Используем приоритетно узлы с лучшей метриков, при нехватке bandwidth используем разные каналы (агрегируем).
|
||||
Динамически обновлем метрики каналов чтобы при отказе быстро переключаться на другие и не фризить обмен из-за отказов.
|
||||
|
||||
|
||||
и узлы обмениваются таблицой маршрутов между собой так чтобы у каждого была актуальная таблица подсетей всех узлов.
|
||||
маршрутами меняются клиенты, подключения которых которые взяты из конфига. и сервера принявшие подключения если клиент инициировал обмен маршрутами.
|
||||
|
||||
инициируется подключение, клиент отправляет свою таблицу. когда сервер принимает таблицу - сервер помечает что по этому маршруту надо обмениваться маршрутами, далее;
|
||||
- добавляет узел в список рассылки обновлений маршрутов
|
||||
- отправляет свою таблицу
|
||||
- добавляет в свою таблицу отсутствующие маршруты
|
||||
- если что-то добавил:
|
||||
- рассылает измененные маршруты по списку рассылки
|
||||
- список рассылки - это linked-list очередей (также на базе ll_queue - каждый элемент = подписчик). один маршрут = одна отправленная кодограмма
|
||||
|
||||
|
||||
при подключении узла или изменении таблицы: узел шлёт свою таблицу
|
||||
формат кодограммы: [0x01 - routing module] [subcmd] [data]
|
||||
subcmd:
|
||||
1 [route] - отправка маршрута
|
||||
2, без данных - больше данных нет
|
||||
|
||||
если сервер получил кодограмму маршрута - он помечает флаг в etcp что с узлом надо обмениваться маршрутами (etcp_conn->routing_exchange_active=2) и добавляет в очередь рассылки маршрутов
|
||||
|
||||
|
||||
|
||||
=========================================
|
||||
механизм инкрементальной синхронизации (реализация - потом, пока мысли)
|
||||
1. вычисляем хеш каждой записи в роутинг таблице. используем ip+mask+node_uid
|
||||
2. потом из этих хешей создаем хеш таблицу (старшие n бит номер ячейки). далее вычисляются хеши каждой ячейки.
|
||||
на первом этапе n=16, на втором - n=16*16 на третьем n=16*16*16.
|
||||
|
||||
отправляем хеши удаленному узлу в формате: [n, 1 байт] ([индекс хеша 2 байта - используется n старших бит][хеш - 8 байт])
|
||||
|
||||
удаленный узел считает свои хеши и сравнивает. где не совпало смотрит сколько записей.
|
||||
если записей не много - передает эти записи.
|
||||
если записей много - добавляет 4 бита к хеш таблице и строит субтаблицу для
|
||||
==========================================
|
||||
|
||||
Формат роутинга:
|
||||
|
||||
Таблица узлов состоит из записей:
|
||||
- uid
|
||||
- name
|
||||
- links
|
||||
- 3 транзитных узла с метриками (RTT)
|
||||
- маршруты узла
|
||||
|
||||
- текущая загрузка линка (за последние 10 сек) можно частоту адаптировать под размер сети
|
||||
- bandidth limit
|
||||
- transit bandwidth limit
|
||||
|
||||
две группы узлов:
|
||||
- узлы за nat. подключаются через транзитные узлы. измеряют пинги до транзитных и выбирают N (3 default) лучшие линки. 3 лучших используем для распространения маршрутов
|
||||
- транзитные узлы. имеют линки с загрузкой.
|
||||
|
||||
добавить кодограмму - отменить распространение маршрутов по линку (+ сделать важным линком)
|
||||
|
||||
|
||||
|
||||
карта маршрутизации:
|
||||
|
||||
План:
|
||||
- сделать передачу роутинга в
|
||||
- сделать фоновый probe для узлов (условно 1 нода в секунду). выигравшие по качеству соатновятся основными
|
||||
- сделать etcp дизконнект:
|
||||
- отправить disconnect request + дождаться ack дальше master удаляет, slave удаляет по down.
|
||||
@@ -206,6 +206,9 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
|
||||
sa->port = ntohs(sin->sin_port);
|
||||
sa->type = e_sock->nat_type;
|
||||
sa->id = e_sock->sock_id;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NODEINFO socket: addr=0x%02x%02x%02x%02x port=%u (from sin_addr=0x%08x sin_port=%u)",
|
||||
sa->addr[0], sa->addr[1], sa->addr[2], sa->addr[3], sa->port,
|
||||
sin->sin_addr.s_addr, ntohs(sin->sin_port));
|
||||
sa++;
|
||||
}
|
||||
e_sock = e_sock->next;
|
||||
|
||||
+74
-72
@@ -62,69 +62,11 @@ static void route_ping_pending_timeout(void* arg) {
|
||||
cur = &(*cur)->next;
|
||||
}
|
||||
if (p->callback) {
|
||||
p->callback(0, 0, 0, 0, 0, 0, p->arg);
|
||||
p->callback(0, 0, 0, 0, p->arg);
|
||||
}
|
||||
u_free(p);
|
||||
}
|
||||
|
||||
// отправить запрос удаленному узлу "пропингуй такой-то узел"
|
||||
int route_ping_send_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, uint64_t node_id,
|
||||
uint8_t count, uint16_t interval_ms, uint16_t timeout_ms,
|
||||
uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg) {
|
||||
if (!bgp || !to_conn || count == 0 || timeout_ms == 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid args");
|
||||
return -1;
|
||||
}
|
||||
struct BGP_PING_REQUEST* req_pkt = u_calloc(1, sizeof(struct BGP_PING_REQUEST));
|
||||
if (!req_pkt) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "alloc failed");
|
||||
return -2;
|
||||
}
|
||||
req_pkt->cmd = ETCP_ID_ROUTE_ENTRY;
|
||||
req_pkt->subcmd = ROUTE_SUBCMD_PING_REQ;
|
||||
req_pkt->request_id = bgp->next_ping_req_id++;
|
||||
req_pkt->node_id = node_id;
|
||||
req_pkt->count = count;
|
||||
req_pkt->interval_ms = interval_ms;
|
||||
req_pkt->timeout_ms = timeout_ms;
|
||||
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
if (!e) {
|
||||
u_free(req_pkt);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "queue_entry_new failed");
|
||||
return -3;
|
||||
}
|
||||
e->dgram = (uint8_t*)req_pkt;
|
||||
e->len = offsetof(struct BGP_PING_REQUEST, target_ipv4);
|
||||
|
||||
int ret = etcp_send(to_conn, e);
|
||||
if (ret != 0) {
|
||||
u_free(req_pkt);
|
||||
queue_entry_free(e);
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "etcp_send failed");
|
||||
return -4;
|
||||
}
|
||||
|
||||
struct route_ping_pending* pending = u_calloc(1, sizeof(struct route_ping_pending));
|
||||
if (!pending) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "pending alloc failed");
|
||||
return -5;
|
||||
}
|
||||
pending->bgp = bgp;
|
||||
pending->request_id = req_pkt->request_id;
|
||||
pending->callback = cb;
|
||||
pending->arg = arg;
|
||||
pending->next = bgp->ping_pending;
|
||||
bgp->ping_pending = pending;
|
||||
|
||||
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 node=%016llx count=%u interval=%u timeout=%u wait=%u",
|
||||
(unsigned long long)pending->request_id, (unsigned long long)node_id,
|
||||
(unsigned)count, (unsigned)interval_ms, (unsigned)timeout_ms, (unsigned)wait_timeout_ms);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// прошел ответ "серия пигнов на удаленном узле завершена"
|
||||
void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn, const uint8_t* data, size_t len) {
|
||||
if (!bgp || !from_conn || !data || len < sizeof(struct BGP_PING_RESPONSE)) {
|
||||
@@ -147,10 +89,7 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn,
|
||||
}
|
||||
if (p->callback) {
|
||||
int success = (resp->count_ok > 0) ? 1 : 0;
|
||||
uint32_t recv_ip = (resp->recv_ipv4[0] << 24) | (resp->recv_ipv4[1] << 16) |
|
||||
(resp->recv_ipv4[2] << 8) | resp->recv_ipv4[3];
|
||||
uint16_t recv_port = ntohs(resp->recv_port);
|
||||
p->callback(success, resp->avg_rtt, resp->count_sent, resp->count_ok, recv_ip, recv_port, p->arg);
|
||||
p->callback(success, resp->avg_rtt, resp->count_sent, resp->count_ok, p->arg);
|
||||
}
|
||||
u_free(p);
|
||||
return;
|
||||
@@ -163,7 +102,7 @@ void route_ping_handle_resp(struct ROUTE_BGP* bgp, struct ETCP_CONN* from_conn,
|
||||
|
||||
// ========================================================================
|
||||
|
||||
int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, uint64_t node_id,
|
||||
int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn,
|
||||
uint32_t target_ip, uint16_t target_port,
|
||||
uint8_t count, uint16_t interval_ms, uint16_t timeout_ms,
|
||||
uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg,
|
||||
@@ -181,7 +120,6 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, u
|
||||
req_pkt->cmd = ETCP_ID_ROUTE_ENTRY;
|
||||
req_pkt->subcmd = ROUTE_SUBCMD_PING_REQ;
|
||||
req_pkt->request_id = bgp->next_ping_req_id++;
|
||||
req_pkt->node_id = node_id;
|
||||
req_pkt->count = count;
|
||||
req_pkt->interval_ms = interval_ms;
|
||||
req_pkt->timeout_ms = timeout_ms;
|
||||
@@ -190,6 +128,10 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, u
|
||||
if (pubkey) {
|
||||
memcpy(req_pkt->pubkey, pubkey, SC_PUBKEY_SIZE);
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "SEND_REQ: target_ip host=0x%08x net=0x%02x%02x%02x%02x port host=%u net=%u",
|
||||
target_ip,
|
||||
req_pkt->target_ipv4[0], req_pkt->target_ipv4[1], req_pkt->target_ipv4[2], req_pkt->target_ipv4[3],
|
||||
target_port, req_pkt->target_port);
|
||||
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
if (!e) {
|
||||
@@ -222,8 +164,8 @@ int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, u
|
||||
|
||||
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 node=%016llx ip=%s port=%u pubkey=%s",
|
||||
(unsigned long long)pending->request_id, (unsigned long long)node_id,
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "request_id=%016llx ip=%s port=%u pubkey=%s",
|
||||
(unsigned long long)pending->request_id,
|
||||
ip_to_str(&target_ip, AF_INET).str, (unsigned)target_port, pubkey ? "yes" : "no");
|
||||
return 0;
|
||||
}
|
||||
@@ -248,9 +190,6 @@ static void route_ping_series_finish(struct route_ping_series_ctx* ctx) {
|
||||
resp->count_sent = ctx->count_sent;
|
||||
resp->count_ok = ctx->count_ok;
|
||||
resp->avg_rtt = avg_rtt;
|
||||
/* recv_ipv4/port = 0 (не используется) */
|
||||
memset(resp->recv_ipv4, 0, 4);
|
||||
resp->recv_port = 0;
|
||||
|
||||
struct ll_entry* e = queue_entry_new(0);
|
||||
if (e) {
|
||||
@@ -318,7 +257,7 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
|
||||
struct ETCP_CONN* from_conn,
|
||||
const uint8_t* data,
|
||||
size_t len) {
|
||||
if (!bgp || !from_conn || !data || len < sizeof(struct BGP_PING_REQUEST)) {
|
||||
if (!bgp || !from_conn || !data || len < offsetof(struct BGP_PING_REQUEST, pubkey)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "ping req: bad args len=%zu", len);
|
||||
return;
|
||||
}
|
||||
@@ -336,13 +275,76 @@ void route_ping_handle_req(struct ROUTE_BGP* bgp,
|
||||
ctx->request_id = req_pkt->request_id;
|
||||
ctx->count_total = req_pkt->count;
|
||||
ctx->timeout_ms = req_pkt->timeout_ms;
|
||||
memcpy(ctx->pubkey, req_pkt->pubkey, SC_PUBKEY_SIZE);
|
||||
if (len >= sizeof(struct BGP_PING_REQUEST)) {
|
||||
memcpy(ctx->pubkey, req_pkt->pubkey, SC_PUBKEY_SIZE);
|
||||
}
|
||||
|
||||
/* Целевой адрес */
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)&ctx->target_addr;
|
||||
sin->sin_family = AF_INET;
|
||||
memcpy(&sin->sin_addr.s_addr, req_pkt->target_ipv4, 4);
|
||||
sin->sin_port = req_pkt->target_port;
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "RECV_REQ: target_ip net_bytes=0x%02x%02x%02x%02x sin_addr=0x%08x port_net=%u port_host=%u",
|
||||
req_pkt->target_ipv4[0], req_pkt->target_ipv4[1], req_pkt->target_ipv4[2], req_pkt->target_ipv4[3],
|
||||
sin->sin_addr.s_addr, req_pkt->target_port, ntohs(req_pkt->target_port));
|
||||
|
||||
/* Если target не указан — можно разрешить из nodeinfo */
|
||||
/*
|
||||
if (sin->sin_addr.s_addr == 0 && sin->sin_port == 0) {
|
||||
struct NODEINFO_Q* nq = route_bgp_get_node(bgp, req_pkt->node_id);
|
||||
if (nq) {
|
||||
const struct NODEINFO_IPV4_SOCKET* sockets;
|
||||
int count = get_node_v4_sockets(nq, &sockets);
|
||||
if (count > 0) {
|
||||
memcpy(&sin->sin_addr.s_addr, sockets[0].addr, 4);
|
||||
sin->sin_port = sockets[0].port;
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "resolved target from nodeinfo: %s:%u",
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* Если pubkey не указан — ищем по target_ip:port в nodeinfo */
|
||||
int pubkey_empty = 1;
|
||||
for (int i = 0; i < SC_PUBKEY_SIZE; i++) {
|
||||
if (ctx->pubkey[i] != 0) { pubkey_empty = 0; break; }
|
||||
}
|
||||
if (pubkey_empty) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "looking for pubkey for target %s:%u, nodes_count=%d",
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port),
|
||||
bgp->nodes ? bgp->nodes->count : -1);
|
||||
struct ll_entry* e = bgp->nodes ? bgp->nodes->head : NULL;
|
||||
while (e) {
|
||||
struct NODEINFO_Q* nq = (struct NODEINFO_Q*)e;
|
||||
const struct NODEINFO_IPV4_SOCKET* sockets;
|
||||
int sc = get_node_v4_sockets(nq, &sockets);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "checking node %016llx with %d sockets",
|
||||
(unsigned long long)nq->node.node_id, sc);
|
||||
for (int i = 0; i < sc; i++) {
|
||||
uint32_t socket_ip, target_ip;
|
||||
memcpy(&socket_ip, sockets[i].addr, 4);
|
||||
memcpy(&target_ip, req_pkt->target_ipv4, 4);
|
||||
if (socket_ip == target_ip || socket_ip == htonl(target_ip) ||
|
||||
htonl(socket_ip) == target_ip || htonl(socket_ip) == htonl(target_ip)) {
|
||||
memcpy(ctx->pubkey, nq->node.public_key, SC_PUBKEY_SIZE);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, "resolved pubkey from nodeinfo for %s:%u",
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
break;
|
||||
}
|
||||
}
|
||||
pubkey_empty = 1;
|
||||
for (int i = 0; i < SC_PUBKEY_SIZE; i++) {
|
||||
if (ctx->pubkey[i] != 0) { pubkey_empty = 0; break; }
|
||||
}
|
||||
if (!pubkey_empty) break;
|
||||
e = e->next;
|
||||
}
|
||||
if (pubkey_empty) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "pubkey not found for target %s:%u",
|
||||
ip_to_str(&sin->sin_addr, AF_INET).str, ntohs(sin->sin_port));
|
||||
}
|
||||
}
|
||||
|
||||
/* Ищем первый IPv4-сокет (как в старом коде) */
|
||||
struct ETCP_SOCKET* ls = bgp->instance->etcp_sockets;
|
||||
|
||||
+2
-11
@@ -12,7 +12,6 @@ struct BGP_PING_REQUEST {
|
||||
uint8_t cmd; // ETCP_ID_ROUTE_ENTRY
|
||||
uint8_t subcmd; // ROUTE_SUBCMD_PING_REQ
|
||||
uint64_t request_id; // для корреляции
|
||||
uint64_t node_id; // целевой узел
|
||||
uint8_t count; // число пингов
|
||||
uint8_t socket_id; // id сокета пингуемого узла
|
||||
uint16_t interval_ms; // интервал между пингами
|
||||
@@ -29,22 +28,14 @@ struct BGP_PING_RESPONSE {
|
||||
uint8_t count_sent;
|
||||
uint8_t count_ok;
|
||||
uint16_t avg_rtt; // средний RTT в 0.1ms
|
||||
uint8_t recv_ipv4[4]; // IP:port с которого получен PING_REQ (STUN-like)
|
||||
uint16_t recv_port; // network byte order
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef void (*route_ping_callback_t)(int success, uint16_t avg_rtt, uint8_t count_sent, uint8_t count_ok,
|
||||
uint32_t recv_ip, uint16_t recv_port, void* arg);
|
||||
|
||||
// Отправить запрос пинга через BGP, ожидать ответа с таймаутом
|
||||
int route_ping_send_req(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, uint64_t node_id,
|
||||
uint8_t count, uint16_t interval_ms, uint16_t timeout_ms,
|
||||
uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg);
|
||||
typedef void (*route_ping_callback_t)(int success, uint16_t avg_rtt, uint8_t count_sent, uint8_t count_ok, void* arg);
|
||||
|
||||
// Отправить запрос пинга по произвольному IP:port (используется для NAT-детекции)
|
||||
// Если target_ip == 0, используется node_id из списка известных узлов
|
||||
// Если pubkey != NULL, он передается в пакете (для пинга без локального nodeinfo)
|
||||
int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn, uint64_t node_id,
|
||||
int route_ping_send_req_addr(struct ROUTE_BGP* bgp, struct ETCP_CONN* to_conn,
|
||||
uint32_t target_ip, uint16_t target_port,
|
||||
uint8_t count, uint16_t interval_ms, uint16_t timeout_ms,
|
||||
uint16_t wait_timeout_ms, route_ping_callback_t cb, void* arg,
|
||||
|
||||
Reference in new issue
Block a user