[Serusers] ACK for non-2XX not record-routed

Miklos Tirpak miklos at iptel.org
Thu Mar 22 14:44:54 CET 2007


ok, I agree, this is a bug. I tried to explain it in the description of 
SER-212, but probably it is not enough detailed.

The problem is basically that loose_route() removes the route HF from 
the INVITE, so the locally generated ACK for non-2xx final response (and 
local CANCEL as well!) should remove the same route HF. But tm module 
does not know that the route HF was removed when it builds the ACK, 
because it is working with the incoming INVITE message buffer instead of 
the outgoing one.

We have changed SER-212 in the bug tracker from "bug" to "wishlist", 
because folks claimed that nobody reported this problem, so the patch is 
not urgent. Until now!!! You are the one who has reported it :)

Anyway, Andrei said that there may be a better way to implement the same 
which does not require message parsing, so this is the reason why the 
patch is in on-hold state. If you problem is urgent, use the patch, or 
vote for changing it back from "wishlist" to "bug".

Regards,
Miklos

On 03/22/2007 12:50 AM, Emmanuel Hislen wrote:
> Hi,
> 
> Agreed on the definition of Route Set, and I have no intention to modify
> it in-dialog. I'm just worried by the fact that SER doesn't remove the
> Route header from a request that was record-routed to it before sending
> it to the next hop.
> 
> Here are the SIP messages to illustrate what I mean...
> 
> Setup:
> 
> UA A ------> SER ------> UA B
> 
> A is 192.168.1.236
> SER is 192.168.1.77
> B is 192.168.1.239
> 
> 
> Here is the body of my simple ser.cfg for completeness:
> 
> **********
> # -------------------------  request routing logic -------------------
> 
> # main routing logic
> 
> route{
> 
>         # initial sanity checks -- messages with
>         # max_forwards==0, or excessively long requests
>         if (!mf_process_maxfwd_header("10")) {
>                 sl_send_reply("483","Too Many Hops");
>                 break;
>         };
>         if (msg:len >=  2048 ) {
>                 sl_send_reply("513", "Message too big");
>                 break;
>         };
> 
>         xlog("L_DBG","===> Main Route logic...\n");
> 
>         # we record-route all messages -- to make sure that
>         # subsequent messages will go through our proxy; that's
>         # particularly good if upstream and downstream entities
>         # use different transport protocol
>         if (!method=="REGISTER") {
>                 xlog("L_DBG","===> Doing Record Route...\n");
>                 record_route();
>         }
> 
>         # subsequent messages withing a dialog should take the
>         # path determined by record-routing
>         if (loose_route()) {
>                 xlog("L_DBG","===> Loose Routing logic...\n");
>                 if ((method=="INVITE" || method=="REFER") && 
> !has_totag()) {
>                         sl_send_reply("403", "Forbidden");
>                         break;
>                 };
> 
>                 # mark routing logic in request
>                 append_hf("P-hint: rr-enforced\r\n");
>                 route(1);
>                 break;
>         };
> 
>         xlog("L_DBG","===> No Loose Routing involved...\n");
> 
>         if (uri!=myself) {
>                 xlog("L_DBG","===> NOT for ME...\n");
>                 # mark routing logic in request
>                 append_hf("P-hint: outbound\r\n");
>                 route(1);
>                 break;
>         };
> 
>         if (uri==myself) {
> 
>                 xlog("L_DBG","===> for ME...[method <%rm> r-uri <%ru>]\n");
> 
>                 if (method=="ACK") {
>                         route(1);
>                         break;
>                 } else if (method=="CANCEL") {
>                         route(1);
>                         break;
>                 } else if (method=="INVITE" || method=="OPTIONS") {
>                         route(3);
>                         break;
>                 } else if (method=="REGISTER") {
>                         route(2);
>                         break;
>                 };
>         };
> 
>         route(1);
> }
> 
> route[1]
> {
>         # send it out now; use stateful forwarding as it works reliably
>         # even for UDP2TCP
>         if (!t_relay()) {
>                 sl_reply_error();
>         };
> }
> 
> route[2]
> {
>         # -----------------------------------------------------------------
>         # REGISTER Message Handler
>         # -----------------------------------------------------------------
>         # we don't expect ANY Register in this setup...
>         sl_send_reply("401", "Unauthorized");
>         break;
> }
> 
> route[3]
> {
>         # -----------------------------------------------------------------
>         # INVITE Message Handler
>         # -----------------------------------------------------------------
> 
>         if (uri=~"^sip:[0-9]*@") { # PSTN
>                 xlog("L_DBG","===> for PSTN...\n");
> 
>                 rewritehost("192.168.1.239"); # PSTN GW
>                 avp_write("i:45", "inv_timeout");
>                 route(1);
>                 break;
>         } else {
>                 xlog("L_DBG","===> NOT for PSTN...\n");
> 
>                 sl_send_reply("404", "User Not Found");
>                 break;
>         }
> }
> **********
> 
> Now A calls B, call successful. This shows handling of an ACK to a 2XX 
> response.
> 
> (I'm removing SDP bodies to keep it short)
> 
> INVITE captured on A:
> 
> **********
> 181742.720: SENDING to 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> INVITE sip:85307 at 192.168.1.77:5060;user=phone SIP/2.0
> To:   <sip:85307 at 192.168.1.77:5060;user=phone>
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817361 INVITE
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK0115514019052115
> Max-Forwards: 70
> Allow: REFER,OPTIONS,BYE,CANCEL,ACK,INVITE
> Supported: replaces
> Contact: sip:192.168.1.236:5060
> Content-Type: application/sdp
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> User-Agent: Foo-Bar
> Content-Length: 205
> **********
> 
> INVITE captured on B, has Record-Route from SER:
> 
> **********
> 181747.640: RECEIVED from 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> INVITE sip:85307 at 192.168.1.239:5060;user=phone SIP/2.0
> Record-Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> To:   <sip:85307 at 192.168.1.77:5060;user=phone>
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817361 INVITE
> Via: SIP/2.0/UDP 192.168.1.77;branch=z9hG4bK4014.1299ece.0
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK0115514019052115
> Max-Forwards: 16
> Allow: REFER,OPTIONS,BYE,CANCEL,ACK,INVITE
> Supported: replaces
> Contact: sip:192.168.1.236:5060
> Content-Type: application/sdp
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> User-Agent: Foo-Bar
> Content-Length: 205
> **********
> 
> --------------------
> 
> 200 OK captured on B, has Record-Route:
> 
> **********
> 181749.780: SENDING to 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> SIP/2.0 200 OK
> Via: SIP/2.0/UDP 192.168.1.77;branch=z9hG4bK4014.1299ece.0
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK0115514019052115
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817361 INVITE
> Allow: REFER,OPTIONS,BYE,CANCEL,ACK,INVITE
> Supported: replaces
> Record-Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> Contact: <sip:85307 at 192.168.1.239:5060;user=phone>
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> Content-Type: application/sdp
> Server: Foo-Bar
> User-Agent: Foo-Bar
> Content-Length: 204
> **********
> 
> 200 OK captured on A, has Record-Route:
> 
> **********
> 181744.870: RECEIVED from 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> SIP/2.0 200 OK
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK0115514019052115
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817361 INVITE
> Allow: REFER,OPTIONS,BYE,CANCEL,ACK,INVITE
> Supported: replaces
> Record-Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> Contact: <sip:85307 at 192.168.1.239:5060;user=phone>
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> Content-Type: application/sdp
> Server: Foo-Bar
> User-Agent: Foo-Bar
> Content-Length: 204
> **********
> 
> --------------------
> 
> ACK captured on A, has Route header:
> 
> **********
> 181744.880: SENDING to 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> ACK sip:85307 at 192.168.1.239:5060;user=phone SIP/2.0
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817361 ACK
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK0115521825db60f5
> Max-Forwards: 70
> Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> User-Agent: Foo-Bar
> Content-Length: 0
> **********
> 
> ACK captured on B, has NO Route header, has Record-Route header:
> 
> **********
> 181749.800: RECEIVED from 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> ACK sip:85307 at 192.168.1.239:5060;user=phone SIP/2.0
> Record-Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817361 ACK
> Via: SIP/2.0/UDP 192.168.1.77;branch=0
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK0115521825db60f5
> Max-Forwards: 16
> User-Agent: Foo-Bar
> Content-Length: 0
> P-hint: rr-enforced
> **********
> 
> --------------------
> --------------------
> 
> Now A re-INVITEs B, B rejects with 415, this shows handling of an ACK to 
> a non-2XX response.
> 
> 
> re-INVITE captured on A, has Route header
> 
> **********
> 181775.580: SENDING to 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> INVITE sip:85307 at 192.168.1.239:5060;user=phone SIP/2.0
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817362 INVITE
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK01155e16dc5473f3
> Max-Forwards: 70
> Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> Contact: sip:192.168.1.236:5060
> Content-Type: application/sdp
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> User-Agent: Foo-Bar
> Content-Length: 200
> **********
> 
> re-INVITE captured on B, has NO Route header, has Record-Route header:
> 
> **********
> 181780.500: RECEIVED from 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> INVITE sip:85307 at 192.168.1.239:5060;user=phone SIP/2.0
> Record-Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817362 INVITE
> Via: SIP/2.0/UDP 192.168.1.77;branch=z9hG4bK1014.fff3b3e5.0
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK01155e16dc5473f3
> Max-Forwards: 16
> Contact: sip:192.168.1.236:5060
> Content-Type: application/sdp
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> User-Agent: Foo-Bar
> Content-Length: 200
> P-hint: rr-enforced
> **********
> 
> --------------------
> 
> 415 captured on B:
> 
> **********
> 181780.510: SENDING to 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> SIP/2.0 415 Unsupported Media Type
> Via: SIP/2.0/UDP 192.168.1.77;branch=z9hG4bK1014.fff3b3e5.0
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK01155e16dc5473f3
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817362 INVITE
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> Server: Foo-Bar
> User-Agent: Foo-Bar
> Content-Length: 0
> **********
> 
> 415 captured on A:
> 
> **********
> 181775.600: RECEIVED from 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> SIP/2.0 415 Unsupported Media Type
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK01155e16dc5473f3
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817362 INVITE
> Accept: application/sdp
> Accept-Encoding:
> Accept-Language: en
> Server: Foo-Bar
> User-Agent: Foo-Bar
> Content-Length: 0
> **********
> 
> --------------------
> 
> ACK captured on A, has same Route header as re-INVITE as per RFC3261 
> section 17.1.1.3:
> 
> **********
> 181775.600: SENDING to 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> ACK sip:85307 at 192.168.1.239:5060;user=phone SIP/2.0
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> CSeq: 1817362 ACK
> Via: SIP/2.0/UDP 192.168.1.236:5060;branch=z9hG4bK01155e16dc5473f3
> Max-Forwards: 70
> Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> User-Agent: Foo-Bar
> Content-Length: 0
> **********
> 
> ACK captured on B, still has Route Header !?!?!?!:
> 
> **********
> 181780.510: RECEIVED from 192.168.1.77:5060
> ----------------------------------------------------------------------------- 
> 
> ACK sip:85307 at 192.168.1.239:5060;user=phone SIP/2.0
> Via: SIP/2.0/UDP 192.168.1.77;branch=z9hG4bK1014.fff3b3e5.0
> From: <sip:192.168.1.236:5060>;tag=b2ce30d4-2062aaaa-ec187086
> Call-ID: f40a387b-3-2062aaaa at 192.168.1.236
> To: <sip:85307 at 192.168.1.77:5060;user=phone>;tag=d85b805d-2062aaaa-ef187086
> CSeq: 1817362 ACK
> Route: <sip:192.168.1.77;ftag=b2ce30d4-2062aaaa-ec187086;lr>
> User-Agent: Sip EXpress router(0.9.6 (i386/linux))
> Content-Length: 0
> **********
> 
> --------------------
> 
> 
> I'm under the impression that SER handles the second ACK as if it was 
> the ACK for a non-2XX response to an initial INVITE (reasonably assuming 
> initial INVITES have usually no Route header). In other words SER 
> assumes that this ACK is not supposed to be Record Routed and therefore 
> does not remove the Route header. Something like that...
> 
> Let me know what you think.
> 
> Thanks,
> 
> Emmanuel.
> 
> 
> Miklos Tirpak wrote:
>> Hello,
>>
>> comments inline
>>
>> On 03/20/2007 09:52 AM, Greger V. Teigre wrote:
>>> I'm not sure that I understand what you mean is wrong. It would be 
>>> easier to follow if you include the ACKs. And non-2xxs, what is 
>>> exactly the exchange? A full SIP trace would help...
>>> g-)
>>>
>>> Emmanuel Hislen wrote:
>>>> Hi,
>>>>
>>>>
>>>> I've been using SER (0.9.6) as a Proxy doing Loose Routing between 2 
>>>> endpoints.
>>>>
>>>>
>>>> If I place a call I can see how the ACK for the 2XX response to the 
>>>> INVITE is properly handled (Route header removed, Record-Route 
>>>> inserted).
>>>>
>>>> Now with the call still up, I do a re-INVITE which is rejected with 
>>>> a 415. The re-INVITE request sent by UAC contained a Route header, 
>>>> as it was an in-dialog request in a record-routed dialog. Now as per 
>>>> RFC3261 section 17.1.1.3:
>>>>
>>>>    If the INVITE request whose response is being acknowledged had Route
>>>>    header fields, those header fields MUST appear in the ACK.  This is
>>>>    to ensure that the ACK can be routed properly through any downstream
>>>>    stateless proxies.
>>>>
>>>>
>>>> My UAC complied with the above, but SER seemed to choke on this:
>>>>
>>>> whereas the ACK for 2XX was successfully routed by SER in the 
>>>> original INVITE, the ACK for non-2XX (looking exactly the same: same 
>>>> Request URI, same IP destination, same Route header, ... different 
>>>> Via branch of course) is not handled properly: yes the ACK reaches 
>>>> UAS but it still has the Route header in it, and no Record-Route was 
>>>> added. And I'm guessing that if there had been another proxy in the 
>>>> Route Set on the way to the UAS it would have been bypassed.
>>
>> just to make some definition clear: Route set is the collection of 
>> Route headers, the Record-route headers are used only to learn the 
>> route-set. So the missing Record-route header does not have any impact 
>> of the ACK routing, however could have an impact of routing the BYE 
>> for example in your case. But the RFC says that the in-dialog requests 
>> do not modify the previously learned route-set:
>>
>> "12.2 Requests within a Dialog
>> ...
>>    Requests within a dialog MAY contain Record-Route and Contact header
>>    fields.  However, these requests do not cause the dialog's route set
>>    to be modified, although they may modify the remote target URI.
>>    Specifically, requests that are not target refresh requests do not
>>    modify the dialog's remote target URI, and requests that are target
>>    refresh requests do.  For dialogs that have been established with an
>>    INVITE, the only target refresh request defined is re-INVITE (see
>>    Section 14).  Other extensions may define different target refresh
>>    requests for dialogs established in other ways.
>>
>>       Note that an ACK is NOT a target refresh request."
>>
>> But be careful with modifying the route-set in SER (not with 
>> record-routeing but with modifying the route headers directly)!
>> More info: http://tracker.iptel.org/browse/SER-212?page=all
>>
>> Regards,
>> Miklos
>>
>>>>
>>>>
>>>> SER traces for ACK-2XX:
>>>>
>>>>>  0(13574) ===> Loose Routing logic...
>>>>>  0(13574) parse_headers: flags=-1
>>>>>  0(13574) DEBUG: t_newtran: msg id=89 , global msg id=88 , T on 
>>>>> entrance=0xffffffff
>>>>>  0(13574) parse_headers: flags=-1
>>>>>  0(13574) parse_headers: flags=60
>>>>>  0(13574) t_lookup_request: start searching: hash=41794, isACK=1
>>>>>  0(13574) parse_headers: flags=28
>>>>>  0(13574) DEBUG: t_lookup_request: e2e proxy ACK found
>>>>>  0(13574) parse_headers: flags=4
>>>>>  0(13574) DEBUG: totag for e2e ACK found: 0
>>>>>  0(13574) SER: forwarding ACK  statelessly
>>>>
>>>>
>>>> SER traces for ACK-non-2XX:
>>>>
>>>>>  0(13574) ===> Loose Routing logic...
>>>>>  0(13574) parse_headers: flags=-1
>>>>>  0(13574) DEBUG: t_newtran: msg id=92 , global msg id=91 , T on 
>>>>> entrance=0xffffffff
>>>>>  0(13574) parse_headers: flags=-1
>>>>>  0(13574) parse_headers: flags=60
>>>>>  0(13574) t_lookup_request: start searching: hash=41807, isACK=1
>>>>>  0(13574) DEBUG: RFC3261 transaction matched, tid=007d7195499e33a1
>>>>>  0(13574) DEBUG: t_lookup_request: transaction found (T=0xb616ae48)
>>>>>  0(13574) DEBUG: cleanup_uac_timers: RETR/FR timers reset
>>>>>  0(13574) DEBUG: add_to_tail_of_timer[2]: 0xb616ae90
>>>>>  0(13574) DEBUG:destroy_avp_list: destroying list (nil)
>>>>>  0(13574) receive_msg: cleaning up
>>>>
>>>>
>>>> This doesn't seem right, am I missing something here?
>>>>
>>>>
>>>>
>>>> Thanks,
>>>>
>>>> Emmanuel.
>>>> _______________________________________________
>>>> Serusers mailing list
>>>> Serusers at lists.iptel.org
>>>> http://lists.iptel.org/mailman/listinfo/serusers
>>>>
>>>>
>>> _______________________________________________
>>> Serusers mailing list
>>> Serusers at lists.iptel.org
>>> http://lists.iptel.org/mailman/listinfo/serusers
>>
>>



More information about the sr-users mailing list