@@ -1373,26 +1373,32 @@ void BaseChatMesh::checkSessionKeyTimeouts() {
13731373
13741374 if (entry->retries_left > 0 ) {
13751375 // Retry: find the contact and resend INIT
1376+ ContactInfo* contact = nullptr ;
13761377 for (int j = 0 ; j < num_contacts; j++) {
13771378 if (memcmp (contacts[j].id .pub_key , entry->peer_pub_prefix , 4 ) == 0 ) {
1378- entry->retries_left --;
1379- entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1380-
1381- // Regenerate ephemeral keypair for retry
1382- uint8_t seed[SEED_SIZE ];
1383- getRNG ()->random (seed, SEED_SIZE );
1384- ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1385- memset (seed, 0 , SEED_SIZE );
1386-
1387- uint8_t req_data[1 + PUB_KEY_SIZE ];
1388- req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1389- memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1390-
1391- uint32_t tag, est_timeout;
1392- sendRequest (contacts[j], req_data, sizeof (req_data), tag, est_timeout);
1379+ contact = &contacts[j];
13931380 break ;
13941381 }
13951382 }
1383+ if (!contact) {
1384+ entry->retries_left = 0 ; // contact gone — fall through to cleanup on next tick
1385+ continue ;
1386+ }
1387+ entry->retries_left --;
1388+ entry->timeout_at = futureMillis (SESSION_KEY_TIMEOUT_MS );
1389+
1390+ // Regenerate ephemeral keypair for retry
1391+ uint8_t seed[SEED_SIZE ];
1392+ getRNG ()->random (seed, SEED_SIZE );
1393+ ed25519_create_keypair (entry->ephemeral_pub , entry->ephemeral_prv , seed);
1394+ memset (seed, 0 , SEED_SIZE );
1395+
1396+ uint8_t req_data[1 + PUB_KEY_SIZE ];
1397+ req_data[0 ] = REQ_TYPE_SESSION_KEY_INIT ;
1398+ memcpy (&req_data[1 ], entry->ephemeral_pub , PUB_KEY_SIZE );
1399+
1400+ uint32_t tag, est_timeout;
1401+ sendRequest (*contact, req_data, sizeof (req_data), tag, est_timeout);
13961402 } else {
13971403 // All retries exhausted — clean up
13981404 memset (entry->ephemeral_prv , 0 , PRV_KEY_SIZE );
0 commit comments