[OpenSIPS-Devel] [ opensips-Feature Requests-2413673 ] [nat_traversal] Should match source and *local* IP:port

SourceForge.net noreply at sourceforge.net
Tue Oct 13 00:58:49 CEST 2009


Feature Requests item #2413673, was opened at 2008-12-10 13:47
Message generated for change (Settings changed) made by dan_pascu
You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=1086413&aid=2413673&group_id=232389

Please note that this message will contain a full copy of the comment thread,
including the initial issue submission, for this request,
not just the latest update.
>Category: modules
>Group: trunk
Status: Open
>Priority: 3
Private: No
Submitted By: Iñaki Baz Castillo (ibc_sf)
Assigned to: Dan (dan_pascu)
Summary: [nat_traversal] Should match source and *local* IP:port

Initial Comment:
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:

  sip:PHONE_PUBLIC_ADDR udp:ADDR1

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))
            break;
        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);
    lock_get(&nat_table->slots[h].lock);

    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");
        }
    }

    lock_release(&nat_table->slots[h].lock);
}
--------


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

----------------------------------------------------------------------

You can respond by visiting: 
https://sourceforge.net/tracker/?func=detail&atid=1086413&aid=2413673&group_id=232389



More information about the Devel mailing list