Does SER 2.0.0-rc1/examples/pstn.cfg or the much more complete one in Chapter 8 of "SER Getting Started" actually work when it comes to a BYE comming from the PSTN gateway?
So far, it appears these two cfg files don't cope with the called party on the PSTN hangs up first, and it isn't clear how it could be made to work in anything more complex than a one-SIP-call-source one pstn-gateway configuration.
Let's say I have four clients from which a call can originate and arrive at SER, with the caller source IP addresses of "A", "B", "C" and "D". "C" sends the INVITE of a call that SER determined is destined for the PSTN gateway, which is at IP address "P". Here, the INVITE, 100 Trying, 180/183, 200 OK and ACK messages all go to the right places and look more or less correct.
If "C" sends a BYE to end the call, this also works correctly, with SER forwarding that on to "P" and the 200 OK being returned. So far, so good.
However, if the called party on the PSTN hangs up first, "P" sends SER a BYE and SER simply sends the BYE right back to "P", whom responds with a "481" back. The originating party at "C" never finds out that the call has ended, because SER didn't pass the BYE on to the calling device. The SIP phone stays in the "Connected" state.
In my case, the calling sites A, B, C and D don't include a Record-Route of their own, but sometimes have a Via: header. In either case, SER still doesn't send a BYE or re-INVITE coming from P to the correct destination of A, B, C or D.
I don't know how I could force SER to send the BYE or INVITE on to the right place, given four possible call-initiator IP addresses, of which only "C" would know about this sample call.
I don't believe I can stick in an extra Record-Route when handling the original INVITE that has the call source IP address in it (in addition to a Record-Route of my own), simply because I don't believe SER will let me dynamically select which senders IP address should go in the forged Record-Route, or if doing so would really help the situation later when that trail of crumbs might be helpful.
Also, even though the pstn.cfg sample in the book has lots of steps to check for fraud before processing a re-INVITE coming from the PSTN (and the footnotes say that this is what these checks are for), I don't see how SER would know the right place to send the re-INVITE that came from the PSTN once it the authentication checks were done. It looks like SER will always send it to "P" regardless of which direction it should be sent, which doesn't help much, and puts any call using Session-Expires: to failure, when 50% of that time (plus 32.5 seconds) has passed.
So, is there with a corrected pstn.cfg out there, or better still, has anybody actually made these two situations work, which are: (1) The called party on the PSTN hangs-up first which causes a BYE to be sent to SER. SER forwards the BYE to the right caller (or whatever the so-called proxy is supposed to do), AND (2) the SIP-PSTN gateway device sends a re-INVITE to SER and it goes somewhere that will generate an OK reply
If someone has made it work, can they show an example, rather than just say "it should be possible" or "works for me"? Such responses are encouraging, but not that helpful. Thanks in advance!
Ok, Frank. You have told me that you don't want me to respond, but I will anyway as you are referring to the Getting Started config and I'm one of the authors. Can you send some traces? I'm particularly interested in the first INVITE and the BYE, and of course the ruri and Route set in these. There seems to be a problem with in-dialog constructed messages from your gw. They should be constructed as specified in RFC3261, section 12. My guess is that there are no Route lines in the BYE (except for the one pointing to SER) and that the BYE's ruri has username@ip-of-gw (at least that would be the easy explanation :-)
g-) PS. A top for later questions on the list: you are far more likely to get responses if you make it short and sweet and include details.
Frank Durda IV wrote:
Does SER 2.0.0-rc1/examples/pstn.cfg or the much more complete one in Chapter 8 of "SER Getting Started" actually work when it comes to a BYE comming from the PSTN gateway?
So far, it appears these two cfg files don't cope with the called party on the PSTN hangs up first, and it isn't clear how it could be made to work in anything more complex than a one-SIP-call-source one pstn-gateway configuration.
Let's say I have four clients from which a call can originate and arrive at SER, with the caller source IP addresses of "A", "B", "C" and "D". "C" sends the INVITE of a call that SER determined is destined for the PSTN gateway, which is at IP address "P". Here, the INVITE, 100 Trying, 180/183, 200 OK and ACK messages all go to the right places and look more or less correct.
If "C" sends a BYE to end the call, this also works correctly, with SER forwarding that on to "P" and the 200 OK being returned. So far, so good.
However, if the called party on the PSTN hangs up first, "P" sends SER a BYE and SER simply sends the BYE right back to "P", whom responds with a "481" back. The originating party at "C" never finds out that the call has ended, because SER didn't pass the BYE on to the calling device. The SIP phone stays in the "Connected" state.
In my case, the calling sites A, B, C and D don't include a Record-Route of their own, but sometimes have a Via: header. In either case, SER still doesn't send a BYE or re-INVITE coming from P to the correct destination of A, B, C or D.
I don't know how I could force SER to send the BYE or INVITE on to the right place, given four possible call-initiator IP addresses, of which only "C" would know about this sample call.
I don't believe I can stick in an extra Record-Route when handling the original INVITE that has the call source IP address in it (in addition to a Record-Route of my own), simply because I don't believe SER will let me dynamically select which senders IP address should go in the forged Record-Route, or if doing so would really help the situation later when that trail of crumbs might be helpful.
Also, even though the pstn.cfg sample in the book has lots of steps to check for fraud before processing a re-INVITE coming from the PSTN (and the footnotes say that this is what these checks are for), I don't see how SER would know the right place to send the re-INVITE that came from the PSTN once it the authentication checks were done. It looks like SER will always send it to "P" regardless of which direction it should be sent, which doesn't help much, and puts any call using Session-Expires: to failure, when 50% of that time (plus 32.5 seconds) has passed.
So, is there with a corrected pstn.cfg out there, or better still, has anybody actually made these two situations work, which are: (1) The called party on the PSTN hangs-up first which causes a BYE to be sent to SER. SER forwards the BYE to the right caller (or whatever the so-called proxy is supposed to do), AND (2) the SIP-PSTN gateway device sends a re-INVITE to SER and it goes somewhere that will generate an OK reply
If someone has made it work, can they show an example, rather than just say "it should be possible" or "works for me"? Such responses are encouraging, but not that helpful. Thanks in advance!
Serusers mailing list Serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Greger Viken Teigre wrote:
Ok, Frank. You have told me that you don't want me to respond,
Actually I was hoping to nudge people who knew the answer to actually provide the answer. The last dozen or so questions asked here over the past several months have pretty-much received no useful answers, although the one where I provided a code fix saw the change quietly introduced into a new release of that piece of software with no comment.
It seems that when I gave lots of detail, someone was bound to say I needed to simplify the question because they didn't have time to read it all, but if I reduced it to an A, B, C case, someone would say they needed every SIP message and the .cfg file. Can't seem to win, so I elected to provide what was requested. :-)
Anyway, here are the pieces you asked about. If you need more, just ask. I realize how much you are getting paid for your assistance (nearly some).
If the PSTN switch really is making a mistake in this scenario (the "BYE" seems okay and because of the presence of the Record-Route it is only sent to the Record-Route address), please indicate where it violates RFC so I can start the long process of getting them to investigate and with luck I would have a fix in a year... :-(
The original INVITE, as sent from a test Asterisk box. IP addresses and phone numbers have been globally changed to protect the innocent.
Our players in this sample: 66.77.88.99 Asterisk box originating the call 206.33.44.55 SER box in the middle 10.100.20.30 PSTN gateway (SIP is really handled at a 10.x.x.x address, all others public) The SIP Phone placing the call is 3796661000 Someone out on the PSTN is the phone 9615551212 that answers the call and goes on hook first, so the PSTN switch receives a SS7 REL message and causes it to emit the BYE back to SER.
U 2009/09/28 03:47:10.060467 66.77.88.99:5060 -> 206.33.44.55:5060 INVITE sip:9615551212@206.33.44.55 SIP/2.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK2a748d20;rport From: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 To: sip:9615551212@206.33.44.55 Contact: sip:3796661000@66.77.88.99 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 CSeq: 102 INVITE User-Agent: Asterisk PBX Max-Forwards: 70 Date: Mon, 28 Sep 2009 03:47:10 GMT Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Supported: replaces Content-Type: application/sdp Content-Length: 415
v=0 o=root 45142 45142 IN IP4 66.77.88.99 s=session c=IN IP4 66.77.88.99 t=0 0 m=audio 10918 RTP/AVP 0 3 8 112 5 10 7 97 111 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:112 AAL2-G726-32/8000 a=rtpmap:5 DVI4/8000 a=rtpmap:10 L16/8000 a=rtpmap:7 LPC/8000 a=rtpmap:97 iLBC/8000 a=fmtp:97 mode=30 a=rtpmap:111 G726-32/8000 a=silenceSupp:off - - - - a=ptime:20 a=sendrecv
Here is the INVITE that SER sent on to the PSTN gateway:
U 2009/09/28 03:47:10.061905 206.33.44.55:5060 -> 10.100.20.30:5060 INVITE sip:9615551212@10.100.20.30 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=as6e0e68d0;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bKd151.5aa15121b87cf2215ad100fd89896056.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK2a748d20;rport=5060 From: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 To: sip:9615551212@206.33.44.55 Contact: sip:3796661000@206.33.44.55:5060 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 CSeq: 102 INVITE User-Agent: Asterisk PBX Max-Forwards: 16 Date: Mon, 28 Sep 2009 03:47:10 GMT Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Supported: replaces Content-Type: application/sdp Content-Length: 435
v=0 o=root 45142 45142 IN IP4 66.77.88.99 s=session c=IN IP4 66.77.88.99 t=0 0 m=audio 31768 RTP/AVP 0 3 8 112 5 10 7 97 111 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:112 AAL2-G726-32/8000 a=rtpmap:5 DVI4/8000 a=rtpmap:10 L16/8000 a=rtpmap:7 LPC/8000 a=rtpmap:97 iLBC/8000 a=fmtp:97 mode=30 a=rtpmap:111 G726-32/8000 a=silenceSupp:off - - - - a=ptime:20 a=sendrecv a=nortpproxy:yes
Now, here is the BYE coming from the PSTN switch to SER, which it would be really nice if SER sent on to the calling asterisk box:
U 2009/09/28 03:47:27.619185 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 70 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Route: sip:206.33.44.55;ftag=as6e0e68d0;lr=on Supported: timer Content-Length: 0
and here is the BYE that SER sends right back to the PSTN switch, which wonders why it was sent this junk:
U 2009/09/28 03:47:27.627511 206.33.44.55:5060 -> 10.100.20.30:5060 BYE sip:3796661000@10.100.20.30:5060 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.8367f454f9911340deec0901b216f326.0 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.55530ed60f502428f904e8008519abec.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 15 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Supported: timer Content-Length: 0
and of course, the PSTN switch replies "Huh?":
U 2009/09/28 03:47:27.629429 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 481 Call/Transaction Does Not Exist Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.8367f454f9911340deec0901b216f326.0 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.55530ed60f502428f904e8008519abec.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 15 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Supported: timer Content-Length: 0
and SER responds right back with "Double-Huh?"
U 2009/09/28 03:47:27.629558 206.33.44.55:5060 -> 10.100.20.30:5060 SIP/2.0 481 Call/Transaction Does Not Exist Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 15 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Supported: timer Content-Length: 0
and so on...
Thanks for looking!
I'm not really sure I understand your logic, but anyway... ;-)
Here's what I see: Caller as available at sip:3796661000@66.77.88.99 (initial contact in INVITE). Then the INVITE sent on to the GW uses another contact sip:3796661000@206.33.44.55:5060 (changed by SER?!). The GW's BYE is correctly using the modified contact (sip:3796661000@206.33.44.55:5060) as ruri. SER does loose routing, sees only one Route (myself), strips it and uses ruri to forward to itself. Now the BYE is not loose routed and SER tries to look up, does not find a local match and (I assume) decides its for the PSTN.
A few questions: - Why does the Contact get changed? - Are you doing double record-routing or is the double route due to SER forwarding to itself as explained above? (I seem to remember you had an issue on that earlier)
Other things that may or may not be relevant: - What is your alias/listen section in your ser.cfg? - How do you test for a URI being local? Do you use the domain module? uri==myself?
g-)
Frank Durda IV wrote:
Greger Viken Teigre wrote:
Ok, Frank. You have told me that you don't want me to respond,
Actually I was hoping to nudge people who knew the answer to actually provide the answer. The last dozen or so questions asked here over the past several months have pretty-much received no useful answers, although the one where I provided a code fix saw the change quietly introduced into a new release of that piece of software with no comment.
It seems that when I gave lots of detail, someone was bound to say I needed to simplify the question because they didn't have time to read it all, but if I reduced it to an A, B, C case, someone would say they needed every SIP message and the .cfg file. Can't seem to win, so I elected to provide what was requested. :-)
Anyway, here are the pieces you asked about. If you need more, just ask. I realize how much you are getting paid for your assistance (nearly some). If the PSTN switch really is making a mistake in this scenario (the "BYE" seems okay and because of the presence of the Record-Route it is only sent to the Record-Route address), please indicate where it violates RFC so I can start the long process of getting them to investigate and with luck I would have a fix in a year... :-(
The original INVITE, as sent from a test Asterisk box. IP addresses and phone numbers have been globally changed to protect the innocent.
Our players in this sample: 66.77.88.99 Asterisk box originating the call 206.33.44.55 SER box in the middle 10.100.20.30 PSTN gateway (SIP is really handled at a 10.x.x.x address, all others public) The SIP Phone placing the call is 3796661000 Someone out on the PSTN is the phone 9615551212 that answers the call and goes on hook first, so the PSTN switch receives a SS7 REL message and causes it to emit the BYE back to SER.
U 2009/09/28 03:47:10.060467 66.77.88.99:5060 -> 206.33.44.55:5060 INVITE sip:9615551212@206.33.44.55 SIP/2.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK2a748d20;rport From: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 To: sip:9615551212@206.33.44.55 Contact: sip:3796661000@66.77.88.99 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 CSeq: 102 INVITE User-Agent: Asterisk PBX Max-Forwards: 70 Date: Mon, 28 Sep 2009 03:47:10 GMT Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Supported: replaces Content-Type: application/sdp Content-Length: 415
v=0 o=root 45142 45142 IN IP4 66.77.88.99 s=session c=IN IP4 66.77.88.99 t=0 0 m=audio 10918 RTP/AVP 0 3 8 112 5 10 7 97 111 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:112 AAL2-G726-32/8000 a=rtpmap:5 DVI4/8000 a=rtpmap:10 L16/8000 a=rtpmap:7 LPC/8000 a=rtpmap:97 iLBC/8000 a=fmtp:97 mode=30 a=rtpmap:111 G726-32/8000 a=silenceSupp:off - - - - a=ptime:20 a=sendrecv
Here is the INVITE that SER sent on to the PSTN gateway:
U 2009/09/28 03:47:10.061905 206.33.44.55:5060 -> 10.100.20.30:5060 INVITE sip:9615551212@10.100.20.30 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=as6e0e68d0;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bKd151.5aa15121b87cf2215ad100fd89896056.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK2a748d20;rport=5060 From: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 To: sip:9615551212@206.33.44.55 Contact: sip:3796661000@206.33.44.55:5060 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 CSeq: 102 INVITE User-Agent: Asterisk PBX Max-Forwards: 16 Date: Mon, 28 Sep 2009 03:47:10 GMT Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Supported: replaces Content-Type: application/sdp Content-Length: 435
v=0 o=root 45142 45142 IN IP4 66.77.88.99 s=session c=IN IP4 66.77.88.99 t=0 0 m=audio 31768 RTP/AVP 0 3 8 112 5 10 7 97 111 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:112 AAL2-G726-32/8000 a=rtpmap:5 DVI4/8000 a=rtpmap:10 L16/8000 a=rtpmap:7 LPC/8000 a=rtpmap:97 iLBC/8000 a=fmtp:97 mode=30 a=rtpmap:111 G726-32/8000 a=silenceSupp:off - - - - a=ptime:20 a=sendrecv a=nortpproxy:yes
Now, here is the BYE coming from the PSTN switch to SER, which it would be really nice if SER sent on to the calling asterisk box:
U 2009/09/28 03:47:27.619185 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 70 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Route: sip:206.33.44.55;ftag=as6e0e68d0;lr=on Supported: timer Content-Length: 0
and here is the BYE that SER sends right back to the PSTN switch, which wonders why it was sent this junk:
U 2009/09/28 03:47:27.627511 206.33.44.55:5060 -> 10.100.20.30:5060 BYE sip:3796661000@10.100.20.30:5060 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.8367f454f9911340deec0901b216f326.0 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.55530ed60f502428f904e8008519abec.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 15 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Supported: timer Content-Length: 0
and of course, the PSTN switch replies "Huh?":
U 2009/09/28 03:47:27.629429 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 481 Call/Transaction Does Not Exist Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.8367f454f9911340deec0901b216f326.0 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK9f22.55530ed60f502428f904e8008519abec.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 15 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Supported: timer Content-Length: 0
and SER responds right back with "Double-Huh?"
U 2009/09/28 03:47:27.629558 206.33.44.55:5060 -> 10.100.20.30:5060 SIP/2.0 481 Call/Transaction Does Not Exist Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Record-Route: sip:206.33.44.55;ftag=000a0283+1+4906002d+2fd2af7a;lr=on Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+2403b90cbb5388c3a1fbf676690bb105+000a0283+1 Max-Forwards: 15 Call-ID: 106cc02230e60e47223b9e643eee9f37@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+4906002d+2fd2af7a To: "TEST PHONE 1000" sip:3796661000@66.77.88.99;tag=as6e0e68d0 CSeq: 969167137 BYE Supported: timer Content-Length: 0
and so on...
Thanks for looking!
Greger Viken Teigre wrote:
I'm not really sure I understand your logic, but anyway... ;-)
Heh, logic sometimes costs extra... :-) I do appreciate the assistance since I'm using your spare time but hopefully not wasting it. Any confusion earlier is probably caused by several other people talking in my ear about six other subjects while I'm trying to type these messages.
Here's what I see: Caller as available at sip:3796661000@66.77.88.99 (initial contact in INVITE). Then the INVITE sent on to the GW uses another contact sip:3796661000@206.33.44.55:5060 (changed by SER?!). The GW's BYE is correctly using the modified contact (sip:3796661000@206.33.44.55:5060) as ruri. SER does loose routing, sees only one Route (myself), strips it and uses ruri to forward to itself. Now the BYE is not loose routed and SER tries to look up, does not find a local match and (I assume) decides its for the PSTN.
A few questions:
- Why does the Contact get changed?
We use fix_nated_contact() to set the Contact: IP address to that of the SER box. This was based on earlier advice because without it, the calling parties would be shown the IP address of the PSTN gateway rather than the SER box, and they got highly agitated about this. At the time, this was not researched to see if that behavior was right or wrong per RFC, just that the customer said it was wrong, and as the first large customer, you made them happy.
I can certainly try pulling that out.
- Are you doing double record-routing or is the double route due to SER
forwarding to itself as explained above? (I seem to remember you had an issue on that earlier)
I tried that some weeks back, and it made things much worse. Also tried taking all loose route stuff out, and found that massive if/rewritehost structures would have to be built to get SER to forward the BYE or re-INVITE on to the correct IP destination. That was clearly much harder to manage and still had issues, that SER didn't recognize the ACK/200 OKs it later received in response to the BYE or re-INVITE messages that SER had just sent out.
The packet dumps were generarted with a main route code that looks like this: (this sample is stripped of unrelated stuff)
route{
//hops/message size checks are here. (There are no //authentication checks because the routers only let friendly //sources in, and there is no registration. If the INVITE //reaches SER, you are good, so the configuration is small.
if (loose_route()) { log(1, "Dealing with loose route as best as we can\n"); fix_nated_contact("206.33.44.55"); /*which doesn't seem to do much*/ t_relay(); break; }
//[Direction determined here by testing src_ip for PSTN gateway // IP address, eg if (src_ip==10.100.20.30) { /*PSTN TO SIP*/ // Not much unique is done here, but this exactly the path that // called-party BYE or re-INVITES from the PSTN gateway will take // without loose routing, but loose routing isn't going to the right // place. What could you do here to cope? You cannot easily // rewritehost to the SIP source because there are many possible // IPaddresses and only one will want to know about this call. // } else { /*SIP TO PSTN*/
rewritehost("10.100.20.30") /*Send to PSTN gateway*/ fix_nated_contact("206.33.44.55"); /*Point back to SER*/ }
// Also Included at the end of each case shown above is the following code, // which has different call parameters based on the direction the Method // message is going:
t_on_reply("DIRECTION_REPLY"); //DIRECTION==INBOUND or OUTBOUND record_route(); if (method=="INVITE" && @to.tag=="") { t_on_failure("FAILURE_ROUTE_DIRECTION"); } if (!t_relay()) { sl_reply_error(); } drop;
Other things that may or may not be relevant:
- What is your alias/listen section in your ser.cfg?
No "alias", just a "listen". Originally I ran two interfaces, one in the 10.x.x.x network and one for the public side, and this just added so much complexity to SER to get things to come out right that I gave up.
So there is just one entry: listen=206.333.44.55:5060
On start it says: Listening on udp: 206.33.44.55 [206.33.44.55]:5060 tcp: 206.33.44.55 [206.33.44.55]:5060 Aliases: tcp: 206.33.44.55.ptr.us.xo.net:5060 udp: 206.33.44.55.ptr.us.xo.net:5060
I used to have a pair of "alias" entries when I had two interfaces. I can certainly add an "alias" line back if you think doing so will help.
- How do you test for a URI being local? Do you use the domain module?
uri==myself?
The tests are shown above. The modules loaded are:
Modules loaded: loadmodule "/usr/local/lib/ser/modules/mysql.so" loadmodule "/usr/local/lib/ser/modules/sl.so" loadmodule "/usr/local/lib/ser/modules/tm.so" loadmodule "/usr/local/lib/ser/modules/rr.so" loadmodule "/usr/local/lib/ser/modules/maxfwd.so" loadmodule "/usr/local/lib/ser/modules/usrloc.so" loadmodule "/usr/local/lib/ser/modules/xlog.so" loadmodule "/usr/local/lib/ser/modules/textops.so" loadmodule "/usr/local/lib/ser/modules/ctl.so" loadmodule "/usr/local/lib/ser/modules/fifo.so" loadmodule "/usr/local/lib/ser/modules/gflags.so" loadmodule "/usr/local/lib/ser/modules/uri.so" loadmodule "/usr/local/lib/ser/modules/uri_db.so" loadmodule "/usr/local/lib/ser/modules/xmlrpc.so" loadmodule "/usr/local/lib/ser/modules/nathelper.so"
# ----------------- setting module-specific parameters ---------------
# specify the path to you database here modparam("acc_db|gflags|usrloc|uri_db", "db_url", "mysql://ser:heslo@localhost/ser")
# -- usrloc params --
# as we use the database anyway we will use it for usrloc as well modparam("usrloc", "db_mode", 1)
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# # limit the length of the AVP cookie to only necessary ones modparam("rr", "cookie_filter", "(account)") # # you probably do not want that someone can simply read and change # the AVP cookie in your Routes, thus should really change this # secret value below modparam("rr", "cookie_secret", "MyRRAVPcookiesecret")
# -- gflags params -- # load the global AVPs modparam("gflags", "load_global_attrs", 1)
# -- ctl params -- # by default ctl listens on unixs:/tmp/ser_ctl if no other address is # specified in modparams; this is also the default for sercmd modparam("ctl", "binrpc", "unixs:/tmp/ser/ser_ctl_tg_1234") # listen on the "standard" fifo for backward compatibility modparam("ctl", "fifo", "fifo:/tmp/ser/ser_fifo_tg_1234") # listen on tcp, localhost modparam("ctl", "binrpc", "tcp:127.0.0.1:1234")
# -- nathelper params -- modparam("nathelper", "natping_interval", 30) # modparam("nathelper", "rtpproxy_sock", "udp:10.130.0.19:8201=1 udp:10.130.0.19:8 202=1 udp:10.130.0.19:8203=1 udp:10.130.0.19:8204=1 udp:10.130.0.19:8205=1 udp:1 0.130.0.19:8206=1 udp:10.130.0.19:8207=1 udp:10.130.0.19:8208=1 udp:10.130.0.20: 8301=1 udp:10.130.0.20:8302=1 udp:10.130.0.20:8303=1 udp:10.130.0.20:8304=1 udp: 10.130.0.20:8305=1 udp:10.130.0.20:8306=1 udp:10.130.0.20:8307=1 udp:10.130.0.20 :8308=1")
# -- xmlrpc params -- # using a sub-route from the module is a lot safer then relying on the # request method to distinguish HTTP from SIP modparam("xmlrpc", "route", "RPC");
inline.
Frank Durda IV wrote:
Greger Viken Teigre wrote:
I'm not really sure I understand your logic, but anyway... ;-)
Heh, logic sometimes costs extra... :-) I do appreciate the assistance since I'm using your spare time but hopefully not wasting it. Any confusion earlier is probably caused by several other people talking in my ear about six other subjects while I'm trying to type these messages.
:-) No probs, I know the feeling.
Here's what I see: Caller as available at sip:3796661000@66.77.88.99 (initial contact in INVITE). Then the INVITE sent on to the GW uses another contact sip:3796661000@206.33.44.55:5060 (changed by SER?!). The GW's BYE is correctly using the modified contact (sip:3796661000@206.33.44.55:5060) as ruri. SER does loose routing, sees only one Route (myself), strips it and uses ruri to forward to itself. Now the BYE is not loose routed and SER tries to look up, does not find a local match and (I assume) decides its for the PSTN.
A few questions:
- Why does the Contact get changed?
We use fix_nated_contact() to set the Contact: IP address to that of the SER box. This was based on earlier advice because without it, the calling parties would be shown the IP address of the PSTN gateway rather than the SER box, and they got highly agitated about this. At the time, this was not researched to see if that behavior was right or wrong per RFC, just that the customer said it was wrong, and as the first large customer, you made them happy.
I can certainly try pulling that out.
Actually, I think that you have found your problem. Any message you forward from your SER needs to have a Contact that your SER is capable of looking up and route. When you change the IP in the Contact, you effectively removes information from the INVITE that you need in order to handle the BYE. I would advice you to take RFC3261 (or maybe better, Jiri/Dorgham's SIP intro, odf on iptel.org) and work through the flow of how Record-Routing, Route headers, Via, ruri, and Contact are used and manipulated when going hop by hop. Once you have that flow under your skin, you "talk" SIP fluently ;-)
caller-id manipulation is normally handled by a separate field, like P-Caller-Id or P-Asserted-Identity, or the From. As long as you don't have any old devices in your network, the From may be manipulated (RFC3261 says you cannot in order to achieve backward compatibility). I'm sure the gw has some way of handling caller-id.
If you really want to keep really tight control on the signaling, you can forward the call through SEMS and use one of the back 2 back user agent plugins. For some clean-up purposes, I run both signalling and media running through SEMS, which then acts as a session border controller.
- Are you doing double record-routing or is the double route due to
SER forwarding to itself as explained above? (I seem to remember you had an issue on that earlier)
I tried that some weeks back, and it made things much worse. Also tried taking all loose route stuff out, and found that massive if/rewritehost structures would have to be built to get SER to forward the BYE or re-INVITE on to the correct IP destination. That was clearly much harder to manage and still had issues, that SER didn't recognize the ACK/200 OKs it later received in response to the BYE or re-INVITE messages that SER had just sent out.
Ok, then the double Record-Route is SER forwarding to itself.
g-)
The packet dumps were generarted with a main route code that looks like this: (this sample is stripped of unrelated stuff)
route{
//hops/message size checks are here. (There are no //authentication checks because the routers only let friendly //sources in, and there is no registration. If the INVITE //reaches SER, you are good, so the configuration is small.
if (loose_route()) { log(1, "Dealing with loose route as best as we can\n"); fix_nated_contact("206.33.44.55"); /*which doesn't
seem to do much*/ t_relay(); break; }
//[Direction determined here by testing src_ip for PSTN gateway // IP address, eg if (src_ip==10.100.20.30) { /*PSTN TO SIP*/ // Not much unique is done here, but this exactly the path that // called-party BYE or re-INVITES from the PSTN gateway will take // without loose routing, but loose routing isn't going to the right // place. What could you do here to cope? You cannot easily // rewritehost to the SIP source because there are many possible // IPaddresses and only one will want to know about this call. // } else { /*SIP TO PSTN*/
rewritehost("10.100.20.30") /*Send to PSTN gateway*/ fix_nated_contact("206.33.44.55"); /*Point back to SER*/ }
// Also Included at the end of each case shown above is the following code, // which has different call parameters based on the direction the Method // message is going:
t_on_reply("DIRECTION_REPLY"); //DIRECTION==INBOUND or OUTBOUND record_route(); if (method=="INVITE" && @to.tag=="") { t_on_failure("FAILURE_ROUTE_DIRECTION"); } if (!t_relay()) { sl_reply_error(); } drop;
Other things that may or may not be relevant:
- What is your alias/listen section in your ser.cfg?
No "alias", just a "listen". Originally I ran two interfaces, one in the 10.x.x.x network and one for the public side, and this just added so much complexity to SER to get things to come out right that I gave up.
So there is just one entry: listen=206.333.44.55:5060
On start it says: Listening on udp: 206.33.44.55 [206.33.44.55]:5060 tcp: 206.33.44.55 [206.33.44.55]:5060 Aliases: tcp: 206.33.44.55.ptr.us.xo.net:5060 udp: 206.33.44.55.ptr.us.xo.net:5060
I used to have a pair of "alias" entries when I had two interfaces. I can certainly add an "alias" line back if you think doing so will help.
- How do you test for a URI being local? Do you use the domain
module? uri==myself?
The tests are shown above. The modules loaded are:
Modules loaded: loadmodule "/usr/local/lib/ser/modules/mysql.so" loadmodule "/usr/local/lib/ser/modules/sl.so" loadmodule "/usr/local/lib/ser/modules/tm.so" loadmodule "/usr/local/lib/ser/modules/rr.so" loadmodule "/usr/local/lib/ser/modules/maxfwd.so" loadmodule "/usr/local/lib/ser/modules/usrloc.so" loadmodule "/usr/local/lib/ser/modules/xlog.so" loadmodule "/usr/local/lib/ser/modules/textops.so" loadmodule "/usr/local/lib/ser/modules/ctl.so" loadmodule "/usr/local/lib/ser/modules/fifo.so" loadmodule "/usr/local/lib/ser/modules/gflags.so" loadmodule "/usr/local/lib/ser/modules/uri.so" loadmodule "/usr/local/lib/ser/modules/uri_db.so" loadmodule "/usr/local/lib/ser/modules/xmlrpc.so" loadmodule "/usr/local/lib/ser/modules/nathelper.so"
# ----------------- setting module-specific parameters ---------------
# specify the path to you database here modparam("acc_db|gflags|usrloc|uri_db", "db_url", "mysql://ser:heslo@localhost/ser")
# -- usrloc params --
# as we use the database anyway we will use it for usrloc as well modparam("usrloc", "db_mode", 1)
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# # limit the length of the AVP cookie to only necessary ones modparam("rr", "cookie_filter", "(account)") # # you probably do not want that someone can simply read and change # the AVP cookie in your Routes, thus should really change this # secret value below modparam("rr", "cookie_secret", "MyRRAVPcookiesecret")
# -- gflags params -- # load the global AVPs modparam("gflags", "load_global_attrs", 1)
# -- ctl params -- # by default ctl listens on unixs:/tmp/ser_ctl if no other address is # specified in modparams; this is also the default for sercmd modparam("ctl", "binrpc", "unixs:/tmp/ser/ser_ctl_tg_1234") # listen on the "standard" fifo for backward compatibility modparam("ctl", "fifo", "fifo:/tmp/ser/ser_fifo_tg_1234") # listen on tcp, localhost modparam("ctl", "binrpc", "tcp:127.0.0.1:1234")
# -- nathelper params -- modparam("nathelper", "natping_interval", 30) # modparam("nathelper", "rtpproxy_sock", "udp:10.130.0.19:8201=1 udp:10.130.0.19:8 202=1 udp:10.130.0.19:8203=1 udp:10.130.0.19:8204=1 udp:10.130.0.19:8205=1 udp:1 0.130.0.19:8206=1 udp:10.130.0.19:8207=1 udp:10.130.0.19:8208=1 udp:10.130.0.20: 8301=1 udp:10.130.0.20:8302=1 udp:10.130.0.20:8303=1 udp:10.130.0.20:8304=1 udp: 10.130.0.20:8305=1 udp:10.130.0.20:8306=1 udp:10.130.0.20:8307=1 udp:10.130.0.20 :8308=1")
# -- xmlrpc params -- # using a sub-route from the module is a lot safer then relying on the # request method to distinguish HTTP from SIP modparam("xmlrpc", "route", "RPC");
A follow-up on this. One of the questions Mr. Teigre asked earlier got me thinking about some things I tried some months ago where I thought I solved these issues before getting stuck on one point and not being able to get any ideas on the list at that time about what was going on. This evening I went back and tried reducing the ser.cfg file, then adding the pieces back as long as each one got things closer to what was desired.
I finally hit on a combination that works and visually seems correct, but at a cost that I guess I will have to pay. It requires me to abandon using two interfaces for SER. I have to let the router split the traffic towards the two now-not-as-isolated networks rather than let SER sit between the two isolated network as was the original design. Router access lists will have to provide protection to keep rogue packets from the public network from reaching the isolated network with the PSTN switch, rather than letting SER stand entirely in the way as was the original design.
The reason SER doesn't appear to work with two interfaces that connect to two isolated networks is pretty simple: If you use record_route() and loose_route() to handle the called-party BYE and re-INVITEs addressing correctly and fix_nated_contact() to straighten out the Contact headers in both directions on most messages, SER also inserts two Record-Route: headers, which is fine for the direction the Method message is sent in, but the order is only good for that direction. On the replies (such as 180/183/200) once you get past the SER, everything falls apart. The two Record-Routes that come out of SER (or are just passed-through) are now in the wrong order for the side of the isolated networks that the reply is sent out of SER to, so the machine receiving them tries to send the PRACK/ACK back to SER on the IP address of the other isolated network because that Record-Route line appears first, and of course you can't get there from here.
If you force the Record-Routes to come out with the listener IP addresses in reverse order, then the same scenario just fails earlier, because now the PSTN gateway sees the first Record-Route of the network it can't reach and sends the 180/183/200 reply there, so it promptly gets lost since that destination can't be reached either.
There doesn't seem to be any logic in SER to flip the order of the two Record-Routes that SER added when the replies pass back through SER (or are regenerated in that order by SER), even though SER knows both of these Record-Routes are ones that it added. As these are reply messages, I doubt I can use the ser.cfg language to fix the problem since SER doesn't allow much editing on reply messages. It will likely require a code change somewhere within SER to allow isolated networks each on its own interface to really work.
The earlier samples included various attempts to avoid the record_route/loose_route trap, but that meant much more complexity in the ser.cfg file and even then all the issues couldn't quite be resolved.
As I have been battling many different problems with SER for two years now and many of the problems are the result of trying to use the two listener/interface address feature, I think I will give up now and go with just one listen interface. The parts I need in SER seem to be really wired to only work that way. Naturally, the SER documentation talks mainly about the one-interface model too. Pity, because this was the main reason we originally wanted to use SER, to put a wall between outside IP traffic and only SIP messages that managed to get past SER config file and malformed packet checks would reach the somewhat vulnerable PSTN switch. A poor-mans Acme Packet SBC if you will. Unfortunately, SIP-capable PSTN switches are far too easy to confuse, or make angry, or both.
Thanks to Mr. Teigre for responding and reviewing this mess.
Frank Durda IV pÃÅ¡e v Út 29. 09. 2009 v 00:19 -0500:
The reason SER doesn't appear to work with two interfaces that connect to two isolated networks is pretty simple: If you use record_route() and loose_route() to handle the called-party BYE and re-INVITEs addressing correctly and fix_nated_contact() to straighten out the Contact headers in both directions on most messages, SER also inserts two Record-Route: headers, which is fine for the direction the Method message is sent in, but the order is only good for that direction. On the replies (such as 180/183/200) once you get past the SER, everything falls apart. The two Record-Routes that come out of SER (or are just passed-through) are now in the wrong order for the side of the isolated networks that the reply is sent out of SER to, so the machine receiving them tries to send the PRACK/ACK back to SER on the IP address of the other isolated network because that Record-Route line appears first, and of course you can't get there from here.
I'm sorry I haven't read all the discussion but the paragraph above hit my eyes and I think you should check whether your client/gateway/etc. is compliant with RFC3261 chapter 12.1.1 and 12.1.2.
Regarding record-route headers and creating route set: - UAS gets all headers and builds the route set - UAC gets all headers REVERSE the order and use it as route set
If it wasn't done this way any request with two or more Record-route headers (regardless who added them - one proxy both or two proxies on the path) would be affected and very probably wouldn't reach the other end.
Michal
Good to hear that it now works. I don't agree in your analysis. IMHO, using fix_nated_contact("fixed_IP") is what got you in this mess in the first place. Leaving that out, SER should be fine using two interfaces. I know others have done it (I haven't myself), but I assume pulling out a working example out of their (probably complex) ser.cfg is the reason for why you haven't received an example on this list. As Michal points out, it's really all about building the right Record-Route set in one direction (for route-changing messages) and constructing the reverse in the other direction (the user agent's responsbility). Your problem has been that the last hop towards the user agent uses the request uri and as you "fixed" the contact, this uri will be wrong. Unless you have a way of "unfixing" the ruri of the last-hop in-dialog messages, the message will either loop or go out some other direction (depending on your ser.cfg).
g-)
Frank Durda IV wrote:
A follow-up on this. One of the questions Mr. Teigre asked earlier got me thinking about some things I tried some months ago where I thought I solved these issues before getting stuck on one point and not being able to get any ideas on the list at that time about what was going on. This evening I went back and tried reducing the ser.cfg file, then adding the pieces back as long as each one got things closer to what was desired.
I finally hit on a combination that works and visually seems correct, but at a cost that I guess I will have to pay. It requires me to abandon using two interfaces for SER. I have to let the router split the traffic towards the two now-not-as-isolated networks rather than let SER sit between the two isolated network as was the original design. Router access lists will have to provide protection to keep rogue packets from the public network from reaching the isolated network with the PSTN switch, rather than letting SER stand entirely in the way as was the original design.
The reason SER doesn't appear to work with two interfaces that connect to two isolated networks is pretty simple: If you use record_route() and loose_route() to handle the called-party BYE and re-INVITEs addressing correctly and fix_nated_contact() to straighten out the Contact headers in both directions on most messages, SER also inserts two Record-Route: headers, which is fine for the direction the Method message is sent in, but the order is only good for that direction. On the replies (such as 180/183/200) once you get past the SER, everything falls apart. The two Record-Routes that come out of SER (or are just passed-through) are now in the wrong order for the side of the isolated networks that the reply is sent out of SER to, so the machine receiving them tries to send the PRACK/ACK back to SER on the IP address of the other isolated network because that Record-Route line appears first, and of course you can't get there from here.
If you force the Record-Routes to come out with the listener IP addresses in reverse order, then the same scenario just fails earlier, because now the PSTN gateway sees the first Record-Route of the network it can't reach and sends the 180/183/200 reply there, so it promptly gets lost since that destination can't be reached either.
There doesn't seem to be any logic in SER to flip the order of the two Record-Routes that SER added when the replies pass back through SER (or are regenerated in that order by SER), even though SER knows both of these Record-Routes are ones that it added. As these are reply messages, I doubt I can use the ser.cfg language to fix the problem since SER doesn't allow much editing on reply messages. It will likely require a code change somewhere within SER to allow isolated networks each on its own interface to really work.
The earlier samples included various attempts to avoid the record_route/loose_route trap, but that meant much more complexity in the ser.cfg file and even then all the issues couldn't quite be resolved.
As I have been battling many different problems with SER for two years now and many of the problems are the result of trying to use the two listener/interface address feature, I think I will give up now and go with just one listen interface. The parts I need in SER seem to be really wired to only work that way. Naturally, the SER documentation talks mainly about the one-interface model too. Pity, because this was the main reason we originally wanted to use SER, to put a wall between outside IP traffic and only SIP messages that managed to get past SER config file and malformed packet checks would reach the somewhat vulnerable PSTN switch. A poor-mans Acme Packet SBC if you will. Unfortunately, SIP-capable PSTN switches are far too easy to confuse, or make angry, or both.
Thanks to Mr. Teigre for responding and reviewing this mess.
Greger Viken Teigre wrote:
Good to hear that it now works. I don't agree in your analysis. IMHO, using fix_nated_contact("fixed_IP") is what got you in this mess in the first place. Leaving that out, SER should be fine using two interfaces.
The problem is that without fix_nated_contact, the Contact address seen by at least one party is an address they can't reach, if the two interfaces are connected to networks that are really isolated.
The issues are all with the SIP calling to TDM direction, the PSTN switch doesn't really care about the Contact being wrong as it uses Record-Route (if present) or Via to figure out where 180/183/200 replies should go. It all falls apart though when the PSTN switch initiates a BYE or a re-INVITE.
Meanwhile, some calling SIP devices (not asterisk but other high-end SBCs) are want to use the Contact value, and SER sticks an IP address in there of the second network, the one the calling network cannot possibly reach.
So while people may make it work without fix_nated_contact, I bet both interfaces/IP addresses are reachable from the calling and called parties and are not isolated, so it doesn't matter if the Contact address isn't the one on the network that party is on.
I'm in the middle of an all-day conference call right now with a telco (geez they love conference calls), so I can't do much on this at the moment, but I'll be happy to provide a sample of what was found to be needed to make things work.
I know others have done it (I haven't myself), but I assume pulling out a working example out of their (probably complex) ser.cfg is the reason for why you haven't received an example on this list.
Actually it is pretty simple as we run separate instances of SER for each "trunk". This was a lot easier than adding tests everywhere that didn't always work for whom this and what features they are supposed to get or not get), but as I have been forced to add some calls and flags to the various nathelper to get around problems and limitations. It also gets around a bug in rtpproxy that I have never been able to fix that causes it to always assign the two IP addresses it hands out in the order they are listed on the command line, regardless of the flags you pass. Again, something that probably works fine when only one interface is used, but goes off the rails when two are used that are isolated and if you get an address not on your network, the audio for that call is dead.
Finally, I assumed people seeing mystery flags and extra parameters to known calls would be a major distraction and prevent any review from getting to the heart of the issue I was asking about.
I was planning to contribute those enhancements back (so I don't have to keep re-importing them), but haven't had the time to do that yet.
As Michal points out, it's really all about building the right Record-Route set in one direction (for route-changing messages) and constructing the reverse in the other direction (the user agent's responsbility). Your problem has been that the last hop towards the user agent uses the request uri and as you "fixed" the contact, this uri will be wrong. Unless you have a way of "unfixing" the ruri of the last-hop in-dialog messages, the message will either loop or go out some other direction (depending on your ser.cfg).
Like I said, if you could get SER to put out the right IP address in Contact that is on the same network as the interface that given message was sent from, all would be well. But it doesn't do that, unless you force it.
I can certainly go back and pull the SIP messages intercepted from calls showing it doing the wrong thing unless you either went back to one interface , allowed the two networks to not be isolated from one another, or use fix_nated_contact liberally to show the distant parties IP addresses that they can actually reach. This isn't a NAT thing, although I expect someone using two interfaces to reach across a network that was NATed would have equal trouble.
Frank Durda IV wrote:
Greger Viken Teigre wrote:
Good to hear that it now works. I don't agree in your analysis. IMHO, using fix_nated_contact("fixed_IP") is what got you in this mess in the first place. Leaving that out, SER should be fine using two interfaces.
The problem is that without fix_nated_contact, the Contact address seen by at least one party is an address they can't reach, if the two interfaces are connected to networks that are really isolated.
Well, I think the key point here is that I cannot see why that is a problem? As long as your SER can resolve the Contact when it is put in the request uri, you can put whatever you want in Contact (and reverse, when you "fix" it with fix_nated_contact you cannot resolve the contact when you receive it back in the BYE). It is not used by any of the parties when record routing is done. A UAC shall according to RFC3261 send the request to the address in the topmost Route header and only use the Contact if there are no Route headers (section 12.2). g-)
The issues are all with the SIP calling to TDM direction, the PSTN switch doesn't really care about the Contact being wrong as it uses Record-Route (if present) or Via to figure out where 180/183/200 replies should go. It all falls apart though when the PSTN switch initiates a BYE or a re-INVITE.
Meanwhile, some calling SIP devices (not asterisk but other high-end SBCs) are want to use the Contact value, and SER sticks an IP address in there of the second network, the one the calling network cannot possibly reach.
So while people may make it work without fix_nated_contact, I bet both interfaces/IP addresses are reachable from the calling and called parties and are not isolated, so it doesn't matter if the Contact address isn't the one on the network that party is on.
I'm in the middle of an all-day conference call right now with a telco (geez they love conference calls), so I can't do much on this at the moment, but I'll be happy to provide a sample of what was found to be needed to make things work.
I know others have done it (I haven't myself), but I assume pulling out a working example out of their (probably complex) ser.cfg is the reason for why you haven't received an example on this list.
Actually it is pretty simple as we run separate instances of SER for each "trunk". This was a lot easier than adding tests everywhere that didn't always work for whom this and what features they are supposed to get or not get), but as I have been forced to add some calls and flags to the various nathelper to get around problems and limitations. It also gets around a bug in rtpproxy that I have never been able to fix that causes it to always assign the two IP addresses it hands out in the order they are listed on the command line, regardless of the flags you pass. Again, something that probably works fine when only one interface is used, but goes off the rails when two are used that are isolated and if you get an address not on your network, the audio for that call is dead.
Finally, I assumed people seeing mystery flags and extra parameters to known calls would be a major distraction and prevent any review from getting to the heart of the issue I was asking about.
I was planning to contribute those enhancements back (so I don't have to keep re-importing them), but haven't had the time to do that yet.
As Michal points out, it's really all about building the right Record-Route set in one direction (for route-changing messages) and constructing the reverse in the other direction (the user agent's responsbility). Your problem has been that the last hop towards the user agent uses the request uri and as you "fixed" the contact, this uri will be wrong. Unless you have a way of "unfixing" the ruri of the last-hop in-dialog messages, the message will either loop or go out some other direction (depending on your ser.cfg).
Like I said, if you could get SER to put out the right IP address in Contact that is on the same network as the interface that given message was sent from, all would be well. But it doesn't do that, unless you force it.
I can certainly go back and pull the SIP messages intercepted from calls showing it doing the wrong thing unless you either went back to one interface , allowed the two networks to not be isolated from one another, or use fix_nated_contact liberally to show the distant parties IP addresses that they can actually reach. This isn't a NAT thing, although I expect someone using two interfaces to reach across a network that was NATed would have equal trouble.
Well, I thought this was working, but after more testing, it is still exhibiting the problem I had before. (Some hard-coded routing I put in was concealing the fact that it isn't handling this situation when left on its own.)
In the PSTN gateway model, SER still doesn't know how to cope when a BYE or re-INVITE arrives which has come from the PSTN gateway, and at best it makes a guess as to which is the right destination for the messages. (It usually ends up looping back to itself.) In this case with the packets that are being received, the pstn.cfg example from the documentation doesn't do the right thing, because loose_route() doesn't get triggered for the BYE and re-INVITE messages, so SER is on its own to determine where to forward the messages.
Here is a full example of the messages involved. In my earlier word example I said the original call INVITE could come from four IP addresses, but in real life the number is more like 200 sources. It is still the same problem, be it two source addresses or a million. Which address to choose in this situation?
Almost everything is correctly-relayed back to the correct IP address (66.77.88.99), EXECPT a BYE initiated by the called network (shown), or a re-INVITE initiated by the called network (not shown, but requires the same handling as called-network BYE). If one can be cured, both should start working.
Key addresses in the example: Call initiates via asterisk server at 66.77.88.99 CALL SOURCE SER is 206.33.44.55 PSTN gateway switch is 10.100.20.30 (where BYE comes from) 2.0.0-rc1 (x86_64/freebsd)
I have only included the messages between the SER and PSTN gateway switch, as that is where the trouble starts. If the others are needed, I can get them.
U 2009/10/05 17:44:48.002403 206.33.44.55:5060 -> 10.100.20.30:5060 INVITE sip:9615551212@10.100.20.30 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55 Contact: sip:3796661000@206.33.44.55:5060 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE User-Agent: Asterisk PBX Max-Forwards: 16 Date: Mon, 05 Oct 2009 17:44:47 GMT Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Supported: replaces Content-Type: application/sdp Content-Length: 435
o=root 27275 27275 IN IP4 206.33.44.66 s=session c=IN IP4 206.33.44.66 t=0 0 m=audio 20366 RTP/AVP 0 3 8 112 5 10 7 97 111 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:112 AAL2-G726-32/8000 a=rtpmap:5 DVI4/8000 a=rtpmap:10 L16/8000 a=rtpmap:7 LPC/8000 a=rtpmap:97 iLBC/8000 a=fmtp:97 mode=30 a=rtpmap:111 G726-32/8000 a=silenceSupp:off - - - - a=ptime:20 a=sendrecv a=nortpproxy:yes
U 2009/10/05 17:44:48.004815 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 100 Trying Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Content-Length: 0
U 2009/10/05 17:44:53.956206 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 183 Session Progress Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Contact: sip:9615551212@10.100.20.30 Content-Type: application/sdp Content-Length: 173
v=0 o=- 3463753493 3463753549 IN IP4 10.100.20.30 s=- c=IN IP4 206.33.99.0 t=0 0 m=audio 34530 RTP/AVP 0 a=sendrecv a=ptime:20 a=rtpmap:0 PCMU/8000 a=silenceSupp:off - - - -
U 2009/10/05 17:44:54.855199 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 183 Session Progress Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Contact: sip:9615551212@10.100.20.30 Content-Type: application/sdp Content-Length: 173
v=0 o=- 3463753493 3463753549 IN IP4 10.100.20.30 s=- c=IN IP4 206.33.99.0 t=0 0 m=audio 34530 RTP/AVP 0 a=sendrecv a=ptime:20 a=rtpmap:0 PCMU/8000 a=silenceSupp:off - - - -
U 2009/10/05 17:44:57.125294 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 200 OK Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Contact: sip:9615551212@10.100.20.30 Content-Type: application/sdp Content-Length: 173
v=0 o=- 3463753493 3463753549 IN IP4 10.100.20.30 s=- c=IN IP4 206.33.99.0 t=0 0 m=audio 34530 RTP/AVP 0 a=sendrecv a=ptime:20 a=rtpmap:0 PCMU/8000 a=silenceSupp:off - - - -
U 2009/10/05 17:44:57.187498 206.33.44.55:5060 -> 10.100.20.30:5060 ACK sip:9615551212@10.100.20.30:5060 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.cb89b9e25754fc653a32363a1ba12e5 9.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK6a6bf681;rport=5060 From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Contact: sip:3796661000@206.33.44.55:5060 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 ACK User-Agent: Asterisk PBX Max-Forwards: 16 Content-Length: 0
So far, everything has worked fine.
And now, the called party hangs up first, so the PSTN switch send a BYE back to SER (because of the Record-Route used in the INVITE). If the Record-Route was absent, the PSTN switch tries to send the BYE direct to 66.77.88.99 (asterisk server), cutting SER out of the loop entirely and leaving the rtpproxy for that call running for a while.
U 2009/10/05 17:45:07.356019 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Max-Forwards: 70 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Supported: timer Content-Length: 0
So now SER has the BYE but SER doesn't know who to send it on to - loose_route() isn't triggered. So the BYE gets sent to the wrong place, no response, PSTN switch repeats BYE several times before SER tells it to stop. The place SER should send the message (66.77.88.99) is in the To: header, but nowhere else, and apparently isn't holding onto such details from the earlier messages.
U 2009/10/05 17:45:07.905334 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Max-Forwards: 70 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Supported: timer Content-Length: 0
...
U 2009/10/05 17:45:35.038148 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Max-Forwards: 70 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Supported: timer Content-Length: 0
U 2009/10/05 17:45:37.354456 206.33.44.55:5060 -> 10.100.20.30:5060 SIP/2.0 408 Request Timeout Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Server: SER (2.0.0-rc1 (x86_64/freebsd)) Content-Length: 0
route{ xlog("L_ERR", "MAIN ROUTE \n method:<%rm> From URI:<%fu> From Tag:<%ft> Destination Set:<%ds> Request's R-URI:<%ru> To URI:<%tu> Received IP:<%Ri> So urce IP:<%si> Source Port:<%sp> Call ID:<%ci> Host's Hostname:<%Hn> Hosts Doma inname:<%Hd> Hosts FQDN <%Hf> Hosts IP <%Hi>");
# first do some initial sanity checks
if (!mf_process_maxfwd_header("10")) { sl_reply("483","Too Many Hops"); break; }
if (msg:len >= max_len ) { sl_reply("513", "Message too big"); break; }
if (loose_route()) { if (src_ip==10.100.20.30) { #Is it outbound? log(1, "Doing loose_route from PSTN\n"); } else { log(1, "Doing loose_route to PSTN\n"); }
t_relay(); break; }
The rest of main is determining direction if there was no loose_route() and here is where it suddenly needs to be told where exactly the BYE message should be sent because the correct destination is one of many possible call sources. Neither of the "Doing loose_route" messages get displayed when the BYE is handled.
Thanks again for suggestions.
Hi Frank, I have already told you what the problem is. If you keep insisting on fixing the Contact before the INVITE goes out of SER, you MUST be able to resolve and route that Contact (sip:3796661000@206.33.44.55:5060) when it comes back (and yes, the port must be correct as well). As you just try to loose route it, SER will forward to the original contact in the INVITE (as that is what is found in the BYE request URI), which is itself. It's not according to the RFC and it sounds to me that you want to do topology hiding. Well, then you need to use a B2BUA. g-)
Frank Durda IV wrote:
Well, I thought this was working, but after more testing, it is still exhibiting the problem I had before. (Some hard-coded routing I put in was concealing the fact that it isn't handling this situation when left on its own.)
In the PSTN gateway model, SER still doesn't know how to cope when a BYE or re-INVITE arrives which has come from the PSTN gateway, and at best it makes a guess as to which is the right destination for the messages. (It usually ends up looping back to itself.) In this case with the packets that are being received, the pstn.cfg example from the documentation doesn't do the right thing, because loose_route() doesn't get triggered for the BYE and re-INVITE messages, so SER is on its own to determine where to forward the messages.
Here is a full example of the messages involved. In my earlier word example I said the original call INVITE could come from four IP addresses, but in real life the number is more like 200 sources. It is still the same problem, be it two source addresses or a million. Which address to choose in this situation?
Almost everything is correctly-relayed back to the correct IP address (66.77.88.99), EXECPT a BYE initiated by the called network (shown), or a re-INVITE initiated by the called network (not shown, but requires the same handling as called-network BYE). If one can be cured, both should start working.
Key addresses in the example: Call initiates via asterisk server at 66.77.88.99 CALL SOURCE SER is 206.33.44.55 PSTN gateway switch is 10.100.20.30 (where BYE comes from) 2.0.0-rc1 (x86_64/freebsd)
I have only included the messages between the SER and PSTN gateway switch, as that is where the trouble starts. If the others are needed, I can get them.
U 2009/10/05 17:44:48.002403 206.33.44.55:5060 -> 10.100.20.30:5060 INVITE sip:9615551212@10.100.20.30 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55 Contact: sip:3796661000@206.33.44.55:5060 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE User-Agent: Asterisk PBX Max-Forwards: 16 Date: Mon, 05 Oct 2009 17:44:47 GMT Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY Supported: replaces Content-Type: application/sdp Content-Length: 435
o=root 27275 27275 IN IP4 206.33.44.66 s=session c=IN IP4 206.33.44.66 t=0 0 m=audio 20366 RTP/AVP 0 3 8 112 5 10 7 97 111 a=rtpmap:0 PCMU/8000 a=rtpmap:3 GSM/8000 a=rtpmap:8 PCMA/8000 a=rtpmap:112 AAL2-G726-32/8000 a=rtpmap:5 DVI4/8000 a=rtpmap:10 L16/8000 a=rtpmap:7 LPC/8000 a=rtpmap:97 iLBC/8000 a=fmtp:97 mode=30 a=rtpmap:111 G726-32/8000 a=silenceSupp:off - - - - a=ptime:20 a=sendrecv a=nortpproxy:yes
U 2009/10/05 17:44:48.004815 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 100 Trying Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Content-Length: 0
U 2009/10/05 17:44:53.956206 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 183 Session Progress Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Contact: sip:9615551212@10.100.20.30 Content-Type: application/sdp Content-Length: 173
v=0 o=- 3463753493 3463753549 IN IP4 10.100.20.30 s=- c=IN IP4 206.33.99.0 t=0 0 m=audio 34530 RTP/AVP 0 a=sendrecv a=ptime:20 a=rtpmap:0 PCMU/8000 a=silenceSupp:off - - - -
U 2009/10/05 17:44:54.855199 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 183 Session Progress Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Contact: sip:9615551212@10.100.20.30 Content-Type: application/sdp Content-Length: 173
v=0 o=- 3463753493 3463753549 IN IP4 10.100.20.30 s=- c=IN IP4 206.33.99.0 t=0 0 m=audio 34530 RTP/AVP 0 a=sendrecv a=ptime:20 a=rtpmap:0 PCMU/8000 a=silenceSupp:off - - - -
U 2009/10/05 17:44:57.125294 10.100.20.30:5060 -> 206.33.44.55:5060 SIP/2.0 200 OK Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 INVITE From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.1b3604dc0be3614c8a5ba10b15c5c39 b.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK32448737;rport=5060 Server: DC-SIP/2.0 Supported: timer Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Contact: sip:9615551212@10.100.20.30 Content-Type: application/sdp Content-Length: 173
v=0 o=- 3463753493 3463753549 IN IP4 10.100.20.30 s=- c=IN IP4 206.33.99.0 t=0 0 m=audio 34530 RTP/AVP 0 a=sendrecv a=ptime:20 a=rtpmap:0 PCMU/8000 a=silenceSupp:off - - - -
U 2009/10/05 17:44:57.187498 206.33.44.55:5060 -> 10.100.20.30:5060 ACK sip:9615551212@10.100.20.30:5060 SIP/2.0 Record-Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Via: SIP/2.0/UDP 206.33.44.55;branch=z9hG4bK17e4.cb89b9e25754fc653a32363a1ba12e5 9.0 Via: SIP/2.0/UDP 66.77.88.99:5060;branch=z9hG4bK6a6bf681;rport=5060 From: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 To: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 Contact: sip:3796661000@206.33.44.55:5060 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 CSeq: 102 ACK User-Agent: Asterisk PBX Max-Forwards: 16 Content-Length: 0
So far, everything has worked fine.
And now, the called party hangs up first, so the PSTN switch send a BYE back to SER (because of the Record-Route used in the INVITE). If the Record-Route was absent, the PSTN switch tries to send the BYE direct to 66.77.88.99 (asterisk server), cutting SER out of the loop entirely and leaving the rtpproxy for that call running for a while.
U 2009/10/05 17:45:07.356019 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Max-Forwards: 70 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Supported: timer Content-Length: 0
So now SER has the BYE but SER doesn't know who to send it on to - loose_route() isn't triggered. So the BYE gets sent to the wrong place, no response, PSTN switch repeats BYE several times before SER tells it to stop. The place SER should send the message (66.77.88.99) is in the To: header, but nowhere else, and apparently isn't holding onto such details from the earlier messages.
U 2009/10/05 17:45:07.905334 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Max-Forwards: 70 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Supported: timer Content-Length: 0
...
U 2009/10/05 17:45:35.038148 10.100.20.30:5060 -> 206.33.44.55:5060 BYE sip:3796661000@206.33.44.55:5060 SIP/2.0 Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Max-Forwards: 70 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Route: sip:206.33.44.55;ftag=as33ea0360;lr=on Supported: timer Content-Length: 0
U 2009/10/05 17:45:37.354456 206.33.44.55:5060 -> 10.100.20.30:5060 SIP/2.0 408 Request Timeout Via: SIP/2.0/UDP 10.100.20.30;branch=z9hG4bK+ffc8b51a07f0b4336d0443eee0ed0b5e+00 0a0283+1 Call-ID: 23cfb70d5362a5180aeb5048470591fc@66.77.88.99 From: sip:9615551212@206.33.44.55;tag=000a0283+1+68bb002b+5fee0f2 To: "TROUBLESHOOTING 1000" sip:3796661000@66.77.88.99;tag=as33ea0360 CSeq: 920677113 BYE Server: SER (2.0.0-rc1 (x86_64/freebsd)) Content-Length: 0
route{ xlog("L_ERR", "MAIN ROUTE \n method:<%rm> From URI:<%fu> From Tag:<%ft> Destination Set:<%ds> Request's R-URI:<%ru> To URI:<%tu> Received IP:<%Ri> So urce IP:<%si> Source Port:<%sp> Call ID:<%ci> Host's Hostname:<%Hn> Hosts Doma inname:<%Hd> Hosts FQDN <%Hf> Hosts IP <%Hi>");
# first do some initial sanity checks
if (!mf_process_maxfwd_header("10")) { sl_reply("483","Too Many Hops"); break; } if (msg:len >= max_len ) { sl_reply("513", "Message too big"); break; } if (loose_route()) { if (src_ip==10.100.20.30) { #Is it outbound? log(1, "Doing loose_route from PSTN\n"); } else { log(1, "Doing loose_route to PSTN\n"); } t_relay(); break; }
The rest of main is determining direction if there was no loose_route() and here is where it suddenly needs to be told where exactly the BYE message should be sent because the correct destination is one of many possible call sources. Neither of the "Doing loose_route" messages get displayed when the BYE is handled.
Thanks again for suggestions.