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