@@ -1349,26 +1349,32 @@ void BaseChatMesh::checkSessionKeyTimeouts() {
13491349
13501350 if (entry->retries_left > 0 ) {
13511351 // Retry: find the contact and resend INIT
1352+ ContactInfo* contact = nullptr ;
13521353 for (int j = 0 ; j < num_contacts; j++) {
13531354 if (memcmp (contacts[j].id .pub_key , entry->peer_pub_prefix , 4 ) == 0 ) {
1354- entry->retries_left --;
1355- entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1356-
1357- // Regenerate ephemeral keypair for retry
1358- uint8_t seed[SEED_SIZE ];
1359- getRNG ()->random (seed, SEED_SIZE );
1360- ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1361- memset (seed, 0 , SEED_SIZE );
1362-
1363- uint8_t req_data[1 + PUB_KEY_SIZE ];
1364- req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1365- memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1366-
1367- uint32_t tag, est_timeout;
1368- sendRequest (contacts[j], req_data, sizeof (req_data), tag, est_timeout);
1355+ contact = &contacts[j];
13691356 break ;
13701357 }
13711358 }
1359+ if (!contact) {
1360+ entry->retries_left = 0 ; // contact gone — fall through to cleanup on next tick
1361+ continue ;
1362+ }
1363+ entry->retries_left --;
1364+ entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1365+
1366+ // Regenerate ephemeral keypair for retry
1367+ uint8_t seed[SEED_SIZE ];
1368+ getRNG ()->random (seed, SEED_SIZE );
1369+ ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1370+ memset (seed, 0 , SEED_SIZE );
1371+
1372+ uint8_t req_data[1 + PUB_KEY_SIZE ];
1373+ req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1374+ memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1375+
1376+ uint32_t tag, est_timeout;
1377+ sendRequest (*contact, req_data, sizeof (req_data), tag, est_timeout);
13721378 } else {
13731379 // All retries exhausted — clean up
13741380 memset (entry->ephemeral_prv , 0 , PRV_KEY_SIZE );
0 commit comments