@@ -1291,26 +1291,32 @@ void BaseChatMesh::checkSessionKeyTimeouts() {
12911291
12921292 if (entry->retries_left > 0 ) {
12931293 // Retry: find the contact and resend INIT
1294+ ContactInfo* contact = nullptr ;
12941295 for (int j = 0 ; j < num_contacts; j++) {
12951296 if (memcmp (contacts[j].id .pub_key , entry->peer_pub_prefix , 4 ) == 0 ) {
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 (contacts[j], req_data, sizeof (req_data), tag, est_timeout);
1297+ contact = &contacts[j];
13111298 break ;
13121299 }
13131300 }
1301+ if (!contact) {
1302+ entry->retries_left = 0 ; // contact gone — fall through to cleanup on next tick
1303+ continue ;
1304+ }
1305+ entry->retries_left --;
1306+ entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1307+
1308+ // Regenerate ephemeral keypair for retry
1309+ uint8_t seed[SEED_SIZE ];
1310+ getRNG ()->random (seed, SEED_SIZE );
1311+ ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1312+ memset (seed, 0 , SEED_SIZE );
1313+
1314+ uint8_t req_data[1 + PUB_KEY_SIZE ];
1315+ req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1316+ memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1317+
1318+ uint32_t tag, est_timeout;
1319+ sendRequest (*contact, req_data, sizeof (req_data), tag, est_timeout);
13141320 } else {
13151321 // All retries exhausted — clean up
13161322 memset (entry->ephemeral_prv , 0 , PRV_KEY_SIZE );
0 commit comments