etcp: reset_id эпоха ресета — фикс потери NODEINFO при флапе
Добавлен 64-битный reset_id (эпоха ресета) в INIT-фреймы и STCP-handshake: - генерится один раз при создании conn, меняется только при фатальном ресете (normalizer desync / bad fragment size); - при приёме чужого id slave принимает эпоху пира и ресетится, master держит свою; - первый id принимается без ресета (свежие при init); - «tcp peer clean» реинит гейтится по смене id — нет повторного сброса seq. Это устраняет коллизию seq=1 (RX dup) из-за двойного реинита нескольких TCP-линков, из-за которой NODEINFO пира терялся и member не возвращался online. Также: chat member online теперь из topo_group (без БД/merkle), тест test_etcp_seq_collision.
This commit is contained in:
1 parent
f7c08f8f5e
commit
61c572cae4
29 files changed
+663
-385
No files matched your search
@@ -84,10 +84,18 @@ int topo_node_sqlite_addrs_put(sqlite3* db, uint64_t node_id, struct TOPO_NODE*
|
||||
sqlite3_exec(db, "BEGIN", NULL, NULL, NULL);
|
||||
|
||||
sqlite3_stmt* ds = NULL;
|
||||
int deleted = 0;
|
||||
if (sqlite3_prepare_v2(db, "DELETE FROM node_addresses WHERE node_id=?", -1, &ds, NULL) == SQLITE_OK) {
|
||||
sqlite3_bind_int64(ds, 1, (sqlite3_int64)node_id);
|
||||
sqlite3_step(ds);
|
||||
int drc = sqlite3_step(ds);
|
||||
deleted = sqlite3_changes(db);
|
||||
if (drc != SQLITE_DONE)
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "addrs_put: DELETE rc=%d (not DONE) node=%016llx: %s",
|
||||
drc, (unsigned long long)node_id, sqlite3_errmsg(db));
|
||||
sqlite3_finalize(ds);
|
||||
} else {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_BGP, "addrs_put: DELETE prepare failed node=%016llx: %s",
|
||||
(unsigned long long)node_id, sqlite3_errmsg(db));
|
||||
}
|
||||
|
||||
sqlite3_stmt* is = NULL;
|
||||
@@ -113,8 +121,9 @@ int topo_node_sqlite_addrs_put(sqlite3* db, uint64_t node_id, struct TOPO_NODE*
|
||||
sqlite3_bind_int(is, 8, (int)nat);
|
||||
sqlite3_bind_int(is, 9, (int)a->socket_id);
|
||||
if (sqlite3_step(is) != SQLITE_DONE)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "addrs_put: INSERT failed node=%016llx fam=4 sock=%d: %s",
|
||||
(unsigned long long)node_id, a->socket_id, sqlite3_errmsg(db));
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "addrs_put: INSERT failed node=%016llx fam=4 sock=%d at=%d cfg=%d nat=%d addr=%d.%d.%d.%d:%d: %s",
|
||||
(unsigned long long)node_id, a->socket_id, at, cfg, nat,
|
||||
a->addr[0], a->addr[1], a->addr[2], a->addr[3], a->port, sqlite3_errmsg(db));
|
||||
sqlite3_reset(is);
|
||||
written++;
|
||||
}
|
||||
@@ -132,16 +141,16 @@ int topo_node_sqlite_addrs_put(sqlite3* db, uint64_t node_id, struct TOPO_NODE*
|
||||
sqlite3_bind_int(is, 8, (int)nat);
|
||||
sqlite3_bind_int(is, 9, (int)a->socket_id);
|
||||
if (sqlite3_step(is) != SQLITE_DONE)
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "addrs_put: INSERT failed node=%016llx fam=6 sock=%d: %s",
|
||||
(unsigned long long)node_id, a->socket_id, sqlite3_errmsg(db));
|
||||
DEBUG_ERROR(DEBUG_CATEGORY_BGP, "addrs_put: INSERT failed node=%016llx fam=6 sock=%d at=%d cfg=%d nat=%d: %s",
|
||||
(unsigned long long)node_id, a->socket_id, at, cfg, nat, sqlite3_errmsg(db));
|
||||
sqlite3_reset(is);
|
||||
written++;
|
||||
}
|
||||
sqlite3_finalize(is);
|
||||
sqlite3_exec(db, "COMMIT", NULL, NULL, NULL);
|
||||
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "addrs_put: node=%016llx v4=%d v6=%d total=%d",
|
||||
(unsigned long long)node_id,
|
||||
DEBUG_DEBUG(DEBUG_CATEGORY_BGP, "addrs_put: node=%016llx deleted=%d v4=%d v6=%d written=%d",
|
||||
(unsigned long long)node_id, deleted,
|
||||
topo_list_count((struct _topo_head*)ni->v4_addrs),
|
||||
topo_list_count((struct _topo_head*)ni->v6_addrs), written);
|
||||
return 0;
|
||||
|
||||
Reference in new issue
Block a user