Add socket type (public/nat/private) to handshake and skip private nodes in NAT detection
This commit is contained in:
1 parent
bd749c1484
commit
f02603f8ac
3 files changed
+28
-12
No files matched your search
+18
-11
@@ -100,6 +100,7 @@ static void etcp_link_send_init(struct ETCP_LINK* link, uint8_t reset) {
|
||||
dgram->data[offset++] = link->local_link_id;
|
||||
dgram->data[offset++] = link->conn ? link->conn->sock_id : 0;
|
||||
dgram->data[offset++] = link->conn ? link->conn->only_local : 0;
|
||||
dgram->data[offset++] = link->conn ? link->conn->type : CFG_SERVER_TYPE_UNKNOWN;
|
||||
|
||||
// padding
|
||||
int s = rand() % (link->handshake_maxsize - link->handshake_minsize) + link->handshake_minsize;
|
||||
@@ -1211,11 +1212,12 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
uint8_t mtu[2];
|
||||
uint8_t keepalive[2];
|
||||
uint8_t recovery[2];
|
||||
uint8_t link_id;
|
||||
uint8_t remote_socket_id;
|
||||
uint8_t only_local;
|
||||
uint8_t pubkey[SC_PUBKEY_SIZE];
|
||||
} *ack_hdr=(void*)&pkt->data[0];
|
||||
uint8_t link_id;
|
||||
uint8_t remote_socket_id;
|
||||
uint8_t only_local;
|
||||
uint8_t type;
|
||||
uint8_t pubkey[SC_PUBKEY_SIZE];
|
||||
} *ack_hdr=(void*)&pkt->data[0];
|
||||
uint64_t peer_id = be64toh(*(uint64_t*)ack_hdr->id);
|
||||
if (ack_hdr->code == ETCP_PING) {
|
||||
uint64_t nonce = be64toh(*(uint64_t*)(pkt->data + 9));
|
||||
@@ -1358,6 +1360,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
link->remote_link_id = ack_hdr->link_id;
|
||||
link->remote_socket_id = ack_hdr->remote_socket_id;
|
||||
link->remote_only_local = ack_hdr->only_local;
|
||||
link->remote_type = ack_hdr->type;
|
||||
|
||||
// For CHANNEL_INIT (0x04): if link already initialized - no reset, otherwise reset
|
||||
// For INIT_REQUEST (0x02): always reset
|
||||
@@ -1385,6 +1388,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
link->remote_link_id = ack_hdr->link_id;
|
||||
link->remote_socket_id = ack_hdr->remote_socket_id;
|
||||
link->remote_only_local = ack_hdr->only_local;
|
||||
link->remote_type = ack_hdr->type;
|
||||
|
||||
// For new links: check session_id to avoid false reinit
|
||||
if (conn->session_id != session_id) {
|
||||
@@ -1408,11 +1412,12 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
uint8_t session_id[4];
|
||||
uint8_t mtu[2];
|
||||
uint8_t link_id;
|
||||
uint8_t remote_socket_id;
|
||||
uint8_t only_local;
|
||||
uint8_t peer_ipv4[4];
|
||||
uint8_t peer_port[2];
|
||||
} *ack_repl_hdr=(void*)&pkt->data[0];
|
||||
uint8_t remote_socket_id;
|
||||
uint8_t only_local;
|
||||
uint8_t type;
|
||||
uint8_t peer_ipv4[4];
|
||||
uint8_t peer_port[2];
|
||||
} *ack_repl_hdr=(void*)&pkt->data[0];
|
||||
|
||||
// Set response code: 0x03 (with reset) or 0x05 (without reset)
|
||||
// response with init (0x03) only if reinit was actually done on server side
|
||||
@@ -1431,6 +1436,7 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
|
||||
ack_repl_hdr->link_id = link->local_link_id;
|
||||
ack_repl_hdr->remote_socket_id = ack_hdr->remote_socket_id;
|
||||
ack_repl_hdr->only_local = e_sock->only_local;
|
||||
ack_repl_hdr->type = e_sock->type;
|
||||
// Add client's IP:port (so client behind NAT can know its external address)
|
||||
if (addr.ss_family == AF_INET) {
|
||||
struct sockaddr_in *sin = (struct sockaddr_in*)&addr;
|
||||
@@ -1537,9 +1543,10 @@ process_decrypted:
|
||||
link->remote_link_id = pkt->data[offset++];
|
||||
link->remote_socket_id = pkt->data[offset++];
|
||||
link->remote_only_local = pkt->data[offset++];
|
||||
link->remote_type = pkt->data[offset++];
|
||||
|
||||
// Parse NAT IP:port from response (new format includes 4+2 bytes)
|
||||
if (pkt_len >= 23) {
|
||||
if (pkt_len >= 24) {
|
||||
uint32_t new_nat_ip;
|
||||
memcpy(&new_nat_ip, &pkt->data[offset], 4);
|
||||
offset += 4;
|
||||
|
||||
@@ -120,6 +120,7 @@ struct ETCP_LINK {
|
||||
uint8_t remote_link_id; // id этого линка на peer (устанавливается в момент initialized)
|
||||
uint8_t remote_socket_id; // socket id peer
|
||||
uint8_t remote_only_local; // only_local flag from peer
|
||||
uint8_t remote_type; // CFG_SERVER_TYPE_* (type of peer's socket)
|
||||
uint8_t nat_type; // NAT_TYPE_* (detected for this client link)
|
||||
uint8_t recv_keepalive; // 1 - up, 0 - down (принимаются ли пакеты)
|
||||
uint8_t remote_keepalive; // 1 - up, 0 - down (удаленная сторона сообщает - принимаются ли у нее пакеты)
|
||||
|
||||
+9
-1
@@ -586,7 +586,10 @@ static struct ETCP_CONN* route_bgp_find_third_node(struct ROUTE_BGP* bgp, struct
|
||||
struct ll_entry* e = bgp->senders_list->head;
|
||||
while (e) {
|
||||
struct ROUTE_BGP_CONN_ITEM* item = (struct ROUTE_BGP_CONN_ITEM*)e->data;
|
||||
if (item && item->conn && item->conn != exclude && item->conn->links && item->conn->links->remote_only_local==0) return item->conn;
|
||||
if (item && item->conn && item->conn != exclude && item->conn->links && item->conn->links->remote_only_local==0) {
|
||||
// Skip nodes with private socket type - they can't help with NAT detection
|
||||
if (item->conn->links->remote_type != CFG_SERVER_TYPE_PRIVATE) return item->conn;
|
||||
}
|
||||
e = e->next;
|
||||
}
|
||||
return NULL;
|
||||
@@ -609,6 +612,11 @@ static void route_bgp_extract_nat_addr(struct ETCP_CONN* conn, uint32_t* nat_ip,
|
||||
void route_bgp_start_link_nat_check(struct ROUTE_BGP* bgp, struct ETCP_LINK* link) {// проверяем тип нат для линка link
|
||||
if (!bgp || !link || !link->conn || !link->etcp) return;
|
||||
if (link->nat_check_status == NAT_CHECK_IN_PROGRESS) return;
|
||||
// Skip NAT check for private sockets - they are not reachable from outside
|
||||
if (link->conn->type == CFG_SERVER_TYPE_PRIVATE) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "skip nat check for private socket link");
|
||||
return;
|
||||
}
|
||||
// Find third node to send ping through
|
||||
struct ETCP_CONN* third_conn = route_bgp_find_third_node(bgp, link->etcp);
|
||||
if (!third_conn) {
|
||||
|
||||
Reference in new issue
Block a user