@@ -1282,26 +1282,32 @@ void BaseChatMesh::checkSessionKeyTimeouts() {
12821282
12831283 if (entry->retries_left > 0 ) {
12841284 // Retry: find the contact and resend INIT
1285+ ContactInfo* contact = nullptr ;
12851286 for (int j = 0 ; j < num_contacts; j++) {
12861287 if (memcmp (contacts[j].id .pub_key , entry->peer_pub_prefix , 4 ) == 0 ) {
1287- entry->retries_left --;
1288- entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1289-
1290- // Regenerate ephemeral keypair for retry
1291- uint8_t seed[SEED_SIZE ];
1292- getRNG ()->random (seed, SEED_SIZE );
1293- ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1294- memset (seed, 0 , SEED_SIZE );
1295-
1296- uint8_t req_data[1 + PUB_KEY_SIZE ];
1297- req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1298- memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1299-
1300- uint32_t tag, est_timeout;
1301- sendRequest (contacts[j], req_data, sizeof (req_data), tag, est_timeout);
1288+ contact = &contacts[j];
13021289 break ;
13031290 }
13041291 }
1292+ if (!contact) {
1293+ entry->retries_left = 0 ; // contact gone — fall through to cleanup on next tick
1294+ continue ;
1295+ }
1296+ entry->retries_left --;
1297+ entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1298+
1299+ // Regenerate ephemeral keypair for retry
1300+ uint8_t seed[SEED_SIZE ];
1301+ getRNG ()->random (seed, SEED_SIZE );
1302+ ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1303+ memset (seed, 0 , SEED_SIZE );
1304+
1305+ uint8_t req_data[1 + PUB_KEY_SIZE ];
1306+ req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1307+ memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1308+
1309+ uint32_t tag, est_timeout;
1310+ sendRequest (*contact, req_data, sizeof (req_data), tag, est_timeout);
13051311 } else {
13061312 // All retries exhausted — clean up
13071313 memset (entry->ephemeral_prv , 0 , PRV_KEY_SIZE );
0 commit comments