|
|
|
@ -106,24 +106,6 @@ int topo_node_sqlite_init(sqlite3* db) { |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static uint8_t collect_socket_ids(struct TOPO_NODE* ni, uint8_t* sock_ids) { |
|
|
|
|
|
|
|
uint8_t count = 0; |
|
|
|
|
|
|
|
struct TOPO_SOCKMETA4* sm4 = ni->v4_sock_meta; |
|
|
|
|
|
|
|
while (sm4) { |
|
|
|
|
|
|
|
uint8_t i; for (i = 0; i < count; i++) if (sock_ids[i] == sm4->id) break; |
|
|
|
|
|
|
|
if (i == count) sock_ids[count++] = sm4->id; |
|
|
|
|
|
|
|
if (count < 510) sock_ids[count++] = sm4->id | 1; /* NAT slave slot, LSB=1 */ |
|
|
|
|
|
|
|
sm4 = sm4->next; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
struct TOPO_SOCKMETA6* sm6 = ni->v6_sock_meta; |
|
|
|
|
|
|
|
while (sm6) { |
|
|
|
|
|
|
|
uint8_t i; for (i = 0; i < count; i++) if (sock_ids[i] == sm6->id) break; |
|
|
|
|
|
|
|
if (i == count) sock_ids[count++] = sm6->id; |
|
|
|
|
|
|
|
if (count < 510) sock_ids[count++] = sm6->id | 1; |
|
|
|
|
|
|
|
sm6 = sm6->next; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return count; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_GROUPS* groups, struct TOPO_GROUP_NODE* nq, time_t now_sec) { |
|
|
|
int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_GROUPS* groups, struct TOPO_GROUP_NODE* nq, time_t now_sec) { |
|
|
|
if (!db || !nq) return -1; |
|
|
|
if (!db || !nq) return -1; |
|
|
|
@ -149,162 +131,9 @@ int topo_node_sqlite_node_put(sqlite3* db, struct TOPO_GROUPS* groups, struct TO |
|
|
|
sqlite3_step(stmt); sqlite3_finalize(stmt); |
|
|
|
sqlite3_step(stmt); sqlite3_finalize(stmt); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* collect current socket_ids */ |
|
|
|
|
|
|
|
uint8_t sock_ids[510]; /* max: 255 v4 + 255 v6, enough */ |
|
|
|
|
|
|
|
uint8_t sock_count = collect_socket_ids(ni, sock_ids); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* delete stale addresses for socket_ids no longer present */ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
char del_sql[512]; |
|
|
|
|
|
|
|
if (sock_count > 0) { |
|
|
|
|
|
|
|
int pos = snprintf(del_sql, sizeof(del_sql), |
|
|
|
|
|
|
|
"DELETE FROM node_addresses WHERE node_id=? AND addr_type!=0 AND socket_id NOT IN ("); |
|
|
|
|
|
|
|
for (uint8_t i = 0; i < sock_count; i++) { |
|
|
|
|
|
|
|
if (i > 0) pos += snprintf(del_sql + pos, sizeof(del_sql) - (size_t)pos, ","); |
|
|
|
|
|
|
|
pos += snprintf(del_sql + pos, sizeof(del_sql) - (size_t)pos, "%d", (int)sock_ids[i]); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
pos += snprintf(del_sql + pos, sizeof(del_sql) - (size_t)pos, ") AND socket_id != 0"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
snprintf(del_sql, sizeof(del_sql), "DELETE FROM node_addresses WHERE node_id=? AND addr_type!=0 AND socket_id != 0"); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
sqlite3_stmt* del_stmt = NULL; |
|
|
|
|
|
|
|
if (sqlite3_prepare_v2(db, del_sql, -1, &del_stmt, NULL) == SQLITE_OK) { |
|
|
|
|
|
|
|
sqlite3_bind_int64(del_stmt, 1, (sqlite3_int64)ni->node_id); |
|
|
|
|
|
|
|
sqlite3_step(del_stmt); |
|
|
|
|
|
|
|
int deled = sqlite3_changes(db); |
|
|
|
|
|
|
|
if (deled > 0) |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "BGP: [ADDR_SYNC] topo_node_sqlite_node_put DELETE stale sock_ids node=0x%016llx sock_count=%d deleted=%d", |
|
|
|
|
|
|
|
(unsigned long long)ni->node_id, sock_count, deled); |
|
|
|
|
|
|
|
sqlite3_finalize(del_stmt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Удалить адреса других узлов, конфликтующие с адресами текущего */ |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
sqlite3_stmt* del_cfl = NULL; |
|
|
|
|
|
|
|
if (sqlite3_prepare_v2(db, |
|
|
|
|
|
|
|
"DELETE FROM node_addresses WHERE node_id != ?1 AND family = ?2 AND address = ?3 AND port = ?4 AND socket_id = ?5", |
|
|
|
|
|
|
|
-1, &del_cfl, NULL) == SQLITE_OK) { |
|
|
|
|
|
|
|
struct TOPO_ADDR4* a4 = ni->v4_addrs; |
|
|
|
|
|
|
|
while (a4) { |
|
|
|
|
|
|
|
sqlite3_bind_int64(del_cfl, 1, (sqlite3_int64)ni->node_id); |
|
|
|
|
|
|
|
sqlite3_bind_int(del_cfl, 2, 4); |
|
|
|
|
|
|
|
sqlite3_bind_blob(del_cfl, 3, a4->addr, 4, SQLITE_STATIC); |
|
|
|
|
|
|
|
sqlite3_bind_int(del_cfl, 4, a4->port); |
|
|
|
|
|
|
|
sqlite3_bind_int(del_cfl, 5, (int)a4->socket_id); |
|
|
|
|
|
|
|
sqlite3_step(del_cfl); |
|
|
|
|
|
|
|
if (sqlite3_changes(db) > 0) |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node_put: removed stale v4 addr %d.%d.%d.%d:%u sock=%d other_node nid=%016llx", |
|
|
|
|
|
|
|
a4->addr[0], a4->addr[1], a4->addr[2], a4->addr[3], a4->port, (int)a4->socket_id, |
|
|
|
|
|
|
|
(unsigned long long)ni->node_id); |
|
|
|
|
|
|
|
sqlite3_reset(del_cfl); |
|
|
|
|
|
|
|
a4 = a4->next; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
struct TOPO_ADDR6* a6 = ni->v6_addrs; |
|
|
|
|
|
|
|
while (a6) { |
|
|
|
|
|
|
|
if (a6->addr[0] == 0xFE && (a6->addr[1] & 0xC0) == 0x80) { a6 = a6->next; continue; } |
|
|
|
|
|
|
|
sqlite3_bind_int64(del_cfl, 1, (sqlite3_int64)ni->node_id); |
|
|
|
|
|
|
|
sqlite3_bind_int(del_cfl, 2, 6); |
|
|
|
|
|
|
|
sqlite3_bind_blob(del_cfl, 3, a6->addr, 16, SQLITE_STATIC); |
|
|
|
|
|
|
|
sqlite3_bind_int(del_cfl, 4, a6->port); |
|
|
|
|
|
|
|
sqlite3_bind_int(del_cfl, 5, (int)a6->socket_id); |
|
|
|
|
|
|
|
sqlite3_step(del_cfl); |
|
|
|
|
|
|
|
sqlite3_reset(del_cfl); |
|
|
|
|
|
|
|
a6 = a6->next; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
sqlite3_finalize(del_cfl); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
addr_stmt_beg: |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
int v4cnt = topo_list_count((struct _topo_head*)ni->v4_addrs); |
|
|
|
|
|
|
|
int v6cnt = topo_list_count((struct _topo_head*)ni->v6_addrs); |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node_put: nid=%016llx INSERT v4=%d v6=%d", |
|
|
|
|
|
|
|
(unsigned long long)ni->node_id, v4cnt, v6cnt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sqlite3_stmt* addr_stmt = NULL; |
|
|
|
|
|
|
|
if (sqlite3_prepare_v2(db, |
|
|
|
|
|
|
|
"INSERT INTO node_addresses(node_id, family, protocol, address, port, rtt, addr_type, socket_id)" |
|
|
|
|
|
|
|
" VALUES(?,?,?,?,?,?,?,?)", -1, &addr_stmt, NULL) == SQLITE_OK) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct TOPO_ADDR4* a4 = ni->v4_addrs; |
|
|
|
|
|
|
|
while (a4) { |
|
|
|
|
|
|
|
int at = ADDR_TYPE_NETIF; |
|
|
|
|
|
|
|
if (a4->type == TOPO_ADDR_NAT) { |
|
|
|
|
|
|
|
struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; |
|
|
|
|
|
|
|
while (sm) { if (sm->id == (a4->socket_id & ~1)) break; sm = sm->next; } |
|
|
|
|
|
|
|
if (sm && (sm->nat_type == NAT_TYPE_STRICT || sm->nat_type == NAT_VERIFIED_STRICT)) |
|
|
|
|
|
|
|
at = ADDR_TYPE_NAT_STRICT; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
at = ADDR_TYPE_NAT_EIM; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
struct TOPO_SOCKMETA4* sm = ni->v4_sock_meta; |
|
|
|
|
|
|
|
while (sm) { if (sm->id == a4->socket_id) break; sm = sm->next; } |
|
|
|
|
|
|
|
if (sm && (sm->nat_type == NAT_TYPE_DIRECT || sm->nat_type == NAT_VERIFIED_DIRECT)) |
|
|
|
|
|
|
|
at = ADDR_TYPE_DIRECT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sqlite3_bind_int64(addr_stmt, 1, (sqlite3_int64)ni->node_id); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 2, 4); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 3, a4->protocol); |
|
|
|
|
|
|
|
sqlite3_bind_blob(addr_stmt, 4, a4->addr, 4, SQLITE_STATIC); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 5, a4->port); |
|
|
|
|
|
|
|
sqlite3_bind_null(addr_stmt, 6); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 7, at); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 8, (int)a4->socket_id); |
|
|
|
|
|
|
|
sqlite3_step(addr_stmt); sqlite3_reset(addr_stmt); |
|
|
|
|
|
|
|
a4 = a4->next; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct TOPO_ADDR6* a6 = ni->v6_addrs; |
|
|
|
|
|
|
|
while (a6) { |
|
|
|
|
|
|
|
/* filter link-local IPv6 */ |
|
|
|
|
|
|
|
if (a6->addr[0] == 0xFE && (a6->addr[1] & 0xC0) == 0x80) { a6 = a6->next; continue; } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int at = ADDR_TYPE_NETIF; |
|
|
|
|
|
|
|
if (a6->type == TOPO_ADDR_NAT) { |
|
|
|
|
|
|
|
struct TOPO_SOCKMETA6* sm = ni->v6_sock_meta; |
|
|
|
|
|
|
|
while (sm) { if (sm->id == (a6->socket_id & ~1)) break; sm = sm->next; } |
|
|
|
|
|
|
|
if (sm && (sm->nat_type == NAT_TYPE_STRICT || sm->nat_type == NAT_VERIFIED_STRICT)) |
|
|
|
|
|
|
|
at = ADDR_TYPE_NAT_STRICT; |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
at = ADDR_TYPE_NAT_EIM; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
struct TOPO_SOCKMETA6* sm = ni->v6_sock_meta; |
|
|
|
|
|
|
|
while (sm) { if (sm->id == a6->socket_id) break; sm = sm->next; } |
|
|
|
|
|
|
|
if (sm && (sm->nat_type == NAT_TYPE_DIRECT || sm->nat_type == NAT_VERIFIED_DIRECT)) |
|
|
|
|
|
|
|
at = ADDR_TYPE_DIRECT; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sqlite3_bind_int64(addr_stmt, 1, (sqlite3_int64)ni->node_id); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 2, 6); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 3, a6->protocol); |
|
|
|
|
|
|
|
sqlite3_bind_blob(addr_stmt, 4, a6->addr, 16, SQLITE_STATIC); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 5, a6->port); |
|
|
|
|
|
|
|
sqlite3_bind_null(addr_stmt, 6); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 7, at); |
|
|
|
|
|
|
|
sqlite3_bind_int(addr_stmt, 8, (int)a6->socket_id); |
|
|
|
|
|
|
|
{ int rc = sqlite3_step(addr_stmt); |
|
|
|
|
|
|
|
if (rc != SQLITE_DONE && rc != SQLITE_OK) |
|
|
|
|
|
|
|
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "node_put: INSERT v6 FAILED nid=%016llx rc=%d err=%s", |
|
|
|
|
|
|
|
(unsigned long long)ni->node_id, rc, sqlite3_errmsg(db)); } |
|
|
|
|
|
|
|
sqlite3_reset(addr_stmt); |
|
|
|
|
|
|
|
a6 = a6->next; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
sqlite3_finalize(addr_stmt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL); |
|
|
|
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL); |
|
|
|
{ int total = 0; |
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node_put: nid=%016llx COMMITTED (nodes only, addrs via member_sync)", |
|
|
|
sqlite3_stmt* cnt_st; |
|
|
|
(unsigned long long)ni->node_id); |
|
|
|
if (sqlite3_prepare_v2(db, "SELECT count(*) FROM node_addresses WHERE node_id=?", -1, &cnt_st, NULL) == SQLITE_OK) { |
|
|
|
|
|
|
|
sqlite3_bind_int64(cnt_st, 1, (sqlite3_int64)ni->node_id); |
|
|
|
|
|
|
|
if (sqlite3_step(cnt_st) == SQLITE_ROW) total = sqlite3_column_int(cnt_st, 0); |
|
|
|
|
|
|
|
sqlite3_finalize(cnt_st); } |
|
|
|
|
|
|
|
DEBUG_INFO(DEBUG_CATEGORY_BGP, "node_put: nid=%016llx COMMITED total=%d", |
|
|
|
|
|
|
|
(unsigned long long)ni->node_id, total); } |
|
|
|
|
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|