Measure owned endpoint mapping and inbound reachability separately
This commit is contained in:
1 parent
b54307a0df
commit
ff69552a61
51 files changed
+2620
-2483
No files matched your search
+116
-34
@@ -91,7 +91,10 @@ void topo_node_apply_reality(struct ETCP_LINK* link, const struct TOPO_REALITY_S
|
||||
prepend даёт одинаковый порядок при неизменном наборе сокетов). */
|
||||
static int sockmeta4_list_equal(struct TOPO_SOCKMETA4* a, struct TOPO_SOCKMETA4* b) {
|
||||
while (a && b) {
|
||||
if (a->id != b->id || a->config_type != b->config_type || a->nat_type != b->nat_type) return 0;
|
||||
if (a->id != b->id || a->config_type != b->config_type ||
|
||||
a->address_profile.mapping != b->address_profile.mapping || a->address_profile.inbound != b->address_profile.inbound ||
|
||||
a->address_profile.evidence_id != b->address_profile.evidence_id || a->address_profile.checked_at != b->address_profile.checked_at)
|
||||
return 0;
|
||||
a = a->next; b = b->next;
|
||||
}
|
||||
return a == NULL && b == NULL;
|
||||
@@ -106,7 +109,10 @@ static int addr4_list_equal(struct TOPO_ADDR4* a, struct TOPO_ADDR4* b) {
|
||||
}
|
||||
static int sockmeta6_list_equal(struct TOPO_SOCKMETA6* a, struct TOPO_SOCKMETA6* b) {
|
||||
while (a && b) {
|
||||
if (a->id != b->id || a->config_type != b->config_type || a->nat_type != b->nat_type) return 0;
|
||||
if (a->id != b->id || a->config_type != b->config_type ||
|
||||
a->address_profile.mapping != b->address_profile.mapping || a->address_profile.inbound != b->address_profile.inbound ||
|
||||
a->address_profile.evidence_id != b->address_profile.evidence_id || a->address_profile.checked_at != b->address_profile.checked_at)
|
||||
return 0;
|
||||
a = a->next; b = b->next;
|
||||
}
|
||||
return a == NULL && b == NULL;
|
||||
@@ -339,6 +345,24 @@ void topo_node_registry_unref(struct TOPO_GROUPS* groups, uint64_t node_id) {
|
||||
|
||||
// ===== serialization =====
|
||||
|
||||
static void sockmeta_wire_write(uint8_t *out, uint8_t id, uint8_t config, const struct address_profile *profile) {
|
||||
out[0] = id; out[1] = config; out[2] = profile->mapping; out[3] = profile->inbound;
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
out[4 + i] = (uint8_t)(profile->evidence_id >> (56 - i * 8));
|
||||
out[12 + i] = (uint8_t)(profile->checked_at >> (56 - i * 8));
|
||||
}
|
||||
}
|
||||
|
||||
static int sockmeta_wire_read(const uint8_t *in, struct address_profile *profile) {
|
||||
memset(profile, 0, sizeof(*profile)); profile->mapping = in[2]; profile->inbound = in[3];
|
||||
for (unsigned i = 0; i < 8; i++) {
|
||||
profile->evidence_id = (profile->evidence_id << 8) | in[4 + i];
|
||||
profile->checked_at = (profile->checked_at << 8) | in[12 + i];
|
||||
}
|
||||
if (!address_profile_valid(profile)) { DEBUG_WARN(DEBUG_CATEGORY_BGP, "invalid address profile in NODEINFO"); return -1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Собирает канонический буфер для Ed25519-подписи узла (id, ver, pubkey, имя, тип, адреса). */
|
||||
int topo_node_build_sig_msg(struct TOPO_NODE* ni, uint8_t* buf, size_t buf_size) {
|
||||
if (!ni || !buf || buf_size < 64 + 9) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "build_sig_msg: invalid args"); return -1; }
|
||||
@@ -356,13 +380,24 @@ int topo_node_build_sig_msg(struct TOPO_NODE* ni, uint8_t* buf, size_t buf_size)
|
||||
if (name_len) { memcpy(buf + off, ni->node_name, name_len); off += name_len; }
|
||||
buf[off++] = '\0';
|
||||
|
||||
if (off + 2 > buf_size) return -1;
|
||||
if (off + 7 > buf_size) return -1;
|
||||
buf[off++] = ni->client_type;
|
||||
buf[off++] = ni->client_activity;
|
||||
/* Границы списков тоже подписаны: нельзя переразбить то же тело на другие секции. */
|
||||
int counts[] = {topo_list_count((struct _topo_head *)ni->v4_sock_meta), topo_list_count((struct _topo_head *)ni->v4_addrs),
|
||||
topo_list_count((struct _topo_head *)ni->v6_sock_meta), topo_list_count((struct _topo_head *)ni->v6_addrs),
|
||||
topo_list_count((struct _topo_head *)ni->reality_socks)};
|
||||
for (unsigned i = 0; i < sizeof(counts) / sizeof(counts[0]); i++) {
|
||||
if (counts[i] > UINT8_MAX) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "signed node section exceeds wire limits"); return -1; }
|
||||
buf[off++] = (uint8_t)counts[i];
|
||||
}
|
||||
|
||||
{ struct TOPO_SOCKMETA4* e = ni->v4_sock_meta; while (e) {
|
||||
if (off + 3 > buf_size) return -1;
|
||||
buf[off++] = e->id; buf[off++] = e->config_type; buf[off++] = e->nat_type; e = e->next;
|
||||
if (off + sizeof(struct TOPOMSG_SOCKMETA4) > buf_size || !address_profile_valid(&e->address_profile)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid/oversized v4 socket profile"); return -1;
|
||||
}
|
||||
sockmeta_wire_write(buf + off, e->id, e->config_type, &e->address_profile);
|
||||
off += sizeof(struct TOPOMSG_SOCKMETA4); e = e->next;
|
||||
}}
|
||||
{ struct TOPO_ADDR4* e = ni->v4_addrs; while (e) {
|
||||
if (off + 9 > buf_size) return -1;
|
||||
@@ -371,8 +406,11 @@ int topo_node_build_sig_msg(struct TOPO_NODE* ni, uint8_t* buf, size_t buf_size)
|
||||
buf[off++] = e->type; buf[off++] = e->socket_id; buf[off++] = e->protocol; e = e->next;
|
||||
}}
|
||||
{ struct TOPO_SOCKMETA6* e = ni->v6_sock_meta; while (e) {
|
||||
if (off + 3 > buf_size) return -1;
|
||||
buf[off++] = e->id; buf[off++] = e->config_type; buf[off++] = e->nat_type; e = e->next;
|
||||
if (off + sizeof(struct TOPOMSG_SOCKMETA6) > buf_size || !address_profile_valid(&e->address_profile)) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "invalid/oversized v6 socket profile"); return -1;
|
||||
}
|
||||
sockmeta_wire_write(buf + off, e->id, e->config_type, &e->address_profile);
|
||||
off += sizeof(struct TOPOMSG_SOCKMETA6); e = e->next;
|
||||
}}
|
||||
{ struct TOPO_ADDR6* e = ni->v6_addrs; while (e) {
|
||||
if (off + 21 > buf_size) return -1;
|
||||
@@ -504,16 +542,16 @@ int topo_node_serialize(struct TOPO_NODE* ni, struct TOPO_GROUP_NODE* nq,
|
||||
if (msg.node_name_len) { memcpy(dp, ni->node_name, msg.node_name_len); dp += msg.node_name_len; }
|
||||
|
||||
{ struct TOPO_SOCKMETA4* e = ni->v4_sock_meta; while (e) {
|
||||
struct TOPOMSG_SOCKMETA4 w = { .id=e->id, .config_type=e->config_type, .nat_type=e->nat_type };
|
||||
memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
|
||||
sockmeta_wire_write(dp, e->id, e->config_type, &e->address_profile);
|
||||
dp += sizeof(struct TOPOMSG_SOCKMETA4); e = e->next;
|
||||
}}
|
||||
{ struct TOPO_ADDR4* e = ni->v4_addrs; while (e) {
|
||||
struct TOPOMSG_ADDR4 w = { .port=e->port, .type=e->type, .socket_id=e->socket_id, .protocol=e->protocol };
|
||||
memcpy(w.addr, e->addr, 4); memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
|
||||
}}
|
||||
{ struct TOPO_SOCKMETA6* e = ni->v6_sock_meta; while (e) {
|
||||
struct TOPOMSG_SOCKMETA6 w = { .id=e->id, .config_type=e->config_type, .nat_type=e->nat_type };
|
||||
memcpy(dp, &w, sizeof(w)); dp += sizeof(w); e = e->next;
|
||||
sockmeta_wire_write(dp, e->id, e->config_type, &e->address_profile);
|
||||
dp += sizeof(struct TOPOMSG_SOCKMETA6); e = e->next;
|
||||
}}
|
||||
{ struct TOPO_ADDR6* e = ni->v6_addrs; while (e) {
|
||||
struct TOPOMSG_ADDR6 w = { .port=e->port, .type=e->type, .socket_id=e->socket_id, .protocol=e->protocol };
|
||||
@@ -582,7 +620,11 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
|
||||
const struct TOPOMSG_SOCKMETA4* w = (const struct TOPOMSG_SOCKMETA4*)dp; dp += sizeof(*w);
|
||||
struct TOPO_SOCKMETA4* e = memory_pool_alloc(group->instance->topo_groups->v4_sock_meta_pool);
|
||||
if (!e) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
|
||||
e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type; e->next = NULL;
|
||||
e->id = w->id; e->config_type = w->config_type; e->next = NULL;
|
||||
if (sockmeta_wire_read((const uint8_t *)w, &e->address_profile)) {
|
||||
memory_pool_free(group->instance->topo_groups->v4_sock_meta_pool, e);
|
||||
ni->v4_sock_meta = head; topo_node_free_raw(group->instance->topo_groups, ni); return -1;
|
||||
}
|
||||
if (!head) head = tail = e; else { tail->next = e; tail = e; }
|
||||
}
|
||||
ni->v4_sock_meta = head; }
|
||||
@@ -600,7 +642,11 @@ int topo_node_deserialize(struct TOPO_GROUP* group, const uint8_t* data, size_t
|
||||
const struct TOPOMSG_SOCKMETA6* w = (const struct TOPOMSG_SOCKMETA6*)dp; dp += sizeof(*w);
|
||||
struct TOPO_SOCKMETA6* e = memory_pool_alloc(group->instance->topo_groups->v6_sock_meta_pool);
|
||||
if (!e) { topo_node_free_raw(group->instance->topo_groups, ni); return -1; }
|
||||
e->id = w->id; e->config_type = w->config_type; e->nat_type = w->nat_type; e->next = NULL;
|
||||
e->id = w->id; e->config_type = w->config_type; e->next = NULL;
|
||||
if (sockmeta_wire_read((const uint8_t *)w, &e->address_profile)) {
|
||||
memory_pool_free(group->instance->topo_groups->v6_sock_meta_pool, e);
|
||||
ni->v6_sock_meta = head; topo_node_free_raw(group->instance->topo_groups, ni); return -1;
|
||||
}
|
||||
if (!head) head = tail = e; else { tail->next = e; tail = e; }
|
||||
}
|
||||
ni->v6_sock_meta = head; }
|
||||
@@ -784,7 +830,10 @@ void topo_node_dump_all(struct TOPO_GROUP* group) {
|
||||
|
||||
int si = 0;
|
||||
{ struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; while (sm) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sock[%d]: id=%u config=%u nat=%u", si++, sm->id, sm->config_type, sm->nat_type);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v4sock[%d]: id=%u config=%u mapping=%s inbound=%s evidence=%016llx checked=%llu",
|
||||
si++, sm->id, sm->config_type, address_mapping_name(sm->address_profile.mapping),
|
||||
address_inbound_name(sm->address_profile.inbound), (unsigned long long)sm->address_profile.evidence_id,
|
||||
(unsigned long long)sm->address_profile.checked_at);
|
||||
sm = sm->next;
|
||||
}}
|
||||
{ const char* atn[] = {"INTERFACE","NAT","REAL"};
|
||||
@@ -795,7 +844,10 @@ void topo_node_dump_all(struct TOPO_GROUP* group) {
|
||||
a = a->next;
|
||||
}}
|
||||
{ int si6 = 0; struct TOPO_SOCKMETA6* sm6 = ni->v6_sock_meta; while (sm6) {
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sock[%d]: id=%u config=%u nat=%u", si6++, sm6->id, sm6->config_type, sm6->nat_type);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_BGP, " v6sock[%d]: id=%u config=%u mapping=%s inbound=%s evidence=%016llx checked=%llu",
|
||||
si6++, sm6->id, sm6->config_type, address_mapping_name(sm6->address_profile.mapping),
|
||||
address_inbound_name(sm6->address_profile.inbound), (unsigned long long)sm6->address_profile.evidence_id,
|
||||
(unsigned long long)sm6->address_profile.checked_at);
|
||||
sm6 = sm6->next;
|
||||
}}
|
||||
{ int ai6 = 0; struct TOPO_ADDR6* a6 = ni->v6_addrs; while (a6) {
|
||||
@@ -875,7 +927,9 @@ int topo_node_format_all(struct TOPO_GROUP* group, char* buf, size_t buf_size) {
|
||||
FMT_ADD(" ed25519: "); for (int k = 0; k < SC_PUBKEY_SIZE; k++) FMT_ADD("%02x", ni->ed25519_public_key[k]); FMT_ADD("\n");
|
||||
|
||||
{ struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; int si = 0; while (sm) {
|
||||
FMT_ADD(" v4sock[%d]: id=%u config=%u nat=%u\n", si++, sm->id, sm->config_type, sm->nat_type); sm = sm->next;
|
||||
FMT_ADD(" v4sock[%d]: id=%u config=%u mapping=%s inbound=%s checked=%llu\n", si++, sm->id, sm->config_type,
|
||||
address_mapping_name(sm->address_profile.mapping), address_inbound_name(sm->address_profile.inbound),
|
||||
(unsigned long long)sm->address_profile.checked_at); sm = sm->next;
|
||||
}}
|
||||
{ const char* atn[] = {"INTERFACE","NAT","REAL"}; struct TOPO_ADDR4* a = ni->v4_addrs; int ai = 0; while (a) {
|
||||
const char* proto = (a->protocol & TOPO_PROTO_REALITY) ? "tcp+reality" : (a->protocol & TOPO_PROTO_TCP) ? "tcp" : (a->protocol & TOPO_PROTO_UDP) ? "udp" : "?";
|
||||
@@ -884,7 +938,9 @@ int topo_node_format_all(struct TOPO_GROUP* group, char* buf, size_t buf_size) {
|
||||
a = a->next;
|
||||
}}
|
||||
{ struct TOPO_SOCKMETA6* sm6 = ni->v6_sock_meta; int s6i = 0; while (sm6) {
|
||||
FMT_ADD(" v6sock[%d]: id=%u config=%u nat=%u\n", s6i++, sm6->id, sm6->config_type, sm6->nat_type); sm6 = sm6->next;
|
||||
FMT_ADD(" v6sock[%d]: id=%u config=%u mapping=%s inbound=%s checked=%llu\n", s6i++, sm6->id, sm6->config_type,
|
||||
address_mapping_name(sm6->address_profile.mapping), address_inbound_name(sm6->address_profile.inbound),
|
||||
(unsigned long long)sm6->address_profile.checked_at); sm6 = sm6->next;
|
||||
}}
|
||||
{ struct TOPO_ADDR6* a6 = ni->v6_addrs; int a6i = 0; while (a6) {
|
||||
const char* proto = (a6->protocol & TOPO_PROTO_REALITY) ? "tcp+reality" : (a6->protocol & TOPO_PROTO_TCP) ? "tcp" : (a6->protocol & TOPO_PROTO_UDP) ? "udp" : "?";
|
||||
@@ -1098,11 +1154,12 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
|
||||
struct ETCP_SOCKET* e_sock = instance->etcp_sockets;
|
||||
while (e_sock) {
|
||||
if (e_sock->is_tcp) { e_sock = e_sock->next; continue; }
|
||||
if (e_sock->is_tcp || e_sock->probe_only) { e_sock = e_sock->next; continue; }
|
||||
if (e_sock->type == CFG_SERVER_TYPE_PRIVATE) { e_sock = e_sock->next; continue; } /* private скрыт, LOCAL рекламируем (LAN) */
|
||||
if (e_sock->local_addr.ss_family == AF_INET) {
|
||||
{ struct TOPO_SOCKMETA4* sm = memory_pool_alloc(instance->topo_groups->v4_sock_meta_pool);
|
||||
sm->id = e_sock->sock_id; sm->config_type = e_sock->type; sm->nat_type = e_sock->nat_type;
|
||||
if (!sm) goto allocation_failed;
|
||||
sm->id = e_sock->sock_id; sm->config_type = e_sock->type; sm->address_profile = e_sock->address_profile;
|
||||
sm->next = m4_head; m4_head = sm; }
|
||||
struct sockaddr_in* local_sin = (struct sockaddr_in*)&e_sock->local_addr;
|
||||
struct sockaddr_in* if_sin = (struct sockaddr_in*)&e_sock->interface_addr;
|
||||
@@ -1112,17 +1169,17 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
uint32_t pre_ip = use_local ? local_sin->sin_addr.s_addr : if_sin->sin_addr.s_addr;
|
||||
uint16_t pre_port = ntohs(use_local ? local_sin->sin_port : if_sin->sin_port);
|
||||
{ struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
|
||||
if (!a) goto allocation_failed;
|
||||
memcpy(a->addr, &pre_ip, 4); a->port = pre_port;
|
||||
a->type = TOPO_ADDR_INTERFACE; a->socket_id = e_sock->sock_id;
|
||||
a->protocol = TOPO_PROTO_UDP;
|
||||
a->next = v4_head; v4_head = a; }
|
||||
/* адрес ПОСЛЕ NAT — дополнительно, если NAT определён (EIM) и есть интернет.
|
||||
DIRECT (nat==интерфейс), STRICT и оффлайн не рекламируем отдельным адресом. */
|
||||
if (instance->ntp.reachable
|
||||
&& e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0
|
||||
&& e_sock->nat_type != NAT_VERIFIED_STRICT
|
||||
&& e_sock->nat_type != NAT_VERIFIED_DIRECT) {
|
||||
/* Общий внешний адрес публикует только владелец после наблюдений EIM.
|
||||
Наличие ответа интернет-NTP не связано с работоспособностью этого endpoint. */
|
||||
if (e_sock->nat_addr.ss_family == AF_INET && nat_sin->sin_addr.s_addr != 0 &&
|
||||
e_sock->address_profile.mapping == ADDRESS_MAP_EIM) {
|
||||
struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
|
||||
if (!a) goto allocation_failed;
|
||||
memcpy(a->addr, &nat_sin->sin_addr.s_addr, 4); a->port = ntohs(nat_sin->sin_port);
|
||||
a->type = TOPO_ADDR_NAT; a->socket_id = e_sock->sock_id;
|
||||
a->protocol = TOPO_PROTO_UDP;
|
||||
@@ -1130,13 +1187,23 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
}
|
||||
} else if (e_sock->local_addr.ss_family == AF_INET6) {
|
||||
{ struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(instance->topo_groups->v6_sock_meta_pool);
|
||||
sm6->id = e_sock->sock_id; sm6->config_type = e_sock->type; sm6->nat_type = e_sock->nat_type;
|
||||
if (!sm6) goto allocation_failed;
|
||||
sm6->id = e_sock->sock_id; sm6->config_type = e_sock->type; sm6->address_profile = e_sock->address_profile;
|
||||
sm6->next = m6_head; m6_head = sm6; }
|
||||
struct sockaddr_in6* if_sin6 = (struct sockaddr_in6*)&e_sock->interface_addr;
|
||||
{ struct TOPO_ADDR6* a6 = memory_pool_alloc(instance->topo_groups->v6_addr_pool);
|
||||
if (!a6) goto allocation_failed;
|
||||
memcpy(a6->addr, &if_sin6->sin6_addr, 16); a6->port = ntohs(if_sin6->sin6_port);
|
||||
a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = e_sock->sock_id; a6->protocol = TOPO_PROTO_UDP;
|
||||
a6->next = v6_head; v6_head = a6; }
|
||||
if (e_sock->nat_addr.ss_family == AF_INET6 && e_sock->address_profile.mapping == ADDRESS_MAP_EIM) {
|
||||
const struct sockaddr_in6 *mapped = (const struct sockaddr_in6 *)&e_sock->nat_addr;
|
||||
struct TOPO_ADDR6 *a6 = memory_pool_alloc(instance->topo_groups->v6_addr_pool);
|
||||
if (!a6) goto allocation_failed;
|
||||
memcpy(a6->addr, &mapped->sin6_addr, 16); a6->port = ntohs(mapped->sin6_port);
|
||||
a6->type = TOPO_ADDR_NAT; a6->socket_id = e_sock->sock_id; a6->protocol = TOPO_PROTO_UDP;
|
||||
a6->next = v6_head; v6_head = a6;
|
||||
}
|
||||
}
|
||||
e_sock = e_sock->next;
|
||||
}
|
||||
@@ -1150,25 +1217,29 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
if (addr->ss_family == AF_INET) {
|
||||
struct sockaddr_in* sin = (struct sockaddr_in*)addr;
|
||||
{ struct TOPO_SOCKMETA4* sm = memory_pool_alloc(instance->topo_groups->v4_sock_meta_pool);
|
||||
sm->id = ts->sock_id; sm->config_type = ts->type; sm->nat_type = ts->nat_type;
|
||||
if (!sm) goto allocation_failed;
|
||||
sm->id = ts->sock_id; sm->config_type = ts->type; sm->address_profile = ts->address_profile;
|
||||
sm->next = m4_head; m4_head = sm; }
|
||||
{ struct TOPO_ADDR4* a = memory_pool_alloc(instance->topo_groups->v4_addr_pool);
|
||||
if (!a) goto allocation_failed;
|
||||
memcpy(a->addr, &sin->sin_addr.s_addr, 4); a->port = ntohs(sin->sin_port);
|
||||
a->type = TOPO_ADDR_INTERFACE; a->socket_id = ts->sock_id; a->protocol = proto;
|
||||
a->next = v4_head; v4_head = a; }
|
||||
} else if (addr->ss_family == AF_INET6) {
|
||||
struct sockaddr_in6* sin6 = (struct sockaddr_in6*)addr;
|
||||
{ struct TOPO_SOCKMETA6* sm6 = memory_pool_alloc(instance->topo_groups->v6_sock_meta_pool);
|
||||
sm6->id = ts->sock_id; sm6->config_type = ts->type; sm6->nat_type = ts->nat_type;
|
||||
if (!sm6) goto allocation_failed;
|
||||
sm6->id = ts->sock_id; sm6->config_type = ts->type; sm6->address_profile = ts->address_profile;
|
||||
sm6->next = m6_head; m6_head = sm6; }
|
||||
{ struct TOPO_ADDR6* a6 = memory_pool_alloc(instance->topo_groups->v6_addr_pool);
|
||||
if (!a6) goto allocation_failed;
|
||||
memcpy(a6->addr, &sin6->sin6_addr, 16); a6->port = ntohs(sin6->sin6_port);
|
||||
a6->type = TOPO_ADDR_INTERFACE; a6->socket_id = ts->sock_id; a6->protocol = proto;
|
||||
a6->next = v6_head; v6_head = a6; }
|
||||
}
|
||||
if (is_reality) {
|
||||
struct TOPO_REALITY_SOCK* r = u_calloc(1, sizeof(struct TOPO_REALITY_SOCK));
|
||||
if (!r) { DEBUG_ERROR(DEBUG_CATEGORY_BGP, "reality_sock alloc failed"); }
|
||||
if (!r) goto allocation_failed;
|
||||
else {
|
||||
r->socket_id = ts->sock_id;
|
||||
memcpy(r->short_id, r_short_id, 8);
|
||||
@@ -1217,14 +1288,17 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "my addresses unchanged (ver=%d), persist DB", ni->ver);
|
||||
}
|
||||
|
||||
int database_failed = 0;
|
||||
/* всегда: адреса (addrs_put) + классификация node_type/storage (nodeinfo_updated) */
|
||||
if (instance->topo_sqlite_db) {
|
||||
time_t now_sec = ntp_time_get_seconds(instance);
|
||||
topo_node_sqlite_node_update_verified(instance->topo_sqlite_db, instance->node_id,
|
||||
if (topo_node_sqlite_node_update_verified(instance->topo_sqlite_db, instance->node_id,
|
||||
instance->name, instance->my_keys.public_key, instance->my_ed25519_pubkey,
|
||||
(uint64_t)now_sec, now_sec);
|
||||
topo_node_sqlite_addrs_put(instance->topo_sqlite_db, instance->node_id, ni);
|
||||
topo_node_sqlite_nodeinfo_updated(instance->topo_sqlite_db, instance->node_id);
|
||||
(uint64_t)now_sec, now_sec) < 0 ||
|
||||
topo_node_sqlite_addrs_put(instance->topo_sqlite_db, instance->node_id, ni) < 0 ||
|
||||
topo_node_sqlite_nodeinfo_updated(instance->topo_sqlite_db, instance->node_id) < 0) {
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "local address projection update failed"); database_failed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
@@ -1244,7 +1318,15 @@ int topo_node_update_my_addresses(struct UTUN_INSTANCE* instance) {
|
||||
ge = ge->next;
|
||||
}
|
||||
}
|
||||
return changed ? 1 : 0;
|
||||
return database_failed ? -1 : changed ? 1 : 0;
|
||||
allocation_failed:
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "local address snapshot allocation failed");
|
||||
free_v4_sock_list(instance->topo_groups->v4_sock_meta_pool, m4_head);
|
||||
free_v4_addr_list(instance->topo_groups->v4_addr_pool, v4_head);
|
||||
free_v6_sock_list(instance->topo_groups->v6_sock_meta_pool, m6_head);
|
||||
free_v6_addr_list(instance->topo_groups->v6_addr_pool, v6_head);
|
||||
free_reality_sock_list(r_head);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Callback изменения сокета (адрес/статус) — инициирует пересборку адресов своего узла. */
|
||||
|
||||
Reference in new issue
Block a user