Hi, I have confgured Kamailio with TLS in an Kamailio-Asterisk
implementation. The phones (Bria - Eyebeam - Aastra 57i) are registering in
Kamailio without problems, but the registration is not being forwarded to
Asterisk.
Kamailio is listening on port tls:5061 only and Asterisk on udp:5080. Should
Kamailio has to listen on port 5060 also for UAC module functions? If I
enable the port 5060, how do I prevent common SIP - UDP registrations? I
mean, I want the registrations to be over TLS only. I would appreciate if
someone can put me on the right path.
Thanks in advance.
Lucas Alvarez
i am trying to route to pstn provider,but i faced a problem .
my provider accept ptime 20 while i am send the call with ptime 30 how i can change ptime
i have kamailio with freeswitch
any help please
I've been playing with sip load-balancer in EC2 but so far haven't been
able to figure out how to insert Record-Route header with
advertised_address.
AFAIK kamailio rr module adds 2 RR headers (one with the inbound address
and one with the outbound address) when your transaction comes with one
interface/port and leaves via another.
In EC2 the receive socket is the same as send socket and I've had no
luck trying to get kamailio insert advertised address as inbound RR and
then the outbound RR, by calling record_route_preset() several times in
a row too. This is a problem if lb is in front of another proxy.
As I see this question has been raised on the mailing lists as far as 6
years ago - I would be surprised if no one has come up with a solution
yet. So how to do record-routing in a draft-ietf-sip-record-route-fix
AKA rfc5658 style on the machine with one physical interface?
--
Sincerely,
Andrew Pogrebennyk
Hello,
I am testing Kamailio (OpenSER) as a frontend forwarding calls to
asterisk. The setup is working fine and I am able to make call fine.
However, Asterisk, naturally, sees calls/connections coming from
Kamailio (OpenSER). Is there a way I can forward the client (calle to
Kamailio (OpenSER)) IP to asterisk so asterisk can authenticate it?
-B
Hi all,
I am attempting to handle NOTIFY within my script but there is a definite
error in my syntax. I believe it has to do with $hdr(Event).
Anyone know how I should re-write this?
if (is_method("NOTIFY") && is_domain_local("$rd") && $hdr(Event) =~
"keep-alive" )
{
sl_send_reply("200", "OK - keep-alive");
exit;
}
TIA
Found it.will google more from now on. Sorry.
if ( is_method("NOTIFY") && uri==myself
&& $hdr(Event) =~ "keep-alive" )
{
sl_send_reply("200", "OK - keepalive");
xlog("L_INFO", "$hdr(Event) detected - ok sent\n");
exit;
}
From: Skyler [mailto:skchopperguy@gmail.com]
Sent: Saturday, May 21, 2011 7:40 PM
To: 'sr-users(a)lists.sip-router.org'
Subject: syntax error?
Hi all,
I am attempting to handle NOTIFY within my script but there is a definite
error in my syntax. I believe it has to do with $hdr(Event).
Anyone know how I should re-write this?
if (is_method("NOTIFY") && is_domain_local("$rd") && $hdr(Event) =~
"keep-alive" )
{
sl_send_reply("200", "OK - keep-alive");
exit;
}
TIA
Found it.
/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/
From: Skyler [mailto:skchopperguy@gmail.com]
Sent: Saturday, May 21, 2011 3:29 PM
To: 'sr-users(a)lists.sip-router.org'
Subject: Modules directory missing?
Hello,
I am new to Kamailio and have installed via rpm repository on CentOS 5.5
Where is the modules directory located? I cannot load any modules and
Kamailio will not start.
I've checked these locations but they don't exist. Is there another package
I need to install or where did I go wrong?
/usr/local/lib/kamailio/modules_k/
/usr/local/lib/kamailio/modules/
Hello,
I am new to Kamailio and have installed via rpm repository on CentOS 5.5
Where is the modules directory located? I cannot load any modules and
Kamailio will not start.
I've checked these locations but they don't exist. Is there another package
I need to install or where did I go wrong?
/usr/local/lib/kamailio/modules_k/
/usr/local/lib/kamailio/modules/
Daniel,
Sorry, I had meant to send it to the list.
You are correct about missing messages. The ACK is being sent, but it is
sent to it's self (loop condition) over the 'lo' device.
So basically its a design flaw on my part of the kamailio.cfg file.
My current config works for initial messages from the provider and from
subscribers.
But for initial messages from the Asterisk boxes, I have Asterisk send
to the Kamailio box and then have Kamailio look at the message and then
route it with a forward(x.x.x.x).
While that works for successful calls it is what is breaking the ACK to
the 486, and I think it is also breaking Cancel.
Do you know of a good example config file where:
1) SIP message from provider hits Kamailio and is routed to one of
several Asterisk boxes (load balancing, using ds_select)
2) Messages from a subscriber will be routed to one of the Asterisk
boxes (load balancing, using ds_select)
3) Messages from an Asterisk box will be routed to the provider OR a
subscribers SIP device based on a fixed string in the R-URI
Or you can laugh at what I have: (constructive criticism is welcome from
anyone!)
(I had to trim this message as it was exceeding the 40K limit)
#!KAMAILIO
#
####### Defined Values #########
# - flags
# FLT_ - per transaction (message) flags
# FLB_ - per branch flags
#!define FLT_ACC 1
#!define FLT_ACCMISSED 2
#!define FLT_ACCFAILED 3
#!define FLT_NATS 5
#!define FLB_NATB 6
####### Global Parameters #########
# debug=4
# log_stderror=yes
debug=3
log_stderror=no
memdbg=5
memlog=5
log_facility=LOG_LOCAL0
fork=yes
children=4
/* uncomment and configure the following line if you want Kamailio to
bind on a specific interface/port/proto (default bind on all available) */
listen=udp:2.2.2.164:5060
/* port to listen to
* - can be specified more than once if needed to listen on many ports */
port=5060
dns=no
rev_dns=no
open_files_limit=4096
disable_core_dump=yes
disable_tcp=yes
check_via=0
reply_to_via=0
# we may be able to use the above with force_rport
####### Modules Section ########
# set paths to location of modules
mpath="/usr/lib/kamailio/modules_k/:/usr/lib/kamailio/modules/"
loadmodule "db_mysql.so"
loadmodule "mi_fifo.so"
loadmodule "kex.so"
loadmodule "tm.so"
loadmodule "tmx.so"
loadmodule "sl.so"
loadmodule "rr.so"
loadmodule "pv.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
# loadmodule "ctl.so"
loadmodule "mi_rpc.so"
loadmodule "acc.so"
loadmodule "auth.so"
loadmodule "auth_db.so"
loadmodule "dispatcher.so"
loadmodule "avpops.so"
# ----------------- setting module-specific parameters ---------------
# ----- mi_fifo params -----
modparam("mi_fifo", "fifo_name", "/tmp/kamailio_fifo")
# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
modparam("tm", "fr_timer", 30000)
modparam("tm", "fr_inv_timer", 120000)
# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)
# ----- registrar params -----
modparam("registrar", "method_filtering", 1)
# ----- acc params -----
/* what special events should be accounted ? */
modparam("acc", "early_media", 0)
modparam("acc", "report_ack", 0)
modparam("acc", "report_cancels", 0)
/* by default ww do not adjust the direct of the sequential requests.
if you enable this parameter, be sure the enable "append_fromtag"
in "rr" module */
modparam("acc", "detect_direction", 0)
/* account triggers (flags) */
modparam("acc", "log_flag", FLT_ACC)
modparam("acc", "log_missed_flag", FLT_ACCMISSED)
# the line below puts extra stuf at the end of the log line
modparam("acc", "log_extra",
"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
/* enhanced DB accounting */
# ----- usrloc params -----
/* enable DB persistency for location entries */
# appears to use table 'location' and this table has data in it
modparam("usrloc", "db_url", "mysql://kamailio:password@my.db.com/kamailio")
modparam("usrloc", "db_mode", 2)
modparam("usrloc", "use_domain", 1)
# ----- auth_db params -----
# appears to use table 'subscriber' and this table has data in it
modparam("auth_db", "db_url",
"mysql://kamailio:password@my.db.com/kamailio")
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "load_credentials", "")
modparam("auth_db", "use_domain", 1)
modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list")
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "flags", 3)
modparam("avpops","db_url","mysql://kamailio:password@my.db.com/AppServer")
modparam("avpops","avp_table","User")
####### Routing Logic ########
# Main SIP request routing logic
# - processing of any incoming SIP request starts with this route
route
{
# initial checks (check for bad/malformed/unsupported messages)
route(REQINIT);
# if it is not a OPTIONS message - log it
if (!is_method("OPTIONS"))
{
xlog("L_INFO", "======== processing new message\n");
xlog("L_INFO", "MAIN: SIP Request: [$rm] ruri=[$ru] (from [$fu] to
[$tu], Call-ID=[$ci]) CSeq=[$cs]\n");
}
# handle requests within SIP dialogs (active ongoing call - has TO: tag)
does not return
route(WITHINDLG);
### only initial requests (no To: tag) from here on
# CANCEL processing
if (is_method("CANCEL"))
{
# - this needs some work and cancels are not being replied to or forwared
# cancle is a hop-by-hop message (send a 200 OK then forward it on)
# t_check_trans = if cancel, this is supposed to be true if the Invite
transaction exits
# see: http://www.kamailio.org/docs/modules/1.1.x/tm.html#AEN460
if (t_check_trans())
{
xlog("L_INFO", "MAIN: Recieved Cancel, t_check_trans is true\n");
t_relay();
exit;
}
xlog("L_INFO", "MAIN: Recieved Cancel, t_check_trans is FALSE\n");
# forward it on (not sure why we are getting here with valid calls that
need to be canceled)
# this may be bad as somone might be able to "cancel storm" us??
t_relay();
exit;
}
# this was added to handle OPTIONS messages
route(HANDLEOPTIONS);
# I 'think' this absorbs retransmissions of Invites
t_check_trans();
if (!is_method("REGISTER"))
{
if ($rU==$null)
{
# request with no Username in RURI
xlog("L_INFO", "Error: main route: request with no Username in RURI\n");
sl_send_reply("484","Address Incomplete");
exit;
}
}
# set up a trigger for failures of INVITEs
if (is_method("INVITE"))
{
xlog("L_INFO", "main_loop: SIP Request: ruri=[$ru] (method [$rm] from
[$fu] to [$tu])\n");
t_on_failure("FAIL_ONE");
}
# at this point we need to determine how to route the call
# if the call is from PROVIDER, it has to go to an AST box (L3 should
never go directly to a subscriber)
# if the call is from a subscriber, it has to go to an AST box (sub
can't dial directly out)
# if the call is from an AST box we need to determine if it goes to L3
or a subscriber
# if to a subscriber the ToURI should contain "SIP_"
# log all invites to syslog
# if (is_method=="INVITE"))
# {
# xlog("L_INFO", "main_loop: SIP Request: ruri=[$ru] (method [$rm] from
[$fu] to [$tu])\n");
# };
# handle the easy cases first
# from PROVIDER
if ($src_ip=="3.3.3.40")
{
route(FROMPROVIDER);
exit; # just to be sure
}
# if from an AST box (will determine wether to send it to PROVIDER or a
subscriber)
if ($src_ip=~"2\.2\.2\.1") # regexp match
{
route(FROMAST);
exit; # just to be sure
}
force_rport(); # attemp to make kamailio use the emhemeral port of the
sender
#=============== Only subscribers left from here down
# handle registrations (from a sip client)
route(REGISTER);
# authentication for everyone
route(AUTH);
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# account only INVITEs
if (is_method("INVITE"))
{
setflag(FLT_ACC); # do accounting
}
route(FROMSUBSCRIBER);
# route(RELAY);
xlog("L_INFO", "ERROR - no route chosen \n");
}
###################################################################
# Per SIP request initial checks
route[REQINIT]
{
# xlog("L_INFO", " REQINIT: Initial Checks\n");
if (!mf_process_maxfwd_header("10"))
{
xlog("L_WARN", " REQINIT: Too Many Hops (Request: [$rm])\n");
sl_send_reply("483","Too Many Hops");
exit;
}
if(!sanity_check("1511", "7"))
{
xlog("L_WARN", " REQINIT: Malformed SIP message from $si:$sp (Request:
[$rm]) \n");
exit;
}
# xlog("L_INFO", " leaving [REQINIT] \n");
# unsupported messages here
if (is_method("SUBSCRIBE"))
{
# probably want to comment the next line out after it is working
xlog("L_WARN", "REQINIT: Subscribe not supported: SIP Request: [$rm]
ruri=[$ru] (from [$fu] to [$tu], Call-ID=[$ci]) CSeq=[$cs]\n");
exit;
}
# if no errors, just fall through and return to caller
}
###################################################################
# Handle requests within SIP dialogs (request has a TO: Tag)
route[WITHINDLG]
{
# xlog("L_INFO", " WITHINDLG: starting up (WithInDialog)\n");
if (has_totag())
{
xlog("L_INFO", " WITHINDLG: SIP Request: [$rm] ruri=[$ru] (from [$fu] to
[$tu], Call-ID=[$ci], CSeq=[$cs])\n");
xlog("L_INFO", " WITHINDLG: has TO: tag\n");
# sequential request withing a dialog should
# take the path determined by record-routing
if (loose_route())
{
xlog("L_INFO", " WITHINDLG: has TO: tag AND loose_route is true\n");
if (is_method("BYE"))
{
setflag(FLT_ACC); # do accounting ...
setflag(FLT_ACCFAILED); # ... even if the transaction fails
}
xlog("L_INFO", " WITHINDLG: sending to relay\n");
route(RELAY);
}
else # not loose_route
{
xlog("L_INFO", " WITHINDLG: has TO: tag AND louse_route is NOT true\n");
if (is_method("SUBSCRIBE") && uri == myself)
{
# in-dialog subscribe requests
route(PRESENCE);
exit;
}
if ( is_method("ACK") )
{
xlog("L_INFO", " WITHINDLG: has TO: tag AND loose_route is NOT true and
is_method = ACK\n");
if ( t_check_trans() ) # see if a message is related to a transaction
{
# Reference:
http://www.kamailio.org/docs/modules/stable/modules/tm.html#t_check_trans
xlog("L_INFO", " WITHINDLG: has TO: tag AND loose_route is NOT true and
is_method = ACK and t_check_trans=true\n");
# no loose-route, but stateful ACK;
# must be an ACK after a 487
# or e.g. 404 from upstream server
t_relay();
exit;
}
else
{
# ACK without matching transaction ... ignore and discard
xlog("L_INFO", " WITHINDLG: has TO: tag AND loose_route is NOT true and
is_method = ACK and t_check_trans=FALSE\n");
xlog("L_INFO", " WITHINDLG: the ACK to a 486 was not being processed so
I am adding t_relay here\n");
# $var(a) = t_relay();
# $var(a) = forward();
t_relay();
xlog ("L_INFO", " WITHINDLG: (ReturnCode = [$var(a)] exiting)\n");
exit;
}
}
# not an ACK - as both branches aove exit
xlog("L_INFO", " WITHINDLG: has TO: tag AND loose_route is NOT true and
is_method not = ACK \n");
sl_send_reply("404","Not here");
}
exit;
}
# xlog("L_INFO", " leaving [WITHINDLG] (WithInDialog)\n");
# if msg has to: tag it should be processed above and then exit, else
just return for further processing
}
###################################################################
# By CEW 2Feb2011
route[REGISTER]
{
if (is_method("REGISTER"))
{
# NOTE: need to review: http://www.kamailio.org/docs/scripting.html on
how they handle registration
# at this point all that should be left are sip clients - they are
coming over the open internet so authenticate them!
# xlog("L_INFO", " REGISTER: processing register from sip client, fu=$fu
\n");
# authenticate the REGISTER requests (uncomment to enable auth)
# www_authenticate will send a 401 Unauthorized (and will contain
WWW-Authenticate in the reply)
# proxy_authenticate will send a 407 Proxy Authentication Required. (and
will contain Proxy-Authenticate in the reply)
# uses the kamailio->subsriber DB table
# if (!proxy_authenticate("2.2.2.164", "subscriber"))
if (!www_authenticate("2.2.2.164", "subscriber"))
{
$var(a) = $rc; # save the return from the www_authenticate
# -1 = generic error
# -2 = invalid password
# -3 = invalid user ( or domain is wrong)
if ($var(a) == -2)
{
xlog ("L_INFO", " REGISTER ERROR: bad password, (ReturnCode = $var(a)
exiting)\n");
exit;
}
if ($var(a) == -3)
{
xlog ("L_INFO", " REGISTER ERROR: invalid user, (ReturnCode = $var(a)
exiting)\n");
exit;
}
xlog("L_INFO", " REGISTER: issuing a challenge, 401 (and then exit
script)\n");
# send a "401 Unauthorized", with realm=2.2.2.164, caller should resend
invite with auth info
www_challenge("2.2.2.164", "1"); # send a 401
# proxy_challenge("2.2.2.164", "1"); # send a 407
# xlog("L_INFO", " REGISTER: exiting\n");
exit;
}
xlog("L_INFO", " REGISTER: Match found in database for register\n");
# make sure the Authorization: username matches the To: username
# $au = user part of username from Authorization: or Proxy-Authorization
header (from the resent Invite, after the challenge)
# $tU = reference to username in URI of 'To' header
if ($au!=$tU)
{
xlog("L_INFO", " REGISTER: sending 403 Forbidden auth ID\n");
sl_send_reply("403","Forbidden auth ID");
exit;
}
# now store it in the DB and then exit
if (!save("location"))
{
xlog("L_INFO", " REGISTER: Error saving location, sending SIP error to
other end\n");
sl_reply_error();
}
exit;
}
}
###################################################################
# Authentication route
route[AUTH]
{
xlog("L_INFO", " entering route[AUTH] Authentication route\n");
# authenticate if from local subscriber
# I think this should be true for LOCAL sip callers (in production there
shouldn't be any of these)
if (from_uri==myself)
{
xlog("L_INFO", " AUTH: from_uri = myself ($fu)\n");
if (!proxy_authenticate("$fd", "subscriber"))
{
$var(a) = $rc; # save the return from the www_authenticate
# -1 = generic error - like no valid auth
# -2 = invalid password
# -3 = invalid user (or domain is wrong)
if ($var(a) <= -2)
{
xlog ("L_INFO", " AUTH: ERROR: Location lookup, ReturnCode = $var(a)
exiting\n");
exit;
}
# xlog("L_INFO", " AUTH: no authenticate credentials supplied, sending
challenge (407), from_uri=$fu \n");
xlog("L_INFO", " AUTH: no authenticate credentials supplied, sending
challenge (401), from_uri=$fu \n");
# send the proxy challenge and exit. Let the caller send another invite
with authentication info.
proxy_challenge("$fd", "0");
exit;
}
xlog("L_INFO", " AUTH: proxy_autorization OK! \n");
# make sure the Authorization: username matches the To: username
# $au = user part of username from Authorization: or Proxy-Authorization
header (from the resent Invite, after the challenge)
# $fU = reference to username in URI of 'From' header
if ($au!=$fU)
{
xlog("L_INFO", " AUTH: Forbidden, sending 403\n");
sl_send_reply("403","Forbidden auth ID");
exit;
}
xlog("L_INFO", " AUTH: Authorization accepted! Consuming credentials\n");
consume_credentials();
# caller authenticated
}
else
{
# !! NOTE: this branch has not been tested as I cant simulate it in my
lab!!!
# a lot of it was just made up so it does need a lot of testing.
# subscriber from the Internet
# this is where all our sip clients should hit
xlog("L_INFO", " AUTH: EXTERNAL subscriber, need to authenticate
from_uri $fu\n");
# caller is not local subscriber, then check if it calls
# a local destination, otherwise deny, not an open relay here
if (!uri==myself)
{
xlog("L_INFO", " AUTH: NOT RELAYING!, (uri!=myself) sending 403\n");
sl_send_reply("403","Not relaying");
exit;
}
# not sure if we need to do a proxy_authenticate or www_authenticate
here - need to test in production
if (!proxy_authenticate("$fd", "subscriber"))
{
xlog("L_INFO", " AUTH: sending proxy_challenge, from_uri=$fu, exiting \n");
# send the proxy challenge and exit. Let the caller send another invite
with authentication info.
proxy_challenge("$fd", "0");
xlog("L_INFO", " AUTH: sent proxy_challenge, exiting\n");
exit;
}
# make sure the Authorization: username matches the To: username
# $au = user part of username from Authorization: or Proxy-Authorization
header (from the resent Invite, after the challenge)
# $fU = reference to username in URI of 'From' header
if ($au!=$fU)
{
xlog("L_INFO", " AUTH: Forbidden auth ID, from_uri=$fu, exiting \n");
sl_send_reply("403","Forbidden auth ID");
exit;
}
xlog("L_INFO", " AUTH: Consuming credentials\n");
consume_credentials();
}
xlog("L_INFO", " leaving route[AUTH] Authentication route\n");
return;
}
###################################################################
# if the call is from PROVIDER, it has to go to an AST box (L3 should
never go directly to a subscriber)
# if (uri=="3.3.3.40")
route[FROMPROVIDER]
{
# xlog("L_INFO", " FROMPROVIDER: starting up \n");
if (is_method("REGISTER"))
{
xlog("L_INFO", " FROMPROVIDER: REGISTER from PROVIDER, sending 200 OK
fd=$fd \n");
sl_send_reply("200", "ok");
exit;
};
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
{
record_route();
};
# account only INVITEs
if (is_method("INVITE"))
{
setflag(FLT_ACC); # do accounting
};
# if a conference call, send it to ast1
# ds_select_dst(set, alg) the method selects a destination from address set
# set - first column from dest file (dispacher.list)
# alg 0 = hash over callid
if (uri=~"12223334444")
{
xlog("L_INFO", " FROMPROVIDER: Conference call - sending to ast1 \n");
ds_select_dst("3", "0");
forward();
exit;
};
# avp_check(name, op_value) check the value of the avp against an
operator and value
# op_value = operator '/' value ['/'flags]
# $fu =
# $ru = SIP Request's URI
# if the call came from ast0 (2.2.2.167) via PROVIDER route it to ast1
or we will have a loop condition
# $ci = the call ID
# AVP = attribute-value-pair
if (avp_check("$ci","re/.*(a)2.2.2.167.*/g"))
{
xlog ("L_INFO", " FROMPROVIDER: Call originating on ast0, sending call
to ast1 [$ru]\n");
ds_select_dst("2", "0");
forward();
exit;
};
# if the call came from ast1 (2.2.2.168) via PROVIDER route it to ast0
or we will have a loop condition
if (avp_check("$ci","re/.*(a)2.2.2.168.*/g"))
{
xlog ("L_INFO", " FROMPROVIDER: Call originating on ast1, sending call
to ast0 [$ru]\n");
ds_select_dst("3", "0");
forward();
exit;
};
# Extract the telephone number from the To-URI
$avp(i:999)=$tU;
# insted of the next line, should we just do a regexp to remove all
non-numeric?
avp_subst("$avp(i:999)","/\+//g"); # remove the literal string "+" from
the variable, if any
# xlog("L_INFO", " FROMPROVIDER: about to do \"SELECT AppName FROM
Application WHERE TelephoneNumber = $avp(i:999) \" \n");
avp_db_query("SELECT AppName FROM Application WHERE TelephoneNumber =
'$avp(i:999)'","$avp(i:888)");
# xlog("L_INFO", " FROMPROVIDER: Query result =[$avp(i:888)] \n");
# see if we got anything back from the DB, if we did it would look like
"product" or some future varient
if(!is_avp_set("$avp(i:888)")) # if avp 888 is not set, dump the call
{
xlog ("L_INFO", " FROMPROVIDER: Bad number. Sending 404. method=[$rm]
ruri=[$ru] to=[$tu] from=[$fu]\n");
# I don't think the next line is needed as it appears this table is
never read (just written to)
avp_db_query("INSERT IGNORE INTO InvalidTN VALUES ('$avp(i:999)')");
sl_send_reply("404", "Not Found"); # do we really want to do this? Or
shoud we just silently drop it?
exit;
};
# this is where we do the main load balancing, ast0 or ast1
xlog ("L_INFO", " FROMPROVIDER: Normal Round-Robin call, routing to
[$ru], from [$fu]\n");
# ds_select_dst("1", "0");
ds_select_dst("3", "0");
forward();
# Note: forward does return, so we could do post call processing here
exit;
}
###################################################################
# if the call is from an AST box we need to determine if it goes to L3
or a subscriber
# if to a subscriber the ToURI should contain "SIP_"
# if (uri=~"2\.2\.2\.1") from our ast box
route[FROMAST]
{
xlog("L_INFO", " FROMAST: starting up \n");
if (is_method("REGISTER"))
{
xlog("L_INFO", " FROMAST: REGISTER from AST, sending 200 OK fd=$fd \n");
sl_send_reply("200", "ok");
exit;
};
# record routing for dialog forming requests (in case they are routed)
# - remove preloaded route headers
remove_hf("Route");
if (is_method("INVITE|SUBSCRIBE"))
record_route();
# account only INVITEs
if (is_method("INVITE"))
{
setflag(FLT_ACC); # do accounting
}
# this block is probalby not needed, except possilby for logging
$avp(i:999)=$tU; # Extract the telephone number from the To-URI
avp_subst("$avp(i:999)","/\+//g"); # remove the literal string "sip:+"
from the variable
xlog("L_INFO", " FROMAST: avp(999) = $avp(i:999)\n");
# at this point we need to see if the number contains a "SIP_". If so
route it to the subscriber, else route it to L3
xlog("L_INFO", " FROMAST: tU=$tU\n");
if ($tU=~"SIP_")
{
xlog("L_INFO", " FROMAST: contains \"SIP_\" so routing to subscriber\n");
route(TOSUBSCRIBER);
exit; # should be handled in TOSUBSCRIBER, but just to make sure we bail
here and don't continue
}
xlog("L_INFO", " FROMAST: does not contain SIP_ so routing to PROVIDER\n");
# need to rewrite the RURI and To URI
$td="3.3.3.40:5060";
$rd="3.3.3.40:5060";
forward("3.3.3.40"); # send it on to PROVIDER
}
###################################################################
# if the call is from a subscriber, it has to go to an AST box
(subscribers can't dial directly out)
route[FROMSUBSCRIBER]
{
xlog("L_INFO", " FROMSUBSCRIBER: starting up \n");
# at this point we should have already been authenticated by route[AUTH]
so just route it to an ast box
# this is where we do the main load balancing, ast0 or ast1 (round robin)
ds_select_dst("3", "0");
forward();
xlog("L_INFO", " leaving route[FROMSUBSCRIBER] \n");
exit; # just in case
}
###################################################################
# The call needs to be routed to a scubscriber
route[TOSUBSCRIBER]
{
xlog("L_INFO", " TOSUBSCRIBER: starting up \n");
# this is NOT tested yet!
# do a DB lookup on kamailio->location to see where to route (should
only be for SIP-to-Subscribers)
if (!lookup("location"))
{
switch ($rc)
{
case -1:
case -3:
t_newtran();
xlog("L_INFO", " TOSUBSCRIBER: Subscriber not Found, sending 404 \n");
t_reply("404", "Not Found");
exit;
case -2:
xlog("L_INFO", " TOSUBSCRIBER: Method Not allowed, sending 405 \n");
sl_send_reply("405", "Method Not Allowed");
exit;
}
}
xlog("L_INFO", " TOSUBSCRIBER: subscriber is authorized! \n");
# not sure about any of this that follows
# when routing via usrloc, log the missed calls also
if (is_method("INVITE"))
{
xlog("L_INFO", " TOSUBSCRIBER: setting flag FLT_ACCMISSED \n");
setflag(FLT_ACCMISSED);
}
xlog("L_INFO", " TOSUBSCRIBER: attempting to do: t_relay \n");
if (!t_relay())
{
xlog("L_INFO", " TOSUBSCRIBER: ERROR in t_relay \n");
sl_reply_error();
};
xlog("L_INFO", " TOSUBSCRIBER: message proxied, now exiting \n");
exit;
}
###################################################################
# Sample failure route
# One source for this block: http://pastebin.com/NMZiBuNm
# A source:
http://www.kamailio.org/dokuwiki/doku.php/core-cookbook:3.1.x#failure_route
# 'failure_route' is executed only by TM module after it was armed via
t_on_failure(“failure_route_index”)
failure_route[FAIL_ONE]
{
xlog("L_INFO", " FAIL_ONE: starting up Sample failure route (looks for
canceled)\n");
if (t_is_canceled())
{
exit;
}
if (t_check_status("486|408"))
{
xlog("L_INFO","[1] ($ru) \n");
sl_send_reply("ACK", "Busy"); # send an ACK back to sender
t_relay(); # forward it on
}
# this may do what I want ??
# if(is_method("INVITE")) {
xlog("L_INFO", " leaving route[FAIL_ONE] Sample failure route \n");
}
###################################################################
route[RELAY]
{
xlog("L_INFO", " RELAY starting up\n");
/* example how to enable some additional event routes */
if (is_method("INVITE"))
{
xlog("L_INFO", " RELAY: Error: INVITE sending sl_on_failure\n");
t_on_failure("FAIL_ONE");
}
if (!t_relay())
{
xlog("L_INFO", " RELAY: Error sending sl_reply_error\n");
sl_reply_error();
}
xlog("L_INFO", " leaving [RELAY]\n");
exit;
}
###################################################################
# Presence server route
route[PRESENCE]
{
xlog("L_INFO", " PRESENCE: starting up \n");
if(!is_method("PUBLISH|SUBSCRIBE"))
return;
# if presence enabled, this part will not be executed
# if (is_method("PUBLISH") || $rU==$null)
# {
xlog("L_INFO", " PRESENCE: PUBLISH and SUBSCRIBE not supported sending
404\n");
sl_send_reply("404", "Not here");
exit;
# }
# xlog("L_INFO", "leaving route[PRESENCE] Presence server route\n");
# return;
}
###################################################################
# Caller NAT detection route
route[NAT]
{
xlog("L_INFO", " NAT: NAT detection route (currently does nothing)\n");
xlog("L_INFO", " leaving route[NAT] NAT detection route \n");
return;
}
###################################################################
# RTPProxy control
route[RTPPROXY]
{
xlog("L_INFO", " RTPPROXY: RTPProxy control(currently does nothing)\n");
xlog("L_INFO", " leaving route[RTPPROXY] RTPProxy control\n");
return;
}
###################################################################
# Routing to foreign domains
route[SIPOUT]
{
xlog("L_INFO", " SIPOUT: Routing to foreign domains\n");
if (!uri==myself)
{
append_hf("P-hint: outbound\r\n");
route(RELAY);
}
xlog("L_INFO", " leaving route[SIPOUT] Routing to foreign domains\n");
}
###################################################################
# PSTN GW routing
route[PSTN]
{
xlog("L_INFO", " PSTN: PSTN GW routing (currently does nothing) \n");
xlog("L_INFO", " leaving route[PSTN] PSTN GW routing\n");
return;
}
###################################################################
# PROVIDER or our AST boxes may send an options message, they are our
friends so just 200 OK them
# By CEW 2Feb2011
route[HANDLEOPTIONS]
{
if (is_method("OPTIONS"))
{
# xlog("L_INFO", " HANDLEOPTIONS: found options message \n");
# if from AST
if ($src_ip=~"2\.2\.2\.1")
{
# xlog("L_INFO", " HANDLEOPTIONS from our AST, sending 200 OK\n");
sl_send_reply("200", "ok");
exit;
};
# if from PROVIDER
if ($src_ip=~"2\.2\.2\.40")
{
xlog("L_INFO", " HANDLEOPTIONS from PROVIDER, sending 200 OK\n");
sl_send_reply("200", "ok");
exit;
};
# if we made it here, just throw the message away
# this assumes that none of our sip clients will send us Options messages!
exit;
};
}