Comment #25 on issue 2254 by [email protected]: keepalive support and cleanup for client-initiated connections as per RFC 5626
http://code.google.com/p/mobicents/issues/detail?id=2254

As part of the full implementation of RFC5626 it would be nice if the container also supported "flows" as outlined in that RFC. There are multiple parts to the final solution but this initial request is only about supporting the "ob" parameter when acting as a UAS. The following information is from my question on google groups but is summarized here to keep it together with the rest of 5626 information (per Jean's request).

Note: Jean just informed me that there has been some re-structuring in the container core so the solution as described below may have to be updated a bit (as well as the patch attached). However, I decided that for completeness sake, I would record that conversation here anyway.

From: http://groups.google.com/group/mobicents-public/browse_thread/thread/88e3af084055b4cc

So, the basic use case I want to support is when the container is
acting as a B2BUA (hence, just a UAS from the clients perspective) and
one of the clients is behind a NAT. As you guys know, the client will
claim that it has ip x but the nat:ed address is really x” (bis) so
when we send a subsequent request back to that client, we really
should be sending it to x”.
Before getting into the stuff I added I just want to point out that
RFC5626 mainly talks about proxies and explains quite in detail how a
proxy would deal with this scenario. However, I think it is important
that a UAS actually can support this as well, something the RFC
doesn’t really talk about (unless I just don’t understand it)
Anyway, at a high-level, this is what I did:
In the JAIN SIP stack, there is already support for “connection reuse”
since it will store each incoming connection in an internal table and
file it under a “connection key” (see: TcpMessageProcessor). In a NAT
scenario, the stack will actually ask the socket for the “real”
address and store it under that address. So, in our scenario above,
the incoming connection will be stored under address x”. Hence, if we
just give the stack the right “key” it would in fact find the correct
connection and reuse it and everything would work.
So, digging around I came to the following solution (thank you step debugging!):
* For incoming dialog creating requests, check if the URI that pointed
to us (either the top-most route or the request-uri) has the “ob”
parameter and if so, do:
    + Generate a flow-token (see section 5.2 Generating Flow Tokens in
RFC5626) and store this flow under that key.
    + If we are acting as a proxy, then add a record-router header
containing the flow token and follow the guidelines in RFC5626.
    + else, we are acting as a UAS so just keep track of this stuff
internally (or we could stamp the flow token on the contact uri if we
want to I guess)
 * For incoming subsequent requests:
    + essentially the same as for initial requests but just update the
existing flow if the connection info has changed.
* For outgoing subsequent requests:
    + When determining the next hop (SipServletRequestImpl.send()), if
the next uri to resolve has the “ob” parameter, then do:
        - if the uri has a flow token stored within it, lookup the
information associated with that flow and set the uri of the next hop
to point to that information.
        - if the uri doesn’t have a flow token, then if we are a UAS
then it may be stored internally (unless we of course stamped it in
the contact uri so perhaps that is a better solutions so we don’t need
special code for handling a proxy vs a uas scenario) so look it up and
use that flow.
That is the entire solution and the following classes were changed (of
course, see attached diff):
 * InitialRequestDispatcher - this class will be the one checking for
the “ob” parameter in the URI pointing to us and store the current
flow on the SipSession so that it can be accessed later.
 * SipServletRequestImpl - when a request is about to be sent out, it
will figure out the next hop to where the request will be sent. It
simply does this by either extracting out the uri from the top-most
route header or the actual remote target (the request-uri, which of
course came from the contact-header in the initial request). However,
we should now examine this “uriToResolve” to see if it has the “ob”
parameter set. If so, see if we can find a “flow” for it and if so,
set the “uriToResolve” to point to this URI instead (which is the URI
that was stored in the InitialRequestDispatcher as described above).
So, that is the entire fix for now. There are still stuff to do (proxy
scenario, dealing with updating the flow for subsequent requests
(looks like the code then probably would go into
SipApplicationDispatcherImpl???) but this takes care of my initial
scenario so for now, I am happy. However, I do want to contribute with
a full solutions if you guys think it would be valuable. The reason
for this is simply:
 * Give back to the community
 * Get more people to crack down on my solution and therefore increase
the chance of this actually working...

Attachments:
        sipoutbound.diff  10.2 KB

Reply via email to