Fix ETCP INIT collision scope and backpressure regression tests

This commit is contained in:
evgeny committed 2026-10-02 02:25:40 +03:00
1 parent 217e5795bf
commit ac45554439
4 files changed
+266 -71

No files matched your search

+17 -8
View File
@@ -512,16 +512,25 @@ static void etcp_link_update_remote_addr(struct ETCP_LINK* link, struct ETCP_SOC
link->etcp->log_name, sockaddr_storage_to_str(new_addr).str);
}
/* Выбор линка для отправки collision INIT: outbound-линк (is_server==0), чей remote_addr
* совпадает с адресом пришедшего INIT (симметричный сокет). NULL — симметричного сокета
* нет (асимметрия/NAT) → коллизия не срабатывает, inbound принимается как есть. */
struct ETCP_LINK* etcp_select_collision_link(struct ETCP_CONN* conn, const struct sockaddr_storage* addr) {
if (!conn || !addr) return NULL;
/* Коллизия INIT возможна только на одной паре: принимающий сокет + адрес отправителя.
* Исходящий линк через другой локальный сокет — независимый путь к тому же пиру. */
struct ETCP_LINK* etcp_select_collision_link(struct ETCP_CONN* conn, struct ETCP_SOCKET* e_sock,
const struct sockaddr_storage* addr) {
if (!conn || !e_sock || !addr) {
DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "collision lookup: invalid conn=%p socket=%p addr=%p", conn, e_sock, addr);
return NULL;
}
struct ETCP_LINK* l = conn->links;
while (l) {
if (l->is_server == 0 && sockaddr_equal(&l->remote_addr, addr)) return l;
if (l->is_server == 0 && l->conn == e_sock && sockaddr_equal(&l->remote_addr, addr)) {
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] collision lookup: recv_socket=%s remote=%s outbound_link=%u/%u",
conn->log_name, e_sock->name, sockaddr_storage_to_str(addr).str, l->local_link_id, l->remote_link_id);
return l;
}
l = l->next;
}
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] collision lookup: recv_socket=%s remote=%s no matching outbound link",
conn->log_name, e_sock->name, sockaddr_storage_to_str(addr).str);
return NULL;
}
@@ -2427,7 +2436,7 @@ static void etcp_process_packet(struct ETCP_SOCKET* e_sock, uint8_t* data,
send_reset = 1;
} else {
// Check if WE have an outbound (master) link on this conn
struct ETCP_LINK* ml = etcp_select_collision_link(conn, &addr);
struct ETCP_LINK* ml = etcp_select_collision_link(conn, e_sock, &addr);
if (ml) {
if (conn->instance->node_id < peer_id) {
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] COLLISION: we=master node_id=%016llx < peer=%016llx — sending collision INIT",
@@ -2477,7 +2486,7 @@ create_new_link:
send_reset = 1;
} else {
// Check if WE have an outbound (master) link
struct ETCP_LINK* ml = etcp_select_collision_link(conn, &addr);
struct ETCP_LINK* ml = etcp_select_collision_link(conn, e_sock, &addr);
if (ml && conn->instance->node_id < peer_id) {
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "[%s] COLLISION: we=master node_id=%016llx < peer=%016llx — sending collision INIT",
conn->log_name, (unsigned long long)conn->instance->node_id, (unsigned long long)peer_id);
+4 -3
View File
@@ -384,9 +384,10 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram);// зашифровывает и
// find link by address
struct ETCP_LINK* etcp_link_find_by_addr(struct ETCP_SOCKET* e_sock, struct sockaddr_storage* addr, int is_tcp);
// Выбор линка для collision INIT: outbound-линк (is_server==0), чей remote_addr совпадает
// с адресом пришедшего INIT (симметричный сокет). NULL — симметричного сокета нет.
struct ETCP_LINK* etcp_select_collision_link(struct ETCP_CONN* conn, const struct sockaddr_storage* addr);
// Выбор исходящего линка для collision INIT по принимающему сокету и адресу отправителя.
// Линк через другой локальный сокет не подходит. NULL — встречной попытки на этой паре нет.
struct ETCP_LINK* etcp_select_collision_link(struct ETCP_CONN* conn, struct ETCP_SOCKET* e_sock,
const struct sockaddr_storage* addr);
// find free local_link_id for connection
// scans all links in connection, marks used ids in bit array