db_sync: fix bad_sig infinite loop — delete+rechain, advance synced_pos past dup/bad_sig, accept on covered tail
This commit is contained in:
1 parent
27906e9f91
commit
e9fce43be5
1 file changed
+23
-3
+23
-3
@@ -429,7 +429,18 @@ static int db_record_insert(struct DB_SYNC_INSTANCE* si,
|
||||
int rc;
|
||||
|
||||
// Verify author signature (mandatory)
|
||||
if (db_verify_author_sig(si, ts, author_node_id, json, jlen, author_sig) != 0) return -2;
|
||||
if (db_verify_author_sig(si, ts, author_node_id, json, jlen, author_sig) != 0) {
|
||||
sqlite3_stmt* del;
|
||||
if (si_prep(si, &del, "DELETE FROM \"%s\" WHERE timestamp=? AND author_signature=?") == SQLITE_OK) {
|
||||
sqlite3_bind_int64(del, 1, (sqlite3_int64)ts);
|
||||
sqlite3_bind_blob(del, 2, author_sig, DB_SIG_SIZE, SQLITE_STATIC);
|
||||
sqlite3_step(del);
|
||||
int chg = sqlite3_changes(SI_DB(si));
|
||||
sqlite3_finalize(del);
|
||||
if (chg > 0) db_cascade_from(si, si_find_pos(si, ts, author_sig));
|
||||
}
|
||||
return -2;
|
||||
}
|
||||
|
||||
rc = sqlite3_exec(db, "BEGIN IMMEDIATE", NULL, NULL, NULL);
|
||||
if (rc != SQLITE_OK) { DEBUG_ERROR(DEBUG_CATEGORY_DB_SYNC, "insert BEGIN: %s", sqlite3_errmsg(db)); return -1; }
|
||||
@@ -905,10 +916,12 @@ static void db_handle_send_data(struct DB_SYNC_INSTANCE* si, uint64_t src, const
|
||||
if (ret == 0 && si->on_insert) si->on_insert(si, rts, (const char*)rdata, rdlen, src, si->on_insert_arg);
|
||||
}
|
||||
|
||||
if (received > 0) {
|
||||
uint16_t total_processed = received + duplicates + bad_sigs;
|
||||
|
||||
if (total_processed > 0) {
|
||||
uint32_t rst = (from < old_synced_pos) ? from : old_synced_pos;
|
||||
db_cascade_range(si, rst, from + received);
|
||||
if (sp) sp->synced_pos = from + received - 1;
|
||||
if (sp) sp->synced_pos = from + total_processed - 1;
|
||||
for (int j = 0; j < si->peer_count; j++) {
|
||||
if (si->peers[j].synced_pos >= rst && &si->peers[j] != sp)
|
||||
si->peers[j].synced_pos = rst > 0 ? rst - 1 : 0;
|
||||
@@ -1051,6 +1064,13 @@ static void db_handle_sync_done(struct DB_SYNC_INSTANCE* si, uint64_t src, const
|
||||
}
|
||||
|
||||
if (mc < pc) {
|
||||
if (sp && sp->synced_pos + 1 >= pc) {
|
||||
if (sp) { sp->synced_pos = pc - 1; sp->sync_state = 2; }
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC,
|
||||
"sync [%s:%04llX] ← SYNC_DONE: count diff my=%u peer=%u but synced=%u covers tail — accept",
|
||||
SI_SHRT(si), (unsigned long long)(src >> 16), mc, pc, sp ? sp->synced_pos : 0);
|
||||
return;
|
||||
}
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DB_SYNC,
|
||||
"sync [%s:%04llX] ← SYNC_DONE: count diff my=%u peer=%u — requesting tail from=%u",
|
||||
SI_SHRT(si), (unsigned long long)(src >> 16), mc, pc, mc);
|
||||
|
||||
Reference in new issue
Block a user