|
|
|
|
@ -101,18 +101,15 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
|
|
|
|
|
struct CFG_ROUTE_ENTRY* s = instance->config->my_subnets; |
|
|
|
|
while (s) { if (s->ip.family == AF_INET) vc++; s = s->next; } |
|
|
|
|
|
|
|
|
|
// считаем сокеты и адреса
|
|
|
|
|
int sock_count = 0, addr_count = 0; |
|
|
|
|
struct ETCP_SOCKET* e_sock = instance->etcp_sockets; |
|
|
|
|
while (e_sock) { |
|
|
|
|
if (e_sock->local_addr.ss_family == AF_INET) { |
|
|
|
|
sock_count++; |
|
|
|
|
addr_count++; // INTERFACE
|
|
|
|
|
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr; |
|
|
|
|
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; |
|
|
|
|
if (e_sock->nat_addr.ss_family == AF_INET) { |
|
|
|
|
uint32_t nat_ip = nat_sin->sin_addr.s_addr; |
|
|
|
|
if (nat_ip != 0) { |
|
|
|
|
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; |
|
|
|
|
if (nat_sin->sin_addr.s_addr != 0) { |
|
|
|
|
if (e_sock->nat_type != NAT_VERIFIED_STRICT) addr_count++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
@ -122,8 +119,7 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
|
|
|
|
|
e_sock = e_sock->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
size_t dyn = name_len |
|
|
|
|
+ sock_count * sizeof(struct NODEINFO_IPV4_SOCKET_META) |
|
|
|
|
size_t dyn = name_len + sock_count * sizeof(struct NODEINFO_IPV4_SOCKET_META) |
|
|
|
|
+ addr_count * sizeof(struct NODEINFO_IPV4_ADDR) |
|
|
|
|
+ vc * sizeof(struct NODEINFO_IPV4_SUBNET); |
|
|
|
|
|
|
|
|
|
@ -136,8 +132,89 @@ int route_bgp_update_my_nodeinfo(struct UTUN_INSTANCE* instance, struct ROUTE_BG
|
|
|
|
|
|| (addr_count != (int)bgp->local_node->node.local_v4_addrs) |
|
|
|
|
|| (name_len != bgp->local_node->node.node_name_len) |
|
|
|
|
|| (memcmp(bgp->local_node->node.public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE) != 0); |
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "my_nodeinfo updated: socks=%d addrs=%d subnets=%d ver=%d", |
|
|
|
|
sock_count, addr_count, vc, bgp->local_node->node.ver); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "my_nodeinfo: node=%016llx changed=%d socks=%d->%d addrs=%d->%d", |
|
|
|
|
(unsigned long long)instance->node_id, changed, |
|
|
|
|
bgp->local_node ? bgp->local_node->node.local_v4_sockets : -1, sock_count, |
|
|
|
|
bgp->local_node ? bgp->local_node->node.local_v4_addrs : -1, addr_count); |
|
|
|
|
|
|
|
|
|
if (changed) { |
|
|
|
|
if (bgp->local_node) u_free(bgp->local_node); |
|
|
|
|
bgp->local_node = u_calloc(1, sizeof(struct NODEINFO_Q) + dyn); |
|
|
|
|
if (!bgp->local_node) return -1; |
|
|
|
|
bgp->local_node->node.node_id = instance->node_id; |
|
|
|
|
bgp->local_node->node.hop_count = 0; |
|
|
|
|
bgp->local_node->node.ver = (old_ver % 255) + 1; |
|
|
|
|
bgp->local_node->node.local_v4_sockets = sock_count; |
|
|
|
|
bgp->local_node->node.local_v4_addrs = addr_count; |
|
|
|
|
bgp->local_node->node.local_v4_subnets = vc; |
|
|
|
|
bgp->local_node->node.node_name_len = name_len; |
|
|
|
|
memcpy(bgp->local_node->node.public_key, instance->my_keys.public_key, SC_PUBKEY_SIZE); |
|
|
|
|
bgp->local_node->dirty = 1; |
|
|
|
|
bgp->local_node->last_ver = bgp->local_node->node.ver; |
|
|
|
|
|
|
|
|
|
uint8_t* dp = (uint8_t*)&bgp->local_node->node + sizeof(struct NODEINFO); |
|
|
|
|
if (name_len) { memcpy(dp, instance->name, name_len); dp += name_len; } |
|
|
|
|
|
|
|
|
|
struct NODEINFO_IPV4_SOCKET_META* meta = (struct NODEINFO_IPV4_SOCKET_META*)dp; |
|
|
|
|
e_sock = instance->etcp_sockets; |
|
|
|
|
int midx = 0; |
|
|
|
|
while (e_sock) { |
|
|
|
|
if (e_sock->local_addr.ss_family == AF_INET) { |
|
|
|
|
meta[midx].id = e_sock->sock_id; |
|
|
|
|
meta[midx].type = e_sock->nat_type; |
|
|
|
|
midx++; |
|
|
|
|
} |
|
|
|
|
e_sock = e_sock->next; |
|
|
|
|
} |
|
|
|
|
dp += sock_count * sizeof(struct NODEINFO_IPV4_SOCKET_META); |
|
|
|
|
|
|
|
|
|
struct NODEINFO_IPV4_ADDR* addrs = (struct NODEINFO_IPV4_ADDR*)dp; |
|
|
|
|
int aidx = 0; |
|
|
|
|
e_sock = instance->etcp_sockets; |
|
|
|
|
while (e_sock) { |
|
|
|
|
if (e_sock->local_addr.ss_family == AF_INET) { |
|
|
|
|
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr; |
|
|
|
|
struct sockaddr_in* nat_sin = (struct sockaddr_in*)&e_sock->nat_addr; |
|
|
|
|
|
|
|
|
|
memcpy(addrs[aidx].addr, &if_sin->sin_addr.s_addr, 4); |
|
|
|
|
addrs[aidx].port = ntohs(if_sin->sin_port); |
|
|
|
|
addrs[aidx].type = ADDR_TYPE_INTERFACE; |
|
|
|
|
addrs[aidx].socket_id = e_sock->sock_id; |
|
|
|
|
aidx++; |
|
|
|
|
|
|
|
|
|
if (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0) { |
|
|
|
|
if (e_sock->nat_type != NAT_VERIFIED_STRICT) { |
|
|
|
|
memcpy(addrs[aidx].addr, &nat_sin->sin_addr.s_addr, 4); |
|
|
|
|
addrs[aidx].port = ntohs(nat_sin->sin_port); |
|
|
|
|
addrs[aidx].type = ADDR_TYPE_NAT; |
|
|
|
|
addrs[aidx].socket_id = e_sock->sock_id; |
|
|
|
|
aidx++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (e_sock->nat_type == NAT_VERIFIED_DIRECT || |
|
|
|
|
(e_sock->type == CFG_SERVER_TYPE_PUBLIC && e_sock->nat_type < NAT_VERIFIED_UNKNOWN)) { |
|
|
|
|
memcpy(addrs[aidx].addr, &if_sin->sin_addr.s_addr, 4); |
|
|
|
|
addrs[aidx].port = ntohs(if_sin->sin_port); |
|
|
|
|
addrs[aidx].type = ADDR_TYPE_REAL; |
|
|
|
|
addrs[aidx].socket_id = e_sock->sock_id; |
|
|
|
|
aidx++; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
e_sock = e_sock->next; |
|
|
|
|
} |
|
|
|
|
dp += addr_count * sizeof(struct NODEINFO_IPV4_ADDR); |
|
|
|
|
|
|
|
|
|
struct NODEINFO_IPV4_SUBNET* ra = (struct NODEINFO_IPV4_SUBNET*)dp; |
|
|
|
|
s = instance->config->my_subnets; |
|
|
|
|
while (s) { |
|
|
|
|
if (s->ip.family == AF_INET) { memcpy(ra->addr, &s->ip.addr.v4, 4); ra->prefix_length = s->netmask; ra++; } |
|
|
|
|
s = s->next; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
DEBUG_WARN(DEBUG_CATEGORY_BGP, "my_nodeinfo updated: node=%016llx v4s=%d v4a=%d ver=%d", |
|
|
|
|
(unsigned long long)instance->node_id, sock_count, addr_count, bgp->local_node->node.ver); |
|
|
|
|
} else { |
|
|
|
|
bgp->local_node->last_ver = bgp->local_node->node.ver; |
|
|
|
|
} |
|
|
|
|
|