#24 [nat_traversal] Should match source and *local* IP:port

modules (91)

I've realized of a limitation in nat_traversal keepalive mechanism. Note the following case:

- OpenSIPS listening in two address: ADDR1, ADDR2 (can be different IP and/or port).

- A multi-account phone (Twinkle) that uses the same internal port for all the accounts (5060).

- The phone behind NAT.

- Phone account 1: uses ADDR1 as outbound proxy / registrar.

- Phone account 2: uses ADDR2 as outbound proxy / registrar.

When account 1 is registered nat_traversal creates a keepalive:


When the register from account 2 arrives nat_traversal *doesn't* create a new keepalive since the source address (IP and port) matches an existing one, but this is a bug since account 2 is using ADDR2 as socket, so when OpenSIPS tries to route a request to account 2 it will fail since there is NO keepalive between OpenSIPS ADDR2 and PHONE_PUBLIC_ADDR.

I assume the problem is in the function "HashTable_search":

static NAT_Contact*
HashTable_search(HashTable *table, char *uri, unsigned slot)
NAT_Contact *contact;

contact = table->slots[slot].head;

while (contact) {
if (NAT_Contact_match(contact, uri))
contact = contact->next;

return contact;

When it's called from "keepalive_registration" it just creates a new keepalive if a contact wan't found:

static void
keepalive_registration(struct sip_msg *request, time_t expire)
NAT_Contact *contact;
unsigned h;
char *uri;

uri = get_source_uri(request);

h = HASH(nat_table, uri);

contact = HashTable_search(nat_table, uri, h);
if (contact) {
SIP_Registration_update(contact, expire);
} else {
contact = NAT_Contact_new(uri, request->rcv.bind_address);
if (contact) {
SIP_Registration_update(contact, expire);
contact->next = nat_table->slots[h].head;
nat_table->slots[h].head = contact;
} else {
LM_ERR("cannot allocate shared memory for new NAT contact\n");


So IMHO the function "HashTable_search" should consider the client contact and *also* the local socket used to communicate OpenSIPS with the client.


  • Bogdan-Andrei Iancu

    • assigned_to: nobody --> dan_pascu
  • Dan Pascu

    Dan Pascu - 2009-10-12
    • labels: 1134770 --> modules
    • milestone: 855201 --> trunk
    • priority: 5 --> 3
    • status: open --> open-later

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks