|
|
|
|
@ -128,97 +128,26 @@ static void nat_detection_handle_nat_info(struct NAT_DETECTION* nd, struct TOPO_
|
|
|
|
|
else if (info->nat_type == NAT_TYPE_DIRECT) verified_type = NAT_VERIFIED_DIRECT; |
|
|
|
|
else verified_type = NAT_VERIFIED_UNKNOWN; |
|
|
|
|
|
|
|
|
|
if (group && group->local_node) { |
|
|
|
|
struct TOPO_NODE* ni = topo_node_registry_find(group->instance->topo_groups, group->local_node->node_id); |
|
|
|
|
if (!ni) return; |
|
|
|
|
int data_changed = 0; |
|
|
|
|
struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; |
|
|
|
|
while (sm) { |
|
|
|
|
if (sm->id == socket_id) { |
|
|
|
|
if (sm->nat_type != verified_type) { sm->nat_type = verified_type; data_changed = 1; } |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
sm = sm->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
struct ETCP_SOCKET* es = group->instance->etcp_sockets; |
|
|
|
|
while (es) { |
|
|
|
|
if (es->sock_id == socket_id) { |
|
|
|
|
if (verified_type == NAT_VERIFIED_STRICT) { |
|
|
|
|
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; |
|
|
|
|
nat_sin->sin_family = AF_INET; |
|
|
|
|
nat_sin->sin_addr.s_addr = nat_ip; |
|
|
|
|
nat_sin->sin_port = htons(nat_port); |
|
|
|
|
es->nat_type = verified_type; |
|
|
|
|
} else { |
|
|
|
|
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; |
|
|
|
|
uint32_t old_nat_ip = nat_sin->sin_addr.s_addr; |
|
|
|
|
uint16_t old_nat_port = ntohs(nat_sin->sin_port); |
|
|
|
|
nat_sin->sin_family = AF_INET; |
|
|
|
|
nat_sin->sin_addr.s_addr = nat_ip; |
|
|
|
|
nat_sin->sin_port = htons(nat_port); |
|
|
|
|
if (old_nat_ip != nat_ip || old_nat_port != nat_port) data_changed = 1; |
|
|
|
|
es->nat_type = verified_type; |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
es = es->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (data_changed) { |
|
|
|
|
int prev_v4a = topo_list_count((struct _topo_head*)ni->v4_addrs); |
|
|
|
|
int dirty = 0; |
|
|
|
|
topo_group_update_my_nodeinfo(group->instance, group); |
|
|
|
|
if (topo_list_count((struct _topo_head*)ni->v4_addrs) != prev_v4a) { |
|
|
|
|
dirty = 1; |
|
|
|
|
ni->ver = (ni->ver % 255) + 1; |
|
|
|
|
group->local_node->last_ver = ni->ver; |
|
|
|
|
} |
|
|
|
|
if (topo_list_count((struct _topo_head*)ni->v4_addrs) == prev_v4a) { |
|
|
|
|
struct TOPO_ADDR4* a = ni->v4_addrs; |
|
|
|
|
while (a) { |
|
|
|
|
if (a->type == TOPO_ADDR_INTERFACE && a->socket_id == socket_id) { |
|
|
|
|
uint32_t a_ip; memcpy(&a_ip, a->addr, 4); |
|
|
|
|
if (a_ip == nat_ip && a->port == nat_port) { |
|
|
|
|
a->type = TOPO_ADDR_NAT; a->socket_id = socket_id; |
|
|
|
|
dirty = 1; |
|
|
|
|
ni->ver = (ni->ver % 255) + 1; |
|
|
|
|
group->local_node->last_ver = ni->ver; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO matched interface addr, updated entry type to NAT sock=%d", socket_id); |
|
|
|
|
} |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
a = a->next; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (dirty && group->senders_list) { |
|
|
|
|
topo_node_sign_self(group->instance, ni); |
|
|
|
|
struct ll_entry* se = group->senders_list->head; |
|
|
|
|
while (se) { |
|
|
|
|
struct TOPO_GROUP_CONN_ITEM* item = (struct TOPO_GROUP_CONN_ITEM*)se->data; |
|
|
|
|
if (item && item->conn) |
|
|
|
|
topo_group_send_nodeinfo(group, group->local_node, item->conn, 0); |
|
|
|
|
se = se->next; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
struct ETCP_SOCKET* es = nd->inst->etcp_sockets; |
|
|
|
|
while (es) { |
|
|
|
|
if (es->sock_id == socket_id) { |
|
|
|
|
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; |
|
|
|
|
nat_sin->sin_family = AF_INET; |
|
|
|
|
nat_sin->sin_addr.s_addr = nat_ip; |
|
|
|
|
nat_sin->sin_port = htons(nat_port); |
|
|
|
|
es->nat_type = verified_type; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO socket=%s id=%d type=%d addr=%s:%u (no topo_group)", |
|
|
|
|
es->name, socket_id, verified_type, |
|
|
|
|
ip_to_str(&nat_ip, AF_INET).str, nat_port); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
es = es->next; |
|
|
|
|
/* Хозяин применяет свой NAT-тип: обновляем только сокет, а nodeinfo
|
|
|
|
|
перестраивается и переподписывается штатно через topo_node_update_my_addresses. */ |
|
|
|
|
(void)group; |
|
|
|
|
struct ETCP_SOCKET* es = nd->inst->etcp_sockets; |
|
|
|
|
while (es) { |
|
|
|
|
if (es->sock_id == socket_id) { |
|
|
|
|
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr; |
|
|
|
|
nat_sin->sin_family = AF_INET; |
|
|
|
|
nat_sin->sin_addr.s_addr = nat_ip; |
|
|
|
|
nat_sin->sin_port = htons(nat_port); |
|
|
|
|
es->nat_type = verified_type; |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "NAT_INFO socket=%s id=%d type=%d addr=%s:%u", |
|
|
|
|
es->name, socket_id, verified_type, |
|
|
|
|
ip_to_str(&nat_ip, AF_INET).str, nat_port); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
es = es->next; |
|
|
|
|
} |
|
|
|
|
if (nd->inst->topo_groups) |
|
|
|
|
topo_node_update_my_addresses(nd->inst); |
|
|
|
|
|
|
|
|
|
struct ETCP_LINK* l = from_conn->links; |
|
|
|
|
while (l) { l->nat_type = info->nat_type; l = l->next; } |
|
|
|
|
|