I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I suspect mine is the same problem as I have two UAs registered so the initial dset is two places and then the append_branch on timeout is just the voicemail uri.
BTW, I am doing this with asterisk for the usual DTMF access reasons (altough I haven't yet figured out how to map sip:alan@columbia.edu to DTMF. Maybe I'll have to give up and do numeric mailboxes:-( I am rewriting with a prefix of "vm*u" before punting over to asterisk which has exten => _vm*u.,1,Wait,1 exten => _vm*u.,2,Voicemail(${EXTEN:3}) exten => _vm*u.,3,Goto(#,1)
Any pointers would be appreciated. My not-yet-complete ser.cfg is attached (not yet punting voicemail for unregistered subscribers; just registered subscribers who time out the invite).
/a
# # $Id: ser.cfg,v 1.21.2.1 2003/07/30 16:46:18 andrei Exp $ # # simple quick-start config script #
# ----------- global configuration parameters ------------------------
debug=2 # debug level (cmd line: -dddddddddd) fork=yes log_stderror=no # (cmd line: -E) #listen=128.59.39.127
check_via=yes # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) port=5060 children=4 fifo="/tmp/ser_fifo" alias="columbia.edu" # ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database loadmodule "/usr/lib/ser/modules/mysql.so" loadmodule "/usr/lib/ser/modules/acc.so" loadmodule "/usr/lib/ser/modules/sl.so" loadmodule "/usr/lib/ser/modules/tm.so" loadmodule "/usr/lib/ser/modules/rr.so" loadmodule "/usr/lib/ser/modules/maxfwd.so" loadmodule "/usr/lib/ser/modules/usrloc.so" loadmodule "/usr/lib/ser/modules/registrar.so"
# Uncomment this if you want digest authentication # mysql.so must be loaded ! loadmodule "/usr/lib/ser/modules/auth.so" loadmodule "/usr/lib/ser/modules/auth_db.so"
loadmodule "/usr/lib/ser/modules/exec.so"
# ----------------- setting module-specific parameters --------------- # -- transaction timers -- modparam("tm", "fr_inv_timer", 15 ) modparam("tm", "fr_timer", 10 )
# -- usrloc params -- # modparam("usrloc", "db_mode", 2) modparam("usrloc", "timer_interval", 10)
# -- auth params -- modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password")
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- acc params -- modparam("acc", "log_level", 1) modparam("acc", "log_flag", 1 ) modparam("acc", "log_missed_flag", 2) # ------------------------- request routing logic -------------------
# main routing logic
route{
/* ********* ROUTINE CHECKS ********************************** */ # 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 > max_len ) { sl_send_reply("513", "Message too big"); break; };
lookup("aliases");
# 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 record_route(); # loose-route processing if (loose_route()) { t_relay(); break; };
setflag(2);
# if the request is for other domain use UsrLoc # (in case, it does not work, use the following command # with proper names and addresses in it) if (uri=~"^sip:(.+@)?columbia.edu") {
if (method=="REGISTER") { log(1, "REGISTER received\n"); if (!www_authorize("columbia.edu", "subscriber")) { www_challenge("columbia.edu", "0"); break; };
save("location"); break; };
/* ********** Dial out to PSTN logic ************* */
# 5 Digit dialing, interior calls if (uri=~"^sip:[1347][0-9]{4}@columbia.edu") { rewritehostport("128.59.59.242:5060"); log(1,"5 digit expression match"); route(2); break; };
# 10 Digit dialing with outlide line if (uri=~"^sip:931[0-9]{10}@columbia.edu") { if(!(src_ip=="128.59.59.242") & !(proxy_authorize("columbia.edu","subscriber"))) { proxy_challenge("columbia.edu", "1"); break;
} else { rewritehostport("128.59.59.242:5060"); log(1," 93 Outside line with 10 digit expression match"); route(2); break; }; };
/* voicemail access */ if (uri=~"^sip:*86@columbia.edu" |uri=~"^sip:vm@columbia.edu" |uri=~"^sip:voicemail@columbia.edu") { route(3); break; };
# native SIP destinations are handled using our USRLOC DB if (!lookup("location")) { if (!exec_dset("/etc/ser/sipldap")) { sl_send_reply("404", "Not Found"); break; } else { log(1," sipldap call"); }; }; #!lookup
};
if (method == "INVITE") { t_on_failure("1"); }; # forward to current uri now; use stateful forwarding; that # works reliably even if we forward from TCP to UDP if (!t_relay()) { sl_reply_error(); }; }
route[2] { log(1,"route[2]:SIP-to-PSTN call routed"); if (!t_relay()) { sl_reply_error(); }; } # ---- voicemail user access ---- route[3] { rewritehostport("127.0.0.1:5069"); log(1,"voicemail access"); if (!t_relay()) { sl_reply_error(); }; } # ------------- handling of unregistered user ------------------ route[4] {
log(1,"route[4]: user not registered"); # non-Voip -- just send "off-line" if (!(method == "INVITE" || method == "ACK" || method == "CANCEL")) { sl_send_reply("404", "Not Found"); break; };
# not voicemail subscriber # if (!isflagset(4)) { # sl_send_reply("404", "Not Found and no voicemail turned on"); # break; # };
# forward to voicemail now prefix("vm*u"); rewritehostport("127.0.0.1:5069"); t_relay_to_udp("127.0.0.1", "5069"); } failure_route[1] { # transfer to asterisk voicemail with uMAILBOX for unavailable. # sip:USER@columbia.edu -> sip:vm*uUSER@127.0.0.1:5069 t_on_failure("2"); prefix("vm*u"); rewritehostport("127.0.0.1:5069"); append_branch(); log(1,"redirection to voicemail\n"); t_relay(); }
failure_route[2] { # forwarding failed (voicemail down?) log(1,"voicemail failed\n"); t_reply("500","Weasels have eaten voicemail again"); }
At 08:58 PM 12/19/2003, Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I think it is a msitake in log severity and it should be softened to a warning. What possibly happens is that a UAS times out at the same time when the call is canceled, and it sends 408 timeout and milisecond later a 487 in response to CANCEL... What UAS did you use?
Generaly, such issues are easier to capture if you keep track of all SIP passing
your site. I think that's a very good practice. If you get me message dumps, I will try to verify what really happened.
Regarding voicemail: SEMS supports voicemail2email. As the number of people interested in IVR grows, there is now a first IVR version of voicemail too -- but this piece of work has never been really tested.
-jiri
Jiri Kuthan wrote:
At 08:58 PM 12/19/2003, Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I think it is a msitake in log severity and it should be softened to a warning. What possibly happens is that a UAS times out at the same time when the call is canceled, and it sends 408 timeout and milisecond later a 487 in response to CANCEL... What UAS did you use?
Both UAs are cisco 7960's (POS3-04-3-00). I don't see why either would time out. It's only 15 seconds for fr_inv_timer. I also just tested with another singly-registered user and the error still happens so it's not a multiple dset thing.
Generaly, such issues are easier to capture if you keep track of all SIP passing
your site. I think that's a very good practice. If you get me message dumps, I will try to verify what really happened.
Part of the problem is since asterisk is running on localhost I won't be able to get captures for that. I suppose I could move it to another machine just to help get some tcpdumps. I'll do that and send along.
Regarding voicemail: SEMS supports voicemail2email. As the number of people interested in IVR grows, there is now a first IVR version of voicemail too -- but this piece of work has never been really tested.
I'll be happy to test it, but you need one of the canned IVR messages to be "Weasels have eaten our phone system" before you'll see a mass exodus from asterisk to sems;-)
-jiri
Jiri,
The tcpdump is at http://www.columbia.edu/~alan/ser.tcpdump Here's the corresponding ser syslog:
Dec 19 16:16:38 ren kernel: eth0: Setting promiscuous mode. Dec 19 16:16:38 ren kernel: device eth0 entered promiscuous mode Dec 19 16:16:56 ren /usr/sbin/ser[5693]: ACC: call missed: method=INVITE, i-uri=sip:17548@128.59.39.127;user=phone;phone-context=private, o-uri=sip:alan@68.198.11.112:5060, call_id=798FB767-319F11D8-B06B89D2-F2E2B15E@128.59.59.242, from="43754" sip:43754@128.59.59.242, code=408 Request Timeout Dec 19 16:16:56 ren /usr/sbin/ser[5693]: redirection to voicemail Dec 19 16:16:56 ren /usr/sbin/ser[5676]: ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487 Dec 19 16:16:56 ren /usr/sbin/ser[5681]: ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487 Dec 19 16:17:19 ren kernel: device eth0 left promiscuous mode
The timestamp in the log corresponds to the 487's coming back from the 7960 phones.
Asterisk is running on 128.59.39.163 in this trace... (Ignore the couple of transactions from some failed REGISTERs for phones that we haven't configured into ser yet.)
/a
Alan Crosswell wrote:
Jiri Kuthan wrote:
At 08:58 PM 12/19/2003, Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I think it is a msitake in log severity and it should be softened to a warning. What possibly happens is that a UAS times out at the same time when the call is canceled, and it sends 408 timeout and milisecond later a 487 in response to CANCEL... What UAS did you use?
Both UAs are cisco 7960's (POS3-04-3-00). I don't see why either would time out. It's only 15 seconds for fr_inv_timer. I also just tested with another singly-registered user and the error still happens so it's not a multiple dset thing.
Generaly, such issues are easier to capture if you keep track of all SIP passing
your site. I think that's a very good practice. If you get me message dumps, I will try to verify what really happened.
Part of the problem is since asterisk is running on localhost I won't be able to get captures for that. I suppose I could move it to another machine just to help get some tcpdumps. I'll do that and send along.
Regarding voicemail: SEMS supports voicemail2email. As the number of people interested in IVR grows, there is now a first IVR version of voicemail too -- but this piece of work has never been really tested.
I'll be happy to test it, but you need one of the canned IVR messages to be "Weasels have eaten our phone system" before you'll see a mass exodus from asterisk to sems;-)
-jiri
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
Alan,
thanks -- the call-flow looks fine, I looked at the source code and it seems to be just a stupid warning.
-jiri
At 10:29 PM 12/19/2003, Alan Crosswell wrote:
Jiri,
The tcpdump is at http://www.columbia.edu/~alan/ser.tcpdump Here's the corresponding ser syslog:
Dec 19 16:16:38 ren kernel: eth0: Setting promiscuous mode. Dec 19 16:16:38 ren kernel: device eth0 entered promiscuous mode Dec 19 16:16:56 ren /usr/sbin/ser[5693]: ACC: call missed: method=INVITE, i-uri=sip:17548@128.59.39.127;user=phone;phone-context=private, o-uri=sip:alan@68.198.11.112:5060, call_id=798FB767-319F11D8-B06B89D2-F2E2B15E@128.59.59.242, from="43754" sip:43754@128.59.59.242, code=408 Request Timeout Dec 19 16:16:56 ren /usr/sbin/ser[5693]: redirection to voicemail Dec 19 16:16:56 ren /usr/sbin/ser[5676]: ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487 Dec 19 16:16:56 ren /usr/sbin/ser[5681]: ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487 Dec 19 16:17:19 ren kernel: device eth0 left promiscuous mode
The timestamp in the log corresponds to the 487's coming back from the 7960 phones.
Asterisk is running on 128.59.39.163 in this trace... (Ignore the couple of transactions from some failed REGISTERs for phones that we haven't configured into ser yet.)
/a
Alan Crosswell wrote:
Jiri Kuthan wrote:
At 08:58 PM 12/19/2003, Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I think it is a msitake in log severity and it should be softened to a warning. What possibly happens is that a UAS times out at the same time when the call is canceled, and it sends 408 timeout and milisecond later a 487 in response to CANCEL... What UAS did you use?
Both UAs are cisco 7960's (POS3-04-3-00). I don't see why either would time out. It's only 15 seconds for fr_inv_timer. I also just tested with another singly-registered user and the error still happens so it's not a multiple dset thing.
Generaly, such issues are easier to capture if you keep track of all SIP passing
your site. I think that's a very good practice. If you get me message dumps, I will try to verify what really happened.
Part of the problem is since asterisk is running on localhost I won't be able to get captures for that. I suppose I could move it to another machine just to help get some tcpdumps. I'll do that and send along.
Regarding voicemail: SEMS supports voicemail2email. As the number of people interested in IVR grows, there is now a first IVR version of voicemail too -- but this piece of work has never been really tested.
I'll be happy to test it, but you need one of the canned IVR messages to be "Weasels have eaten our phone system" before you'll see a mass exodus from asterisk to sems;-)
-jiri
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
-- Jiri Kuthan http://iptel.org/~jiri/
At 09:39 PM 12/19/2003, Alan Crosswell wrote:
Part of the problem is since asterisk is running on localhost I won't be able to get captures for that. I suppose I could move it to another machine just to help get some tcpdumps. I'll do that and send along.
Thank you, that would be interesting to learn what happens. BTW, in some distributions tcpdump can spoof all interfaces.
Regarding voicemail: SEMS supports voicemail2email. As the number of people interested in IVR grows, there is now a first IVR version of voicemail too -- but this piece of work has never been really tested.
I'll be happy to test it, but you need one of the canned IVR messages to be "Weasels have eaten our phone system"
If that's just about announcements, you can play them with SEMS too.
-jiri
I've found that the whole system works better when you don't use failure_route() to do "time out" style voicemail.
I have a test setup where I just add a call to Asterisk immediately if the user is registered (has location entry) with a special prefix that gets matched in the * extensions.conf file, and causes * to simply wait for X seconds before answering. If the calee phone(s) is answered, SER cancels the call to * and any other phones registered to the user. If no phones are answered, * answers and sends the call to voicemail.
For whatever reason, this approach seems more stable so far, and seems more compatible with more phones, etc, than the failure_route approach. For instance, if you have a locations entry that points a user to another user, or more than one user (e.g. mainline@domain.com -> receptionist@domain.com -> receptionist@phone-IP:port), SER seems to get confused and sends a CANCEL to the voicemail system you've just triggered the INVITE to in your failure_route. When doing it the other way, it doesn't seem to have this problem.
As for mapping user names to numeric extensions in Asterisk, I wrote an AGI script which does this by reverse-mapping the username to aliases in the SER script. It requires that your users have numerical extensions assigned in the SER aliases database (e.g. 1234 -> joe@domain.com). If there are multiple #s mapped to the user, it just returns the lowest one. Not sure if I can give this out though, since I wrote it for a client.
- Jim
Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I suspect mine is the same problem as I have two UAs registered so the initial dset is two places and then the append_branch on timeout is just the voicemail uri.
BTW, I am doing this with asterisk for the usual DTMF access reasons (altough I haven't yet figured out how to map sip:alan@columbia.edu to DTMF. Maybe I'll have to give up and do numeric mailboxes:-( I am rewriting with a prefix of "vm*u" before punting over to asterisk which has exten => _vm*u.,1,Wait,1 exten => _vm*u.,2,Voicemail(${EXTEN:3}) exten => _vm*u.,3,Goto(#,1)
Any pointers would be appreciated. My not-yet-complete ser.cfg is attached (not yet punting voicemail for unregistered subscribers; just registered subscribers who time out the invite).
/a
# # $Id: ser.cfg,v 1.21.2.1 2003/07/30 16:46:18 andrei Exp $ # # simple quick-start config script #
# ----------- global configuration parameters ------------------------
debug=2 # debug level (cmd line: -dddddddddd) fork=yes log_stderror=no # (cmd line: -E) #listen=128.59.39.127
check_via=yes # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) port=5060 children=4 fifo="/tmp/ser_fifo" alias="columbia.edu" # ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database loadmodule "/usr/lib/ser/modules/mysql.so" loadmodule "/usr/lib/ser/modules/acc.so" loadmodule "/usr/lib/ser/modules/sl.so" loadmodule "/usr/lib/ser/modules/tm.so" loadmodule "/usr/lib/ser/modules/rr.so" loadmodule "/usr/lib/ser/modules/maxfwd.so" loadmodule "/usr/lib/ser/modules/usrloc.so" loadmodule "/usr/lib/ser/modules/registrar.so"
# Uncomment this if you want digest authentication # mysql.so must be loaded ! loadmodule "/usr/lib/ser/modules/auth.so" loadmodule "/usr/lib/ser/modules/auth_db.so"
loadmodule "/usr/lib/ser/modules/exec.so"
# ----------------- setting module-specific parameters --------------- # -- transaction timers -- modparam("tm", "fr_inv_timer", 15 ) modparam("tm", "fr_timer", 10 )
# -- usrloc params -- # modparam("usrloc", "db_mode", 2) modparam("usrloc", "timer_interval", 10)
# -- auth params -- modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password")
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- acc params -- modparam("acc", "log_level", 1) modparam("acc", "log_flag", 1 ) modparam("acc", "log_missed_flag", 2) # ------------------------- request routing logic -------------------
# main routing logic
route{
/* ********* ROUTINE CHECKS ********************************** */
# 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 > max_len ) { sl_send_reply("513", "Message too big"); break; };
lookup("aliases");
# 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 record_route();
# loose-route processing if (loose_route()) { t_relay(); break; };
setflag(2);
# if the request is for other domain use UsrLoc # (in case, it does not work, use the following command # with proper names and addresses in it) if (uri=~"^sip:(.+@)?columbia.edu") {
if (method=="REGISTER") { log(1, "REGISTER received\n"); if (!www_authorize("columbia.edu", "subscriber")) { www_challenge("columbia.edu", "0"); break; }; save("location"); break; };
/* ********** Dial out to PSTN logic ************* */
# 5 Digit dialing, interior calls if (uri=~"^sip:[1347][0-9]{4}@columbia\.edu") { rewritehostport("128.59.59.242:5060"); log(1,"5 digit expression match"); route(2); break; }; # 10 Digit dialing with outlide line if (uri=~"^sip:931[0-9]{10}@columbia\.edu") { if(!(src_ip=="128.59.59.242") & !(proxy_authorize("columbia.edu","subscriber"))) { proxy_challenge("columbia.edu", "1"); break; } else { rewritehostport("128.59.59.242:5060"); log(1," 93 Outside line with 10 digit expression match"); route(2); break; }; };
/* voicemail access */ if (uri=~"^sip:*86@columbia.edu" |uri=~"^sip:vm@columbia.edu" |uri=~"^sip:voicemail@columbia.edu") { route(3); break; };
# native SIP destinations are handled using our USRLOC DB if (!lookup("location")) { if (!exec_dset("/etc/ser/sipldap")) { sl_send_reply("404", "Not Found"); break; } else { log(1," sipldap call"); }; }; #!lookup
};
if (method == "INVITE") { t_on_failure("1"); }; # forward to current uri now; use stateful forwarding; that # works reliably even if we forward from TCP to UDP if (!t_relay()) { sl_reply_error(); };
}
route[2] { log(1,"route[2]:SIP-to-PSTN call routed"); if (!t_relay()) { sl_reply_error(); }; } # ---- voicemail user access ---- route[3] { rewritehostport("127.0.0.1:5069"); log(1,"voicemail access"); if (!t_relay()) { sl_reply_error(); }; } # ------------- handling of unregistered user ------------------ route[4] {
log(1,"route[4]: user not registered"); # non-Voip -- just send "off-line" if (!(method == "INVITE" || method == "ACK" || method == "CANCEL")) { sl_send_reply("404", "Not Found"); break; };
# not voicemail subscriber
# if (!isflagset(4)) { # sl_send_reply("404", "Not Found and no voicemail turned on"); # break; # };
# forward to voicemail now
prefix("vm*u"); rewritehostport("127.0.0.1:5069"); t_relay_to_udp("127.0.0.1", "5069"); } failure_route[1] { # transfer to asterisk voicemail with uMAILBOX for unavailable. # sip:USER@columbia.edu -> sip:vm*uUSER@127.0.0.1:5069 t_on_failure("2"); prefix("vm*u"); rewritehostport("127.0.0.1:5069"); append_branch(); log(1,"redirection to voicemail\n"); t_relay(); }
failure_route[2] { # forwarding failed (voicemail down?) log(1,"voicemail failed\n"); t_reply("500","Weasels have eaten voicemail again"); }
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
At 02:39 AM 12/20/2003, Jim Burwell wrote:
For instance, if you have a locations entry that points a user to another user, or more than one user (e.g. mailto:mainline@domain.commainline@domain.com -> mailto:receptionist@domain.comreceptionist@domain.com -> receptionist@phone-IP:port), SER seems to get confused and sends a CANCEL to the voicemail system you've just triggered the INVITE to in your failure_route.
Whats is exactly the issue? I mean SER sends CANCEL when timeout strikes or when some of the branches completes. If you decide to forward to voicemail, other pending branches will be cancelled and it is good so. If you maintain the CANCEL is sent to voicemail (as opposed to pending branhces), send me your message dumps.
-jiri
I'm going to try to explain this to Jiri and the list. I've changed the subject since it will diverge from the original.
What we're trying to do is set something up in SER which allows a single URI/phone # to be called, and have it ring multiple user's phones, which, if they go unanswered, will go to the original dialed user's voice mail box (which is a 'common' VM account that multiple users have access to). It also needs to be flexible in that any user can put themselves on and take themselves off the 'list' of users whose phones will ring when this number is dialed. And lastly, but not leastly, it also needs to be very user friendly, so users with no knowledge of SER/SIP can add/remove themselves from this list.
I'd like to do this with as little custom programming as possible. Preferably, none. I've been trying to get this working with SER/SERWeb/Asterisk/SEMS "natively". I realize this may not be possible without some coding, and that SER wasn't meant to do everything every user wanted 'out of the box' without coding, etc.
The main problem is, with the current setup of SEMS/SERWeb, and the current examples of voice mail setup, there is a presumption that the original called URI is the same person, and rings one or more of this same person's phones. But as explained above, we want to dial one user, and have it actually ring a bunch of other users phones, which can change dynamically.
The simplest way to implement this is to have whoever wants to receive the calls have their phones register themselves as the "main" user. This actually works fine with existing setups. The problem with this is that it's not very user friendly or practical, since not all SIP phones allow multiple user registration, which would require each user who wants to do this to have a separate phone reserved for this purpose. It's also somewhat inconvenient for a user with multiple phones to add/remove themselves from the registration for this "main" user on every phone every time they need to do it (like when they go to lunch, etc). It's far nicer for a user to be able to log into a central location and add their personal URI there, and have their already registered phones ring. I've though of hacking SERWeb and adding some functionality which would look up the users' current contacts in location and simply add them to the "main" user's contact list, but then realized that they'd have to update this every time they turned off a phone, added a new phone, etc.
We tried doing this by having the users register their contacts via SERWeb by logging into the "main" user's account and adding contacts like "user1@domain.tld", "user2@domain.tld". I call these sorts of locations entries "indirect contacts", since they're not destined for a different SIP domain, but they're also not pointing at the users' phones. Instead, they point back at other SER location entries which in turn point to the actual phones (hence, indirect). They wind up causing SER to relay the call back to itself. Example: main@domain.tld -> user1@domain.tld -> user1@phoneIP:port. These sorts of location entries would actually work for ringing the phones, etc, but would fail when it timed out to voice mail, for reasons both clear and unclear when the SIP messages were analyzed.
Analyzing the SIP messages, the failure reasons varied depending on whether there was a single contact, multiple contacts, and which "time-out method" was used, etc. For the case of multiple contacts, the routing logic wound up doing multiple failure_routes for voice mail for the same phone call, etc, which is bad. If there was a single contact, and we were using the failure_route method of timing out, SER would send a CANCEL message to the VM system within a second of issuing the INVITE from the added VM branch (as if it couldn't differentiate between the original URI, indirect contact, and final contact branches of the call, and the added VM branch, or was simply choosing the wrong ones to CANCEL).
However, if the "have Asterisk wait" method of timing out were used with a single contact, SER would be fine and the call would be answered by the VM system (unfortunately not for the original URI user, but for the "ringing phone" user, which makes sense when the routing logic is examined). If the call involved multiple contacts, this method would fail, not because of SER, but because Asterisk would misinterpret SER's CANCEL message for one user for another, and stop responding to the call it just issued an OK for. This is likely because a double INVITE was issued (for each branch of the final destination set), and confused Asterisk.
The problem is, for this sort of set up is that there's no easy 'native' way to 'mark' the particular original URI, and resulting indirect URIs for the special treatment by the routing logic without hard coding them into ser.cfg, or using exec_dset() and some other of database of special users, etc, for which their would need to be a UI front end written (and which could be an expensive operation because of the "exec_dset").
The new approach I'm implementing right now is to use special prefixes for these types of users so that SER will treat them differently in the routing logic, and "do the proper thing". I'm hoping this will result in SER keeping its cookies, etc, and CANCELing the right calls when VM picks up.
Another stumbling block I see already is the case of handling "indirect contacts" which don't have a final location entry. E.g., the user logged out of the SIP domain, but didn't remove his indirect contact entry. When SER relays the call back to itself, and goes to lookup the location, it won't find one and normally it'd issue a "404". The desired action in this case is to forget about that particular contact, and just ring any other contacts that exist without having it tear down the entire call, or instantly shunt it off to voice mail (unless of course, there are no 'final contacts' available to ring). Tricky, especially since I'm still learning all this stuff.
Hopefully this will explain what I'm trying to do, the problems I've been having, etc. Perhaps I'm taking a completely wrong approach and someone will just say "just do it this way dummy!". :-)
- Jim
Jiri Kuthan wrote:
At 02:39 AM 12/20/2003, Jim Burwell wrote:
For instance, if you have a locations entry that points a user to another user, or more than one user (e.g. mailto:mainline@domain.commainline@domain.com -> mailto:receptionist@domain.comreceptionist@domain.com -> receptionist@phone-IP:port), SER seems to get confused and sends a CANCEL to the voice mail system you've just triggered the INVITE to in your failure_route.
Whats is exactly the issue? I mean SER sends CANCEL when timeout strikes or when some of the branches completes. If you decide to forward to voice mail, other pending branches will be cancelled and it is good so. If you maintain the CANCEL is sent to voice mail (as opposed to pending branhces), send me your message dumps.
-jiri
Jim,
I think you should first make yourself better with the SIP technology, especially if you indicate that you have customers to whom you would like to market it. In particularly, the concepts of user location and forking are important to you. I'm trying to respond to some of your questions, but such quick hints are not a good substitute for thorough understanding. More inline.
-jiri
At 08:54 AM 12/21/2003, Jim Burwell wrote:
I'm going to try to explain this to Jiri and the list. I've changed the subject since it will diverge from the original.
What we're trying to do is set something up in SER which allows a single URI/phone # to be called, and have it ring multiple user's phones, which, if they go unanswered, will go to the original dialed user's voice mail box (which is a 'common' VM account that multiple users have access to). It also needs to be flexible in that any user can put themselves on and take themselves off the 'list' of users whose phones will ring when this number is dialed. And lastly, but not leastly, it also needs to be very user friendly, so users with no knowledge of SER/SIP can add/remove themselves from this list.
That's all simple -- let the users register with the same address, that's it. If you would like to provision some users manualy, use serweb or serctl to manipulate contacts associated with the address. All the contacts will be ringing on incoming calls.
I'd like to do this with as little custom programming as possible. Preferably, none. I've been trying to get this working with SER/SERWeb/Asterisk/SEMS "natively". I realize this may not be possible without some coding, and that SER wasn't meant to do everything every user wanted 'out of the box' without coding, etc.
The main problem is, with the current setup of SEMS/SERWeb, and the current examples of voice mail setup, there is a presumption that the original called URI is the same person, and rings one or more of this same person's phones. But as explained above, we want to dial one user, and have it actually ring a bunch of other users phones, which can change dynamically.
I'm not aware of anything what would prohibit you from doing so.
The simplest way to implement this is to have whoever wants to receive the calls have their phones register themselves as the "main" user. This actually works fine with existing setups. The problem with this is that it's not very user friendly or practical, since not all SIP phones allow multiple user registration, which would require each user who wants to do this to have a separate phone reserved for this purpose. It's also somewhat inconvenient for a user with multiple phones to add/remove themselves from the registration for this "main" user on every phone every time they need to do it (like when they go to lunch, etc). It's far nicer for a user to be able to log into a central location and add their personal URI there, and have their already registered phones ring. I've though of hacking SERWeb and adding some functionality which would look up the users' current contacts in location and simply add them to the "main" user's contact list,
Why have you thought of hacking serweb, when contact manipulation is already there?
but then realized that they'd have to update this every time they turned off a phone, added a new phone, etc.
I'm not sure you completely understand the user location model. SIP address, so called address of record (AOR), can be linked to any number of contacts. There are handled by phones' REGISTER requests, but also any other out-of-band method, such as serweb. Obviously, if you wish the contact list to change, than someone has to do the modification job. Either the telephone using REGISTER, or a user through serweb.
For examples, jiri@iptel.org may be provisioned to link to contacts: - sip:jiri@10.0.0.1 (my phone) - sip:secretary@iptel.org (calls to jiri should ring there too -- note a contact address may ne another AOR) - sip:1234@iptel.org (my PBX phone as well).
All these contacts have some time-to-live. Telephones use one hour by default, provisioning interface allows you to set infinite time if you wish.
We tried doing this by having the users register their contacts via SERWeb by logging into the "main" user's account and adding contacts like mailto:user1@domain.tld"user1@domain.tld", mailto:user2@domain.tld"user2@domain.tld". I call these sorts of locations entries "indirect contacts", since they're not destined for a different SIP domain, but they're also not pointing at the users' phones. Instead, they point back at other SER location entries which in turn point to the actual phones (hence, indirect). They wind up causing SER to relay the call back to itself. Example: mailto:main@domain.tldmain@domain.tld -> mailto:user1@domain.tlduser1@domain.tld -> user1@phoneIP:port. These sorts of location entries would actually work for ringing the phones, etc, but would fail when it timed out to voice mail, for reasons both clear and unclear when the SIP messages were analyzed.
That's the way to do it. If you think there is an error, then come up with a case.
Analyzing the SIP messages, the failure reasons varied depending on whether there was a single contact, multiple contacts, and which "time-out method" was used, etc. For the case of multiple contacts, the routing logic wound up doing multiple failure_routes for voice mail for the same phone call, etc, which is bad. If there was a single contact, and we were using the failure_route method of timing out, SER would send a CANCEL message to the VM system within a second of issuing the INVITE from the added VM branch (as if it couldn't differentiate between the original URI, indirect contact, and final contact branches of the call, and the added VM branch, or was simply choosing the wrong ones to CANCEL).
Sounds like a SER miconfiguration. That's however hard to judge without seeing message dumps, config files. See www.iptel.org/ser/problems/ for information on how meaningful problem reporting is supposed to look like. Hopefuly, someone on the mailing list will have cycles to go through your information.
Another stumbling block I see already is the case of handling "indirect contacts" which don't have a final location entry. E.g., the user logged out of the SIP domain, but didn't remove his indirect contact entry. When SER relays the call back to itself, and goes to lookup the location, it won't find one and normally it'd issue a "404". The desired action in this case is to forget about that particular contact, and just ring any other contacts that exist without having it tear down the entire call, or instantly shunt it off to voice mail (unless of course, there are no 'final contacts' available to ring). Tricky, especially since I'm still learning all this stuff.
Again, I think you wish to make yourself better familiar with SIP (RFC3261). Reponding with 404 to a request to an off-line user is the only correct thing to do for a server. If a request is forked to multiple destinations (this is called "parallel forking") well, then one will return 404, the other branches will keep pending till someone answers.
a@10.0.0.1 ---INVITE----> SER ---+--------------> ringing < 180 | b@10.0.0.1 +---------------> offline < 404 | c@iptel.org +-----------+ | +----------------------| | +--------------------------> offline < 404
In this example, the INVITE will be fokred to a,b,c. a results in rigning phone. b will immediately yield 404. c will result in a spiral through the server and yiled 404 in next step.
So later, b and c branches are gone, only a keeps ringing. If ser is configured to do so, it will CANCEL the branch a) and initate another branch to voicemail eventually.
If you troubleshoot such scenarios, it is important that you understand how transactions are identified. All request branches must include the same Via/branch id prefix, only the suffix differs as it identifies branch in question.
-jiri
Comments in line..
Jiri Kuthan wrote:
Jim,
I think you should first make yourself better with the SIP technology, especially if you indicate that you have customers to whom you would like to market it. In particularly, the concepts of user location and forking are important to you. I'm trying to respond to some of your questions, but such quick hints are not a good substitute for thorough understanding. More inline.
Yes. Granted. I'm no SIP expert, as I already stated in my previous message. My background is in Unix systems administration and Network administration. Like many on this list, I'm still learning about SIP/VOIP technology. I haven't actually had time to plow through the RFC yet, but the SER documentation has a fairly good explanation of what 'location' and 'forking' are. I've also read some of the other documentation from iptel, like the SIP tutorial, etc. But like most things, the devil is in the details, and learning all the subtleties and nuances of SIP is a bit of a learning curve. This is why I occasionally post messages on this list, asking questions and stuff. :-)
Having said that, I think your hints have nudged me in the proper direction for solving this problem.
-jiri
At 08:54 AM 12/21/2003, Jim Burwell wrote:
I'm going to try to explain this to Jiri and the list. I've changed the subject since it will diverge from the original.
What we're trying to do is set something up in SER which allows a single URI/phone # to be called, and have it ring multiple user's phones, which, if they go unanswered, will go to the original dialed user's voice mail box (which is a 'common' VM account that multiple users have access to). It also needs to be flexible in that any user can put themselves on and take themselves off the 'list' of users whose phones will ring when this number is dialed. And lastly, but not leastly, it also needs to be very user friendly, so users with no knowledge of SER/SIP can add/remove themselves from this list.
That's all simple -- let the users register with the same address, that's it. If you would like to provision some users manualy, use serweb or serctl to manipulate contacts associated with the address. All the contacts will be ringing on incoming calls.
Yes. I mentioned this solution in my last message. We're already doing this. But this is inconvenient and not very _user friendly_. It requires the end user, some of whom will be non technical people, to know the dynamically changing IP address and port number of their SIP phones and enter them into SERWeb for the 'group AOR'. They'd also have to repeat this process for every SIP phone they have. Either that, or set up their SIP phones to register both themselves, and the 'group AOR' with SER. Some SIP phones allow this (the Xten soft phones do, for instance), some don't.
What I'd like to do is just have them simply enter "sip:myusername@domain.tld" to cover all their phones without having to go through phone menus and look up IP addresses and ports, etc. This is where I ran into the problems. Using "sip:user@domain" as a contact for the 'group AOR' results in voice mail failure for various reasons I'll try to explain below.
I'd like to do this with as little custom programming as possible. Preferably, none. I've been trying to get this working with SER/SERWeb/Asterisk/SEMS "natively". I realize this may not be possible without some coding, and that SER wasn't meant to do everything every user wanted 'out of the box' without coding, etc.
The main problem is, with the current setup of SEMS/SERWeb, and the current examples of voice mail setup, there is a presumption that the original called URI is the same person, and rings one or more of this same person's phones. But as explained above, we want to dial one user, and have it actually ring a bunch of other users phones, which can change dynamically.
I'm not aware of anything what would prohibit you from doing so.
There's nothing prohibiting it. It's just that voice mail fails when you use location entries which cause forked branches to spiral back through SER instead of being dispatched to a phone, or another SIP router, or PBX, or whatever. I think (hope) that the reason for the failure is because right now, each branch of the forked call is setting up a call to voice mail.
These sorts of branches need special treatment. For instance, for these branches, you shouldn't set up a failure_route to call voice mail upon INVITE timer expiration, since in this special case, it results in multiple branches of the same call calling voice mail, which causes a failure. Only the original group user should set up the voice mail timeout. You also must be careful not to call voice mail immediately if there's no final contact for this user, since you want the other users listed in the group user contact to ring.
The problem I have is figuring out a way to differentiate between a normal call to the user him/herself, and a call to a 'group user' in which this particular user is included in a forked branch. Basically, I need a way to implement the logic: if(user is called directly) { set up voice mail timeout, call voice mail normally if offline; relay call; } else if(user is part of a branch of a group user call) { just relay call or 404 if no contact; }
So far, the idea I've come up with to handle this is to use special prefixes on the contacts usernames which are later stripped off when the branch spirals back through SER. These prefixes would essentially carry state back into SER, telling it in this case not to set up a voice mail timeout for this branch, and not to call voice mail if the branch's contact is off line. Instead, it just strips off the prefix, looks up the URI in the locations table, returns a 404 if offline, and relays the call if location exists. I'm hoping this will work and solve all the problems I'm having with these group addresses.
Are there better ways of doing this ? I cant think of another way to 'mark' these branches, or use ser.cfg code to have it detect this special case. Would "setflag" serve in this case ? I'm not sure if setflag's scope is just for one iteration through the ser.cfg file, or whether it's saved as state for the entire transaction and all associated forked branches. I believe the former is true.
I also previously thought that returning a 404 in the case of having no final contact (offline) would cause the _entire_ call to fail. But after reading your reply, I realize that this shouldn't happen, and returning the 404 is the proper thing to do.
The simplest way to implement this is to have whoever wants to receive the calls have their phones register themselves as the "main" user. This actually works fine with existing setups. The problem with this is that it's not very user friendly or practical, since not all SIP phones allow multiple user registration, which would require each user who wants to do this to have a separate phone reserved for this purpose. It's also somewhat inconvenient for a user with multiple phones to add/remove themselves from the registration for this "main" user on every phone every time they need to do it (like when they go to lunch, etc). It's far nicer for a user to be able to log into a central location and add their personal URI there, and have their already registered phones ring. I've though of hacking SERWeb and adding some functionality which would look up the users' current contacts in location and simply add them to the "main" user's contact list,
Why have you thought of hacking serweb, when contact manipulation is already there?
My idea was to have SERWeb look up the IP:ports of the contacts entered and put them into the group user's contact list to avoid branches spiraling back through SER. A few seconds thought made me realize that this wouldn't work since the IPs could change.
but then realized that they'd have to update this every time they turned off a phone, added a new phone, etc.
I'm not sure you completely understand the user location model. SIP address, so called address of record (AOR), can be linked to any number of contacts. There are handled by phones' REGISTER requests, but also any other out-of-band method, such as serweb. Obviously, if you wish the contact list to change, than someone has to do the modification job. Either the telephone using REGISTER, or a user through serweb.
No. I do understand this. That's what we're having them do now, but it's not user friendly, since they need to enter all of their phones by IP address:port with our present SER configuration for reasons I explained above.
For examples, jiri@iptel.org may be provisioned to link to contacts:
- sip:jiri@10.0.0.1 (my phone)
This works fine, but as I've said requires the user to know the IP/port of his phone(s) and enter it into SERWeb for the group user, or have their phones register for this group user as well as for themselves if the phone supports multiple users.
- sip:secretary@iptel.org (calls to jiri should ring there too -- note
a contact address may ne another AOR)
In our current ser.cfg logic, having a contact like this in your AOR causes VM to fail, for reasons I explained above. This is the problem and the point of my whole post/question to the list.
- sip:1234@iptel.org (my PBX phone as well).
All these contacts have some time-to-live. Telephones use one hour by default, provisioning interface allows you to set infinite time if you wish.
We tried doing this by having the users register their contacts via SERWeb by logging into the "main" user's account and adding contacts like mailto:user1@domain.tld"user1@domain.tld", mailto:user2@domain.tld"user2@domain.tld". I call these sorts of locations entries "indirect contacts", since they're not destined for a different SIP domain, but they're also not pointing at the users' phones. Instead, they point back at other SER location entries which in turn point to the actual phones (hence, indirect). They wind up causing SER to relay the call back to itself. Example: mailto:main@domain.tldmain@domain.tld -> mailto:user1@domain.tlduser1@domain.tld -> user1@phoneIP:port. These sorts of location entries would actually work for ringing the phones, etc, but would fail when it timed out to voice mail, for reasons both clear and unclear when the SIP messages were analyzed.
That's the way to do it. If you think there is an error, then come up with a case.
Yes. I will try to. If this is the way you guys do it at iptel, and it works in the way desired, including voicemail, then the problem is obviously a configuration issue in our ser.cfg file, and not a bug in SER.
However, I remember from some of my experimentation that SER was CANCELing the calls to VM that it just sent an INVITE for when a VM URI was appended in the failure_route.
I'm hoping that this was because the failure_route was not set up at the initial INVITE, but rather at a later iteration when the branch spiraled back through SER. To illustrate:
INVITE -> SER forks to destination set, no failure_route set up -> forked branch enters SER, failure_route set up -> relay to branch contact.
I'm not sure if this would be a problem or not. Regardless of whether it is or not, this is not the desired behavior I want anyway. I need to set up a cfg so that only the original group user gets a VM timeout set, and subsequent contact users don't, as I explained above.
Analyzing the SIP messages, the failure reasons varied depending on whether there was a single contact, multiple contacts, and which "time-out method" was used, etc. For the case of multiple contacts, the routing logic wound up doing multiple failure_routes for voice mail for the same phone call, etc, which is bad. If there was a single contact, and we were using the failure_route method of timing out, SER would send a CANCEL message to the VM system within a second of issuing the INVITE from the added VM branch (as if it couldn't differentiate between the original URI, indirect contact, and final contact branches of the call, and the added VM branch, or was simply choosing the wrong ones to CANCEL).
Sounds like a SER miconfiguration. That's however hard to judge without seeing message dumps, config files. See www.iptel.org/ser/problems/ for information on how meaningful problem reporting is supposed to look like. Hopefuly, someone on the mailing list will have cycles to go through your information.
Yes. I realize it's hard to debug this without this information. I usually include this, but this time I didn't have access to good dumps. I need to reproduce them.
Another stumbling block I see already is the case of handling "indirect contacts" which don't have a final location entry. E.g., the user logged out of the SIP domain, but didn't remove his indirect contact entry. When SER relays the call back to itself, and goes to lookup the location, it won't find one and normally it'd issue a "404". The desired action in this case is to forget about that particular contact, and just ring any other contacts that exist without having it tear down the entire call, or instantly shunt it off to voice mail (unless of course, there are no 'final contacts' available to ring). Tricky, especially since I'm still learning all this stuff.
Again, I think you wish to make yourself better familiar with SIP (RFC3261). Reponding with 404 to a request to an off-line user is the only correct thing to do for a server. If a request is forked to multiple destinations (this is called "parallel forking") well, then one will return 404, the other branches will keep pending till someone answers.
a@10.0.0.1
---INVITE----> SER ---+--------------> ringing < 180 | b@10.0.0.1 +---------------> offline < 404 | c@iptel.org +-----------+ | +----------------------| | +--------------------------> offline < 404
In this example, the INVITE will be fokred to a,b,c. a results in rigning phone. b will immediately yield 404. c will result in a spiral through the server and yiled 404 in next step.
So later, b and c branches are gone, only a keeps ringing. If ser is configured to do so, it will CANCEL the branch a) and initate another branch to voicemail eventually.
If you troubleshoot such scenarios, it is important that you understand how transactions are identified. All request branches must include the same Via/branch id prefix, only the suffix differs as it identifies branch in question.
Ah. I was under the impression that a single 404 for a contact in the group would cancel the whole call, because this seemed to be what was happening when I was troubleshooting.
I also wondered how SIP differentiates between different branches of a call while I was analyzing the dumps. I came to the conclusion that it was the "branch=" suffix in the VIA field, since these were the only items that were consistently in every message sent in the transaction, and unique.
-jiri
- Jim
Jim,
I've been catching up to where you have already been with respect to failure route and the single global fr_inv_timer. It just doesn't work if the same SER is fielding invites for those having voicemail and those not. Before I go ahead and add a Wait 20 to my Asterisk voicemail, I had one other idea I wanted to ask about:
What if I run two ser instances? The main one checks is_user_in("Request-URI", "voicemail") and then punts any Invites for that user to a second ser which implements the fr_inv_timer, t_on_failure, etc. transfer to voicemail. Meanwhile all the non-voicemail subscribers (including stuff sent to our PSTN gateway, etc.) continues to chug along without the timer stuff happening.
Does this sound like a reasonable approach?
/a
Jim Burwell wrote:
I've found that the whole system works better when you don't use failure_route() to do "time out" style voicemail.
I have a test setup where I just add a call to Asterisk immediately if the user is registered (has location entry) with a special prefix that gets matched in the * extensions.conf file, and causes * to simply wait for X seconds before answering. If the calee phone(s) is answered, SER cancels the call to * and any other phones registered to the user. If no phones are answered, * answers and sends the call to voicemail.
For whatever reason, this approach seems more stable so far, and seems more compatible with more phones, etc, than the failure_route approach. For instance, if you have a locations entry that points a user to another user, or more than one user (e.g. mainline@domain.com -> receptionist@domain.com -> receptionist@phone-IP:port), SER seems to get confused and sends a CANCEL to the voicemail system you've just triggered the INVITE to in your failure_route. When doing it the other way, it doesn't seem to have this problem.
As for mapping user names to numeric extensions in Asterisk, I wrote an AGI script which does this by reverse-mapping the username to aliases in the SER script. It requires that your users have numerical extensions assigned in the SER aliases database (e.g. 1234 -> joe@domain.com). If there are multiple #s mapped to the user, it just returns the lowest one. Not sure if I can give this out though, since I wrote it for a client.
- Jim
Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I suspect mine is the same problem as I have two UAs registered so the initial dset is two places and then the append_branch on timeout is just the voicemail uri.
BTW, I am doing this with asterisk for the usual DTMF access reasons (altough I haven't yet figured out how to map sip:alan@columbia.edu to DTMF. Maybe I'll have to give up and do numeric mailboxes:-( I am rewriting with a prefix of "vm*u" before punting over to asterisk which has exten => _vm*u.,1,Wait,1 exten => _vm*u.,2,Voicemail(${EXTEN:3}) exten => _vm*u.,3,Goto(#,1)
Any pointers would be appreciated. My not-yet-complete ser.cfg is attached (not yet punting voicemail for unregistered subscribers; just registered subscribers who time out the invite).
/a
# # $Id: ser.cfg,v 1.21.2.1 2003/07/30 16:46:18 andrei Exp $ # # simple quick-start config script #
# ----------- global configuration parameters ------------------------
debug=2 # debug level (cmd line: -dddddddddd) fork=yes log_stderror=no # (cmd line: -E) #listen=128.59.39.127
check_via=yes # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) port=5060 children=4 fifo="/tmp/ser_fifo" alias="columbia.edu" # ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database loadmodule "/usr/lib/ser/modules/mysql.so" loadmodule "/usr/lib/ser/modules/acc.so" loadmodule "/usr/lib/ser/modules/sl.so" loadmodule "/usr/lib/ser/modules/tm.so" loadmodule "/usr/lib/ser/modules/rr.so" loadmodule "/usr/lib/ser/modules/maxfwd.so" loadmodule "/usr/lib/ser/modules/usrloc.so" loadmodule "/usr/lib/ser/modules/registrar.so"
# Uncomment this if you want digest authentication # mysql.so must be loaded ! loadmodule "/usr/lib/ser/modules/auth.so" loadmodule "/usr/lib/ser/modules/auth_db.so"
loadmodule "/usr/lib/ser/modules/exec.so"
# ----------------- setting module-specific parameters --------------- # -- transaction timers -- modparam("tm", "fr_inv_timer", 15 ) modparam("tm", "fr_timer", 10 )
# -- usrloc params -- # modparam("usrloc", "db_mode", 2) modparam("usrloc", "timer_interval", 10)
# -- auth params -- modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password")
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- acc params -- modparam("acc", "log_level", 1) modparam("acc", "log_flag", 1 ) modparam("acc", "log_missed_flag", 2) # ------------------------- request routing logic -------------------
# main routing logic
route{
/* ********* ROUTINE CHECKS ********************************** */
# 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 > max_len ) { sl_send_reply("513", "Message too big"); break; };
lookup("aliases");
# 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 record_route();
# loose-route processing if (loose_route()) { t_relay(); break; };
setflag(2);
# if the request is for other domain use UsrLoc # (in case, it does not work, use the following command # with proper names and addresses in it) if (uri=~"^sip:(.+@)?columbia.edu") {
if (method=="REGISTER") { log(1, "REGISTER received\n"); if (!www_authorize("columbia.edu", "subscriber")) { www_challenge("columbia.edu", "0"); break; }; save("location"); break; };
/* ********** Dial out to PSTN logic ************* */
# 5 Digit dialing, interior calls if (uri=~"^si"^sip:[1347][0-9]{4}@columbia\.edu") { rewritehostport("128.59.59.242:5060"); log(1,"5 digit expression match"); route(2); break; }; # 10 Digit dialing with outlide line if (uri=~"^si"^sip:931[0-9]{10}@columbia\.edu") { if(!(src_ip=="128.59.59.242") & !(proxy_authorize("columbia.edu","subscriber"))) { proxy_challenge("columbia.edu", "1"); break; } else { rewritehostport("128.59.59.242:5060"); log(1," 93 Outside line with 10 digit expression match"); route(2); break; }; };
/* voicemail access */ if (uri=~"^sip:*86@columbia.edu" |uri=~"^sip:vm@columbia.edu" |uri=~"^sip:voicemail@columbia.edu") { route(3); break; };
# native SIP destinations are handled using our USRLOC DB if (!lookup("location")) { if (!exec_dset("/etc/ser/sipldap")) { sl_send_reply("404", "Not Found"); break; } else { log(1," sipldap call"); }; }; #!lookup
};
if (method == "INVITE") { t_on_failure("1"); }; # forward to current uri now; use stateful forwarding; that # works reliably even if we forward from TCP to UDP if (!t_relay()) { sl_reply_error(); };
}
route[2] { log(1,"route[2]:SIP-to-PSTN call routed"); if (!t_relay()) { sl_reply_error(); }; } # ---- voicemail user access ---- route[3] { rewritehostport("127.0.0.1:5069"); log(1,"voicemail access"); if (!t_relay()) { sl_reply_error(); }; } # ------------- handling of unregistered user ------------------ route[4] {
log(1,"route[4]: user not registered"); # non-Voip -- just send "off-line" if (!(method == "INVITE" || method == "ACK" || method == "CANCEL")) { sl_send_reply("404", "Not Found"); break; };
# not voicemail subscriber
# if (!isflagset(4)) { # sl_send_reply("404", "Not Found and no voicemail turned on"); # break; # };
# forward to voicemail now
prefix("vm*u"); rewritehostport("127.0.0.1:5069"); t_relay_to_udp("127.0.0.1", "5069"); } failure_route[1] { # transfer to asterisk voicemail with uMAILBOX for unavailable. # sip:USER@columbia.edu -> sip:vm*uUSER@127.0.0.1:5069 t_on_failure("2"); prefix("vm*u"); rewritehostport("127.0.0.1:5069"); append_branch(); log(1,"redirection to voicemail\n"); t_relay(); }
failure_route[2] { # forwarding failed (voicemail down?) log(1,"voicemail failed\n"); t_reply("500","Weasels have eaten voicemail again"); }
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
-- +---------------------------------------------------------------------------+ | Jim Burwell - Sr. Systems/Network/Security Engineer, JSBC | +---------------------------------------------------------------------------+ | "I never let my schooling get in the way of my education." - Mark Twain | | "UNIX was never designed to keep people from doing stupid things, because | | that policy would also keep them from doing clever things." - Doug Gwyn | | "Cool is only three letters away from Fool" - Mike Muir, Suicyco | | "..Government in its best state is but a necessary evil; in its worst | | state an intolerable one.." - Thomas Paine, "Common Sense" (1776) | +---------------------------------------------------------------------------+ | Email: jimb@jsbc.cc ICQ UIN: 1695089 | +---------------------------------------------------------------------------+ | Reply problems ? Turn off the "sign" function in email prog. Blame MS. | +---------------------------------------------------------------------------+
Well, in doing this I never had a problem with one SER handling normal and voicemail calls. You just have to implement the proper logic. Basically, the pseudo-code:
IF call is for ME (my SIP domain) THEN { IF callee is NOT online THEN { IF callee is in voicemail group THEN { call VM system immediately with URI modified signaling "answer immediately" break } ELSE (callee is NOT in voicemail group) { return 404 (user not found) break } } ELSE (callee is online) { IF callee is in voicemail group THEN { append destination set including VM system with URI modified signaling "wait before answering" } } }
relay call to dest set
This approach has worked in all my testing. However, it may not be ideal for reasons I mentioned before.
What would be far nicer is having per branch or call timers one could set in the SER script. But in all likelyhood the schizophrenia caused by the conflict of the value proposition of SIP being 'light weight' and 'stateless' conflicting with the reality of SIP requiring state to give us basic real-world functionalities such as accounting and timed-out voicemail will result in this not happening any time soon, IMHO :-).
- Jim
Alan Crosswell wrote:
Jim,
I've been catching up to where you have already been with respect to failure route and the single global fr_inv_timer. It just doesn't work if the same SER is fielding invites for those having voicemail and those not. Before I go ahead and add a Wait 20 to my Asterisk voicemail, I had one other idea I wanted to ask about:
What if I run two ser instances? The main one checks is_user_in("Request-URI", "voicemail") and then punts any Invites for that user to a second ser which implements the fr_inv_timer, t_on_failure, etc. transfer to voicemail. Meanwhile all the non-voicemail subscribers (including stuff sent to our PSTN gateway, etc.) continues to chug along without the timer stuff happening.
Does this sound like a reasonable approach?
/a
Jim Burwell wrote:
I've found that the whole system works better when you don't use failure_route() to do "time out" style voicemail. I have a test setup where I just add a call to Asterisk immediately if the user is registered (has location entry) with a special prefix that gets matched in the * extensions.conf file, and causes * to simply wait for X seconds before answering. If the calee phone(s) is answered, SER cancels the call to * and any other phones registered to the user. If no phones are answered, * answers and sends the call to voicemail.
For whatever reason, this approach seems more stable so far, and seems more compatible with more phones, etc, than the failure_route approach. For instance, if you have a locations entry that points a user to another user, or more than one user (e.g. mainline@domain.com -> receptionist@domain.com -> receptionist@phone-IP:port), SER seems to get confused and sends a CANCEL to the voicemail system you've just triggered the INVITE to in your failure_route. When doing it the other way, it doesn't seem to have this problem. As for mapping user names to numeric extensions in Asterisk, I wrote an AGI script which does this by reverse-mapping the username to aliases in the SER script. It requires that your users have numerical extensions assigned in the SER aliases database (e.g. 1234 -> joe@domain.com). If there are multiple #s mapped to the user, it just returns the lowest one. Not sure if I can give this out though, since I wrote it for a client.
- Jim
Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I suspect mine is the same problem as I have two UAs registered so the initial dset is two places and then the append_branch on timeout is just the voicemail uri.
BTW, I am doing this with asterisk for the usual DTMF access reasons (altough I haven't yet figured out how to map sip:alan@columbia.edu to DTMF. Maybe I'll have to give up and do numeric mailboxes:-( I am rewriting with a prefix of "vm*u" before punting over to asterisk which has exten => _vm*u.,1,Wait,1 exten => _vm*u.,2,Voicemail(${EXTEN:3}) exten => _vm*u.,3,Goto(#,1)
Any pointers would be appreciated. My not-yet-complete ser.cfg is attached (not yet punting voicemail for unregistered subscribers; just registered subscribers who time out the invite).
/a
# # $Id: ser.cfg,v 1.21.2.1 2003/07/30 16:46:18 andrei Exp $ # # simple quick-start config script #
# ----------- global configuration parameters ------------------------
debug=2 # debug level (cmd line: -dddddddddd) fork=yes log_stderror=no # (cmd line: -E) #listen=128.59.39.127
check_via=yes # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) port=5060 children=4 fifo="/tmp/ser_fifo" alias="columbia.edu" # ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database loadmodule "/usr/lib/ser/modules/mysql.so" loadmodule "/usr/lib/ser/modules/acc.so" loadmodule "/usr/lib/ser/modules/sl.so" loadmodule "/usr/lib/ser/modules/tm.so" loadmodule "/usr/lib/ser/modules/rr.so" loadmodule "/usr/lib/ser/modules/maxfwd.so" loadmodule "/usr/lib/ser/modules/usrloc.so" loadmodule "/usr/lib/ser/modules/registrar.so"
# Uncomment this if you want digest authentication # mysql.so must be loaded ! loadmodule "/usr/lib/ser/modules/auth.so" loadmodule "/usr/lib/ser/modules/auth_db.so"
loadmodule "/usr/lib/ser/modules/exec.so"
# ----------------- setting module-specific parameters --------------- # -- transaction timers -- modparam("tm", "fr_inv_timer", 15 ) modparam("tm", "fr_timer", 10 )
# -- usrloc params -- # modparam("usrloc", "db_mode", 2) modparam("usrloc", "timer_interval", 10)
# -- auth params -- modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password")
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- acc params -- modparam("acc", "log_level", 1) modparam("acc", "log_flag", 1 ) modparam("acc", "log_missed_flag", 2) # ------------------------- request routing logic -------------------
# main routing logic
route{
/* ********* ROUTINE CHECKS
********************************** */ # 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 > max_len ) { sl_send_reply("513", "Message too big"); break; };
lookup("aliases"); # 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 record_route(); # loose-route processing if (loose_route()) { t_relay(); break; }; setflag(2); # if the request is for other domain use UsrLoc # (in case, it does not work, use the following command # with proper names and addresses in it) if (uri=~"^sip:(.+@)?columbia.edu") { if (method=="REGISTER") { log(1, "REGISTER received\n"); if (!www_authorize("columbia.edu", "subscriber")) { www_challenge("columbia.edu", "0"); break; }; save("location"); break; };
/* ********** Dial out to PSTN logic ************* */
# 5 Digit dialing, interior calls if (uri=~"^si"^sip:[1347][0-9]{4}@columbia\.edu") { rewritehostport("128.59.59.242:5060"); log(1,"5 digit expression match"); route(2); break; }; # 10 Digit dialing with outlide line if (uri=~"^si"^sip:931[0-9]{10}@columbia\.edu") { if(!(src_ip=="128.59.59.242") &
!(proxy_authorize("columbia.edu","subscriber"))) { proxy_challenge("columbia.edu", "1"); break;
} else { rewritehostport("128.59.59.242:5060"); log(1," 93 Outside line with 10 digit
expression match"); route(2); break; }; };
/* voicemail access */ if (uri=~"^sip:*86@columbia.edu" |uri=~"^sip:vm@columbia.edu" |uri=~"^sip:voicemail@columbia.edu") { route(3); break; };
# native SIP destinations are handled using our USRLOC DB if (!lookup("location")) { if (!exec_dset("/etc/ser/sipldap")) { sl_send_reply("404", "Not Found"); break; } else { log(1," sipldap call"); }; }; #!lookup }; if (method == "INVITE") { t_on_failure("1"); }; # forward to current uri now; use stateful forwarding; that # works reliably even if we forward from TCP to UDP if (!t_relay()) { sl_reply_error(); };
}
route[2] { log(1,"route[2]:SIP-to-PSTN call routed"); if (!t_relay()) { sl_reply_error(); }; } # ---- voicemail user access ---- route[3] { rewritehostport("127.0.0.1:5069"); log(1,"voicemail access"); if (!t_relay()) { sl_reply_error(); }; } # ------------- handling of unregistered user ------------------ route[4] {
log(1,"route[4]: user not registered"); # non-Voip -- just send "off-line" if (!(method == "INVITE" || method == "ACK" || method ==
"CANCEL")) { sl_send_reply("404", "Not Found"); break; };
# not voicemail subscriber
# if (!isflagset(4)) { # sl_send_reply("404", "Not Found and no voicemail turned on"); # break; # };
# forward to voicemail now prefix("vm*u"); rewritehostport("127.0.0.1:5069"); t_relay_to_udp("127.0.0.1", "5069");
} failure_route[1] { # transfer to asterisk voicemail with uMAILBOX for unavailable. # sip:USER@columbia.edu -> sip:vm*uUSER@127.0.0.1:5069 t_on_failure("2"); prefix("vm*u"); rewritehostport("127.0.0.1:5069"); append_branch(); log(1,"redirection to voicemail\n"); t_relay(); }
failure_route[2] { # forwarding failed (voicemail down?) log(1,"voicemail failed\n"); t_reply("500","Weasels have eaten voicemail again"); }
Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
-- +---------------------------------------------------------------------------+
| Jim Burwell - Sr. Systems/Network/Security Engineer, JSBC | +---------------------------------------------------------------------------+
| "I never let my schooling get in the way of my education." - Mark Twain | | "UNIX was never designed to keep people from doing stupid things, because | | that policy would also keep them from doing clever things." - Doug Gwyn | | "Cool is only three letters away from Fool" - Mike Muir, Suicyco | | "..Government in its best state is but a necessary evil; in its worst | | state an intolerable one.." - Thomas Paine, "Common Sense" (1776) | +---------------------------------------------------------------------------+
| Email: jimb@jsbc.cc ICQ UIN: 1695089 | +---------------------------------------------------------------------------+
| Reply problems ? Turn off the "sign" function in email prog. Blame MS. | +---------------------------------------------------------------------------+
I'm glad this issue was brought up when it was, cause I was just about to post on it :) I am using the same trick for voice mail. The problem is, if the user is busy, there is no way to detect it, since t_on_failure doesn't call the failure_route[x], if only one of the forks in the dset gets an error from the UAS.
It would be nice to see a way that the failure_route could get called if any fork gets an error, and had a way to test for other existing forks, and cancel them, and then re-direct the call.
The other way (feature) would be to allow onreply_route[x] to be able to start a new fork. So if it sees that the user agent returned a 1xx response, it could then start the second branch to the voice mail server, with the delay answer.
Am I missing something in the current version? Is there a way to do this now with some trick? Please let me know if any of you have figured a way around this limitation.
Thanks, --Dave
-----Original Message----- From: serusers-bounces@iptel.org [mailto:serusers-bounces@lists.iptel.org] On Behalf Of Jim Burwell Sent: Wednesday, January 28, 2004 5:16 PM To: Alan Crosswell Cc: serusers@lists.iptel.org Subject: Re: [Serusers] failure route and ERROR: t_should_relay: status rewriteby UAS: stored: 408, received: 487
Well, in doing this I never had a problem with one SER handling normal and voicemail calls. You just have to implement the proper logic. Basically, the pseudo-code: IF call is for ME (my SIP domain) THEN { IF callee is NOT online THEN { IF callee is in voicemail group THEN { call VM system immediately with URI modified signaling "answer immediately" break } ELSE (callee is NOT in voicemail group) { return 404 (user not found) break } } ELSE (callee is online) { IF callee is in voicemail group THEN { append destination set including VM system with URI modified signaling "wait before answering" } } }
relay call to dest set This approach has worked in all my testing. However, it may not be ideal for reasons I mentioned before.
What would be far nicer is having per branch or call timers one could set in the SER script. But in all likelyhood the schizophrenia caused by the conflict of the value proposition of SIP being 'light weight' and 'stateless' conflicting with the reality of SIP requiring state to give us basic real-world functionalities such as accounting and timed-out voicemail will result in this not happening any time soon, IMHO :-).
- Jim
Alan Crosswell wrote:
Jim,
I've been catching up to where you have already been with respect to failure route and the single global fr_inv_timer. It just doesn't work if the same SER is fielding invites for those having voicemail and those not. Before I go ahead and add a Wait 20 to my Asterisk voicemail, I had one other idea I wanted to ask about:
What if I run two ser instances? The main one checks is_user_in("Request-URI", "voicemail") and then punts any Invites for that user to a second ser which implements the fr_inv_timer, t_on_failure, etc. transfer to voicemail. Meanwhile all the non-voicemail subscribers (including stuff sent to our PSTN gateway, etc.) continues to chug along without the timer stuff happening.
Does this sound like a reasonable approach?
/a
Jim Burwell wrote:
I've found that the whole system works better when you don't use failure_route() to do "time out" style voicemail. I have a test setup where I just add a call to Asterisk immediately if the user is registered (has location entry) with a special prefix that gets matched in the * extensions.conf file, and causes * to simply wait for X seconds before answering. If the calee phone(s) is answered, SER cancels the call to * and any other phones registered to the user. If no phones are answered, * answers and sends the call to voicemail.
For whatever reason, this approach seems more stable so far, and seems more compatible with more phones, etc, than the failure_route approach. For instance, if you have a locations entry that points a user to another user, or more than one user (e.g. mainline@domain.com -> receptionist@domain.com -> receptionist@phone-IP:port), SER seems to get confused and sends a CANCEL to the voicemail system you've just triggered the INVITE to in your failure_route. When doing it the other way, it doesn't seem to have this problem. As for mapping user names to numeric extensions in Asterisk, I wrote an AGI script which does this by reverse-mapping the username to aliases in the SER script. It requires that your users have numerical extensions assigned in the SER aliases database (e.g. 1234 -> joe@domain.com). If there are multiple #s mapped to the user, it just returns the lowest one. Not sure if I can give this out though, since I wrote it for a client.
- Jim
Alan Crosswell wrote:
I'm trying to do failure route to voicemail (which is working) but this error is logged:
ERROR: t_should_relay: status rewrite by UAS: stored: 408, received: 487
I googled this and see that this came up last in October (http://lists.iptel.org/pipermail/serusers/2003-October/002921.html) but I don't see any evidence of a solution in the thread.
I suspect mine is the same problem as I have two UAs registered so the initial dset is two places and then the append_branch on timeout is just the voicemail uri.
BTW, I am doing this with asterisk for the usual DTMF access reasons (altough I haven't yet figured out how to map sip:alan@columbia.edu to DTMF. Maybe I'll have to give up and do numeric mailboxes:-( I am rewriting with a prefix of "vm*u" before punting over to asterisk which has exten => _vm*u.,1,Wait,1 exten => _vm*u.,2,Voicemail(${EXTEN:3}) exten => _vm*u.,3,Goto(#,1)
Any pointers would be appreciated. My not-yet-complete ser.cfg is attached (not yet punting voicemail for unregistered subscribers; just registered subscribers who time out the invite).
/a
------------------------------------------------------------------------
# # $Id: ser.cfg,v 1.21.2.1 2003/07/30 16:46:18 andrei Exp $ # # simple quick-start config script #
# ----------- global configuration parameters ------------------------
debug=2 # debug level (cmd line: -dddddddddd) fork=yes log_stderror=no # (cmd line: -E) #listen=128.59.39.127
check_via=yes # (cmd. line: -v) dns=no # (cmd. line: -r) rev_dns=no # (cmd. line: -R) port=5060 children=4 fifo="/tmp/ser_fifo" alias="columbia.edu" # ------------------ module loading ----------------------------------
# Uncomment this if you want to use SQL database loadmodule "/usr/lib/ser/modules/mysql.so" loadmodule "/usr/lib/ser/modules/acc.so" loadmodule "/usr/lib/ser/modules/sl.so" loadmodule "/usr/lib/ser/modules/tm.so" loadmodule "/usr/lib/ser/modules/rr.so" loadmodule "/usr/lib/ser/modules/maxfwd.so" loadmodule "/usr/lib/ser/modules/usrloc.so" loadmodule "/usr/lib/ser/modules/registrar.so"
# Uncomment this if you want digest authentication # mysql.so must be loaded ! loadmodule "/usr/lib/ser/modules/auth.so" loadmodule "/usr/lib/ser/modules/auth_db.so"
loadmodule "/usr/lib/ser/modules/exec.so"
# ----------------- setting module-specific parameters --------------- # -- transaction timers -- modparam("tm", "fr_inv_timer", 15 ) modparam("tm", "fr_timer", 10 )
# -- usrloc params -- # modparam("usrloc", "db_mode", 2) modparam("usrloc", "timer_interval", 10)
# -- auth params -- modparam("auth_db", "calculate_ha1", yes) modparam("auth_db", "password_column", "password")
# -- rr params -- # add value to ;lr param to make some broken UAs happy modparam("rr", "enable_full_lr", 1)
# -- acc params -- modparam("acc", "log_level", 1) modparam("acc", "log_flag", 1 ) modparam("acc", "log_missed_flag", 2) # ------------------------- request routing logic -------------------
# main routing logic
route{
/* ********* ROUTINE CHECKS ********************************** */ # 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 > max_len ) { sl_send_reply("513", "Message too big"); break; };
lookup("aliases");
# 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 record_route(); # loose-route processing if (loose_route()) { t_relay(); break; };
setflag(2);
# if the request is for other domain use UsrLoc # (in case, it does not work, use the following command # with proper names and addresses in it) if (uri=~"^sip:(.+@)?columbia.edu") {
if (method=="REGISTER") { log(1, "REGISTER received\n"); if (!www_authorize("columbia.edu", "subscriber")) { www_challenge("columbia.edu", "0"); break; };
save("location"); break; };
/* ********** Dial out to PSTN logic ************* */
# 5 Digit dialing, interior calls if (uri=~"^si"^si"^sip:[1347][0-9]{4}@columbia.edu") { rewritehostport("128.59.59.242:5060"); log(1,"5 digit expression match"); route(2); break; };
# 10 Digit dialing with outlide line if (uri=~"^si"^si"^sip:931[0-9]{10}@columbia.edu") { if(!(src_ip=="128.59.59.242") & !(proxy_authorize("columbia.edu","subscriber"))) { proxy_challenge("columbia.edu", "1"); break;
} else { rewritehostport("128.59.59.242:5060"); log(1," 93 Outside line with 10 digit expression match"); route(2); break; }; };
/* voicemail access */ if (uri=~"^sip:*86@columbia.edu" |uri=~"^sip:vm@columbia.edu" |uri=~"^sip:voicemail@columbia.edu") { route(3); break; };
# native SIP destinations are handled using our USRLOC DB if (!lookup("location")) { if (!exec_dset("/etc/ser/sipldap")) { sl_send_reply("404", "Not Found"); break; } else { log(1," sipldap call"); }; }; #!lookup
}; if (method == "INVITE") { t_on_failure("1"); }; # forward to current uri now; use stateful forwarding; that # works reliably even if we forward from TCP to UDP if (!t_relay()) { sl_reply_error(); }; }
route[2] { log(1,"route[2]:SIP-to-PSTN call routed"); if (!t_relay()) { sl_reply_error(); }; } # ---- voicemail user access ---- route[3] { rewritehostport("127.0.0.1:5069"); log(1,"voicemail access"); if (!t_relay()) { sl_reply_error(); }; } # ------------- handling of unregistered user ------------------ route[4] {
log(1,"route[4]: user not registered"); # non-Voip -- just send "off-line" if (!(method == "INVITE" || method == "ACK" || method == "CANCEL")) { sl_send_reply("404", "Not Found"); break; };
# not voicemail subscriber # if (!isflagset(4)) { # sl_send_reply("404", "Not Found and no voicemail turned on"); # break; # };
# forward to voicemail now prefix("vm*u"); rewritehostport("127.0.0.1:5069"); t_relay_to_udp("127.0.0.1", "5069"); } failure_route[1] { # transfer to asterisk voicemail with uMAILBOX for unavailable. # sip:USER@columbia.edu -> sip:vm*uUSER@127.0.0.1:5069 t_on_failure("2"); prefix("vm*u"); rewritehostport("127.0.0.1:5069"); append_branch(); log(1,"redirection to voicemail\n"); t_relay(); }
failure_route[2] { # forwarding failed (voicemail down?) log(1,"voicemail failed\n"); t_reply("500","Weasels have eaten voicemail again"); }
------------------------------------------------------------------------
_______________________________________________ Serusers mailing list serusers@lists.iptel.org http://lists.iptel.org/mailman/listinfo/serusers
-- +----------------------------------------------------------------------- ----+ | Jim Burwell - Sr. Systems/Network/Security Engineer, JSBC | +----------------------------------------------------------------------- ----+ | "I never let my schooling get in the way of my education." - Mark Twain | | "UNIX was never designed to keep people from doing stupid things, because | | that policy would also keep them from doing clever things." - Doug Gwyn | | "Cool is only three letters away from Fool" - Mike Muir, Suicyco | | "..Government in its best state is but a necessary evil; in its worst | | state an intolerable one.." - Thomas Paine, "Common Sense" (1776) | +----------------------------------------------------------------------- ----+ | Email: jimb@jsbc.cc ICQ UIN: 1695089 | +----------------------------------------------------------------------- ----+ | Reply problems ? Turn off the "sign" function in email prog. Blame MS. | +----------------------------------------------------------------------- ----+
At 08:04 PM 1/29/2004, David R. Kompel wrote:
I'm glad this issue was brought up when it was, cause I was just about to post on it :) I am using the same trick for voice mail. The problem is, if the user is busy, there is no way to detect it, since t_on_failure doesn't call the failure_route[x], if only one of the forks in the dset gets an error from the UAS.
It would be nice to see a way that the failure_route could get called if any fork gets an error, and had a way to test for other existing forks, and cancel them, and then re-direct the call.
I am not sure if there is a benefit in forking to N destinations and giving on N-1 of them if one fails... what is the use case? (I naively thought you fork in parallel to try as many destinations as you wish and fall back to other alternative such as voicemail only if none of these original destinations succeded.)
-jiri