Browse Source

nat_detection: применять NAT-тип через topo_node_update_my_addresses с переподписью

v2
evgeny 4 weeks ago
parent
commit
f7c08f8f5e
  1. 107
      src/routing_layer/nat_detection.c

107
src/routing_layer/nat_detection.c

@ -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 if (info->nat_type == NAT_TYPE_DIRECT) verified_type = NAT_VERIFIED_DIRECT;
else verified_type = NAT_VERIFIED_UNKNOWN; else verified_type = NAT_VERIFIED_UNKNOWN;
if (group && group->local_node) { /* Хозяин применяет свой NAT-тип: обновляем только сокет, а nodeinfo
struct TOPO_NODE* ni = topo_node_registry_find(group->instance->topo_groups, group->local_node->node_id); перестраивается и переподписывается штатно через topo_node_update_my_addresses. */
if (!ni) return; (void)group;
int data_changed = 0; struct ETCP_SOCKET* es = nd->inst->etcp_sockets;
struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; while (es) {
while (sm) { if (es->sock_id == socket_id) {
if (sm->id == socket_id) { struct sockaddr_in* nat_sin = (struct sockaddr_in*)&es->nat_addr;
if (sm->nat_type != verified_type) { sm->nat_type = verified_type; data_changed = 1; } nat_sin->sin_family = AF_INET;
break; nat_sin->sin_addr.s_addr = nat_ip;
} nat_sin->sin_port = htons(nat_port);
sm = sm->next; 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,
struct ETCP_SOCKET* es = group->instance->etcp_sockets; ip_to_str(&nat_ip, AF_INET).str, nat_port);
while (es) { break;
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;
} }
es = es->next;
} }
if (nd->inst->topo_groups)
topo_node_update_my_addresses(nd->inst);
struct ETCP_LINK* l = from_conn->links; struct ETCP_LINK* l = from_conn->links;
while (l) { l->nat_type = info->nat_type; l = l->next; } while (l) { l->nat_type = info->nat_type; l = l->next; }

Loading…
Cancel
Save