@@ -1361,26 +1361,32 @@ void BaseChatMesh::checkSessionKeyTimeouts() {
13611361
13621362 if (entry->retries_left > 0 ) {
13631363 // Retry: find the contact and resend INIT
1364+ ContactInfo* contact = nullptr ;
13641365 for (int j = 0 ; j < num_contacts; j++) {
13651366 if (memcmp (contacts[j].id .pub_key , entry->peer_pub_prefix , 4 ) == 0 ) {
1366- entry->retries_left --;
1367- entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1368-
1369- // Regenerate ephemeral keypair for retry
1370- uint8_t seed[SEED_SIZE ];
1371- getRNG ()->random (seed, SEED_SIZE );
1372- ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1373- memset (seed, 0 , SEED_SIZE );
1374-
1375- uint8_t req_data[1 + PUB_KEY_SIZE ];
1376- req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1377- memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1378-
1379- uint32_t tag, est_timeout;
1380- sendRequest (contacts[j], req_data, sizeof (req_data), tag, est_timeout);
1367+ contact = &contacts[j];
13811368 break ;
13821369 }
13831370 }
1371+ if (!contact) {
1372+ entry->retries_left = 0 ; // contact gone — fall through to cleanup on next tick
1373+ continue ;
1374+ }
1375+ entry->retries_left --;
1376+ entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1377+
1378+ // Regenerate ephemeral keypair for retry
1379+ uint8_t seed[SEED_SIZE ];
1380+ getRNG ()->random (seed, SEED_SIZE );
1381+ ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1382+ memset (seed, 0 , SEED_SIZE );
1383+
1384+ uint8_t req_data[1 + PUB_KEY_SIZE ];
1385+ req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1386+ memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1387+
1388+ uint32_t tag, est_timeout;
1389+ sendRequest (*contact, req_data, sizeof (req_data), tag, est_timeout);
13841390 } else {
13851391 // All retries exhausted — clean up
13861392 memset (entry->ephemeral_prv , 0 , PRV_KEY_SIZE );
0 commit comments