Hello,
I've been using Kamailio to replace a Telcobridge ProSBC for several days
now, but I've been stuck for a whole day on a simple concept
My Kamaillio is connected to an Asterisk to which it redirects requests.
However, this Asterisk sends OPTIONS requests in order to ping the phone.
On the Kamailio side, I don't know how to respond to these requests.
I've done tons of research but I can't find anything similar, maybe there's
something very obvious I'm missing....
If I t_relay the message it never receives a reply via the phone's public
ip/port.
Thanks in advance if anyone could help me with this. Please apologize if
it's a dumb thing.
SIP OPTIONS:
2024/02/28 23:28:25.181663 100.66.138.5:5060 -> 100.66.138.7:5060
OPTIONS sip:110@100.66.138.7:5060 SIP/2.0
Via: SIP/2.0/UDP 100.66.138.5:5060
;rport;branch=z9hG4bKPje213d53f-fd1d-47f2-b0f8-fd3a8bf5188c
From: <sip:110@100.66.138.5>;tag=46e51407-77b0-47f1-af73-cd8bec95b179
To: <sip:110@100.66.138.7>
Contact: <sip:110@100.66.138.5:5060>
Call-ID: 74401738-d874-4c5c-a4b5-b74514361043
CSeq: 50224 OPTIONS
Max-Forwards: 70
User-Agent: Asterisk
Content-Length: 0
=============
kamailio.cfg
#!KAMAILIO
#!define WITH_MYSQL
#!define WITH_AUTH
#!define WITH_USRLOCDB
#!define WITH_RTPENGINE
# define WITH_ANTIFLOOD
#!define WITH_WEBSOCKETS
#!define WITH_TLS
#!define WITH_NAT
...
#!ifdef ACCDB_COMMENT
ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';
ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT
'';
ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL
DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default
'';
ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL
DEFAULT '';
ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT
'';
ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL
DEFAULT '';
#!endif
####### DEFINE VARIABLE ########
#!substdef "!MY_IP_ADDR!X.X.X.X!g"
#!substdef "!MY_WS_PORT!8080!g"
#!substdef "!MY_WSS_PORT!4443!g"
#!substdef "!MY_WS_ADDR!tcp:MY_IP_ADDR:MY_WS_PORT!g"
#!substdef "!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g"
#!substdef "!MY_MSRP_PORT!4444!g"
#!substdef "!MY_WSS_ADDR!tls:MY_IP_ADDR:MY_WSS_PORT!g"
#!substdef "!MY_MSRP_ADDR!tls:MY_IP_ADDR:MY_MSRP_PORT!g"
#!substdef "!MSRP_MIN_EXPIRES!1800!g"
#!substdef "!MSRP_MAX_EXPIRES!3600!g"
####### Include Local Config If Exists #########
import_file "kamailio-local.cfg"
####### Defined Values #########
# *** Value defines - IDs used later in config
#!ifdef WITH_DEBUG
#!define DBGLEVEL 3
#!else
#!define DBGLEVEL 2
#!endif
#!ifdef WITH_MYSQL
# - database URL - used to connect to database server by modules such
# as: auth_db, acc, usrloc, a.s.o.
#!trydef DBURL "mysql://kamailio:kamailiorw@localhost/kamailio"
#!endif
#!ifdef WITH_MULTIDOMAIN
# - the value for 'use_domain' parameters
#!define MULTIDOMAIN 1
#!else
#!define MULTIDOMAIN 0
#!endif
# - flags
# FLT_ - per transaction (message) flags
#!define FLT_ACC 1
#!define FLT_ACCMISSED 2
#!define FLT_ACCFAILED 3
#!define FLT_NATS 5
# FLB_ - per branch flags
#!define FLB_NATB 6
#!define FLB_NATSIPPING 7
####### Global Parameters #########
/* LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR, ... */
debug=DBGLEVEL
/* set to 'yes' to print log messages to terminal or use '-E' cli option
*/
log_stderror=no
memdbg=5
memlog=5
log_facility=LOG_LOCAL0
log_prefix="{$mt $hdr(CSeq) $ci} "
/* number of SIP routing processes for each UDP socket
* - value inherited by tcp_children and sctp_children when not set
explicitely */
children=8
/* uncomment the next line to disable TCP (default on) */
# disable_tcp=yes
/* number of SIP routing processes for all TCP/TLS sockets */
# tcp_children=8
/* uncomment the next line to disable the auto discovery of local aliases
* based on reverse DNS on IPs (default on) */
# auto_aliases=no
/* add local domain aliases - it can be set many times */
# alias="sip.mydomain.com"
/* listen sockets - if none set, Kamailio binds to all local IP addresses
* - basic prototype (full prototype can be found in Wiki - Core Cookbook):
* listen=[proto]:[localip]:[lport] advertise [publicip]:[pport]
* - it can be set many times to add more sockets to listen to */
listen=udp:X.X.X.X:5060
listen=udp:100.66.138.7:5060
/* life time of TCP connection when there is no traffic
* - a bit higher than registration expires to cope with UA behind NAT */
tcp_connection_lifetime=3605
/* upper limit for TCP connections (it includes the TLS connections) */
tcp_max_connections=2048
#!ifdef WITH_JSONRPC
tcp_accept_no_cl=yes
#!endif
#!ifdef WITH_TLS
enable_tls=yes
/* upper limit for TLS connections */
tls_max_connections=2048
#!endif
/* set it to yes to enable sctp and load sctp.so module */
enable_sctp=no
####### Custom Parameters #########
/* These parameters can be modified runtime via RPC interface
* - see the documentation of 'cfg_rpc' module.
*
* Format: group.id = value 'desc' description
* Access: $sel(cfg_get.group.id) or @cfg_get.group.id */
#!ifdef WITH_PSTN
/* PSTN GW Routing
*
* - pstn.gw_ip: valid IP or hostname as string value, example:
* pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"
*
* - by default is empty to avoid misrouting */
pstn.gw_ip = "" desc "PSTN GW Address"
pstn.gw_port = "" desc "PSTN GW Port"
#!endif
#!ifdef WITH_VOICEMAIL
/* VoiceMail Routing on offline, busy or no answer
*
* - by default Voicemail server IP is empty to avoid misrouting */
voicemail.srv_ip = "" desc "VoiceMail IP Address"
voicemail.srv_port = "5060" desc "VoiceMail Port"
#!endif
####### Modules Section ########
/* set paths to location of modules */
# mpath="/usr/lib/x86_64-linux-gnu/kamailio/modules/"
#!ifdef WITH_MYSQL
loadmodule "db_mysql.so"
#!endif
#!ifdef WITH_JSONRPC
loadmodule "xhttp.so"
#!endif
loadmodule "jsonrpcs.so"
loadmodule "kex.so"
loadmodule "corex.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 "textopsx.so"
loadmodule "siputils.so"
loadmodule "xlog.so"
loadmodule "sanity.so"
loadmodule "ctl.so"
loadmodule "cfg_rpc.so"
loadmodule "acc.so"
loadmodule "counters.so"
loadmodule "rtpengine.so"
#loadmodule "rtpproxy.so"
#!ifdef WITH_WEBSOCKETS
loadmodule "xhttp.so"
loadmodule "websocket.so"
# loadmodule "nathelper.so"
#!endif
#!ifdef WITH_AUTH
loadmodule "auth.so"
loadmodule "auth_db.so"
#!ifdef WITH_IPAUTH
loadmodule "permissions.so"
#!endif
#!endif
#!ifdef WITH_ALIASDB
loadmodule "alias_db.so"
#!endif
#!ifdef WITH_SPEEDDIAL
loadmodule "speeddial.so"
#!endif
#!ifdef WITH_MULTIDOMAIN
loadmodule "domain.so"
#!endif
#!ifdef WITH_PRESENCE
loadmodule "presence.so"
loadmodule "presence_xml.so"
#!endif
#!ifdef WITH_NAT
loadmodule "nathelper.so"
#!ifdef WITH_RTPENGINE
#!else
#!loadmodule "rtpproxy.so"
#!endif
#!endif
#!ifdef WITH_TLS
loadmodule "tls.so"
#!endif
#!ifdef WITH_ANTIFLOOD
loadmodule "htable.so"
loadmodule "pike.so"
#!endif
#!ifdef WITH_DEBUG
loadmodule "debugger.so"
#!endif
# ----------------- setting module-specific parameters ---------------
# ----- jsonrpcs params -----
modparam("jsonrpcs", "pretty_format", 1)
/* set the path to RPC fifo control file */
# modparam("jsonrpcs", "fifo_name",
"/run/kamailio/kamailio_rpc.fifo")
/* set the path to RPC unix socket control file */
# modparam("jsonrpcs", "dgram_socket",
"/run/kamailio/kamailio_rpc.sock")
#!ifdef WITH_JSONRPC
modparam("jsonrpcs", "transport", 7)
#!endif
# ----- ctl params -----
/* set the path to RPC unix socket control file */
# modparam("ctl", "binrpc",
"unix:/run/kamailio/kamailio_ctl")
# ----- sanity params -----
modparam("sanity", "autodrop", 0)
# ----- tm params -----
# auto-discard branches from previous serial forking leg
modparam("tm", "failure_reply_mode", 3)
# default retransmission timeout: 30sec
modparam("tm", "fr_timer", 30000)
# default invite retransmission timeout after 1xx: 120sec
modparam("tm", "fr_inv_timer", 120000)
#rtp
modparam("rtpengine", "rtpengine_sock",
"udp:127.0.0.1:2223")
modparam("rtpengine", "force_send_interface",
"100.66.138.7")
#modparam("rtpproxy", "rtpproxy_sock",
"udp:127.0.0.1:7722")
# ----- rr params -----
# set next param to 1 to add value to ;lr param (helps with some UAs)
modparam("rr", "enable_full_lr", 0)
# 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)
/* uncomment the next line to disable parallel forking via location */
# modparam("registrar", "append_branches", 0)
/* uncomment the next line not to allow more than 10 contacts per AOR */
# modparam("registrar", "max_contacts", 10)
/* max value for expires of registrations */
modparam("registrar", "max_expires", 3600)
/* set it to 1 to enable GRUU */
modparam("registrar", "gruu_enabled", 0)
/* set it to 0 to disable Path handling */
modparam("registrar", "use_path", 1)
/* save Path even if not listed in Supported header */
modparam("registrar", "path_mode", 0)
# ----- 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)
modparam("acc", "log_extra",
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
/* enhanced DB accounting */
#!ifdef WITH_ACCDB
modparam("acc", "db_flag", FLT_ACC)
modparam("acc", "db_missed_flag", FLT_ACCMISSED)
modparam("acc", "db_url", DBURL)
modparam("acc", "db_extra",
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
#!endif
# ----- usrloc params -----
modparam("usrloc", "timer_interval", 60)
modparam("usrloc", "timer_procs", 1)
modparam("usrloc", "use_domain", MULTIDOMAIN)
/* enable DB persistency for location entries */
#!ifdef WITH_USRLOCDB
modparam("usrloc", "db_url", DBURL)
modparam("usrloc", "db_mode", 2)
#!endif
# ----- auth_db params -----
#!ifdef WITH_AUTH
modparam("auth_db", "db_url", DBURL)
modparam("auth_db", "calculate_ha1", yes)
modparam("auth_db", "password_column", "password")
modparam("auth_db", "load_credentials", "")
modparam("auth_db", "use_domain", MULTIDOMAIN)
# ----- permissions params -----
#!ifdef WITH_IPAUTH
modparam("permissions", "db_url", DBURL)
modparam("permissions", "load_backends", 1)
#!endif
#!endif
# ----- alias_db params -----
#!ifdef WITH_ALIASDB
modparam("alias_db", "db_url", DBURL)
modparam("alias_db", "use_domain", MULTIDOMAIN)
#!endif
# ----- speeddial params -----
#!ifdef WITH_SPEEDDIAL
modparam("speeddial", "db_url", DBURL)
modparam("speeddial", "use_domain", MULTIDOMAIN)
#!endif
# ----- domain params -----
#!ifdef WITH_MULTIDOMAIN
modparam("domain", "db_url", DBURL)
/* register callback to match myself condition with domains list */
modparam("domain", "register_myself", 1)
#!endif
#!ifdef WITH_PRESENCE
# ----- presence params -----
modparam("presence", "db_url", DBURL)
# ----- presence_xml params -----
modparam("presence_xml", "db_url", DBURL)
modparam("presence_xml", "force_active", 1)
#!endif
#!ifdef WITH_NAT
#!ifdef WITH_RTPENGINE
# ----- rtpengine params -----
#modparam("rtpengine", "rtpengine_sock",
"udp:127.0.0.1:2223")
#!else
# ----- rtpproxy params -----
#!modparam("rtpproxy", "rtpproxy_sock",
"udp:127.0.0.1:7722")
#!endif
# ----- nathelper params -----
modparam("nathelper", "natping_interval", 30)
modparam("nathelper", "ping_nated_only", 1)
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
modparam("nathelper", "sipping_from",
"sip:pinger@sip.super.fr")
#modparam("nathelper", "sipping_method", "OPTIONS")
# params needed for NAT traversal in other modules
modparam("nathelper|registrar", "received_avp",
"$avp(RECEIVED)")
modparam("usrloc", "nat_bflag", FLB_NATB)
#!endif
#!ifdef WITH_TLS
# ----- tls params -----
modparam("tls", "config", "/etc/kamailio/tls.cfg")
#!endif
#!ifdef WITH_ANTIFLOOD
# ----- pike params -----
modparam("pike", "sampling_time_unit", 2)
modparam("pike", "reqs_density_per_unit", 40)
modparam("pike", "remove_latency", 4)
# ----- htable params -----
/* ip ban htable with autoexpire after 5 minutes */
modparam("htable", "htable",
"ipban=>size=8;autoexpire=300;")
#!endif
#!ifdef WITH_DEBUG
# ----- debugger params -----
modparam("debugger", "cfgtrace", 1)
modparam("debugger", "log_level_name", "exec")
#!endif
######## websocket ############
#!ifdef WITH_TLS
enable_tls=yes
#!endif
listen=MY_IP_ADDR
#!ifdef WITH_WEBSOCKETS
listen=MY_WS_ADDR
tcp_accept_no_cl=yes
# tcp_rd_buf_size=65536
#!ifdef WITH_TLS
listen=MY_WSS_ADDR
#!endif
#!endif
######## SECURITY #######
server_signature=no
sip_warning=0
user_agent_header="User-Agent: SIP Server"
####### Routing Logic ########
/* Main SIP request routing logic
* - processing of any incoming SIP request starts with this route
* - note: this is the same as route { ... } */
request_route {
route(REQINIT);
route(NATDETECT);
route(REGISTER);
route(INVITE);
route(ACK);
route(BYE);
return;
}
# Wrapper for relaying requests
#Check initial detail
route[REQINIT] {
# no connect for sending replies
set_reply_no_connect();
# enforce symmetric signaling
# - send back replies to the source address of request
force_rport();
if($ua =~ "friendly|scanner|sipcli|sipvicious|VaxSIPUserAgent|pplsip") {
# silent drop for scanners - uncomment next line if want to reply
# sl_send_reply("200", "OK");
exit;
}
if (!mf_process_maxfwd_header("10")) {
sl_send_reply("483", "Too Many Hops");
exit;
}
if(is_method("OPTIONS") && uri==myself && $rU==$null) {
sl_send_reply("200", "Keepalive");
exit;
}
if(!sanity_check("17895", "7")) {
xlog("Malformed SIP request from $si:$sp\n");
exit;
}
}
# Caller NAT detection
route[NATDETECT] {
#!ifdef WITH_NAT
force_rport();
if (nat_uac_test("19")) {
if (is_method("REGISTER")) {
fix_nated_register();
} else {
if(is_first_hop()) {
set_contact_alias();
}
}
setflag(FLT_NATS);
}
#!endif
return;
}
route[REGISTER] {
if (is_method("REGISTER")) {
t_on_reply("1");
force_send_socket(100.66.138.7:5060);
t_relay_to_udp("100.66.138.5", "5060");
exit();
}
}
route[INVITE] {
if (( is_method("REFER")) || is_method("INVITE")
||is_method("NOTIFY")) {
record_route();
if (src_ip == "100.66.138.5") {
if(lookup("location") &&
!is_method("OPTIONS")) {
xlog("L_NOTICE", "user enregistrax");
force_send_socket(X.X.X.X:5060);
rtpengine_manage("replace-origin
replace-session-connection media-address=X.X.X.X direction=priv
direction=pub");
t_relay();
}
else {
sl_send_reply("403","Not registred");
}
} else {
force_send_socket(100.66.138.7:5060);
rtpengine_manage("replace-origin
replace-session-connection media-address=100.66.138.7 direction=pub
direction=priv");
t_relay_to_udp("100.66.138.5", "5060");
}
}
}
route[ACK] {
if (is_method("ACK")) {
if (src_ip == "100.66.138.5") {
force_send_socket(udp:X.X.X.X:5060);
t_relay();
} else {
force_send_socket(udp:100.66.138.7:5060);
t_relay();
}
exit();
}
}
route[BYE] {
if (is_method("BYE|CANCEL")) {
if (src_ip == "100.66.138.5") {
force_send_socket(udp:X.X.X.X:5060);
t_relay();
} else {
force_send_socket(udp:100.66.138.7:5060);
t_relay();
}
exit();
}
}
onreply_route {
if (status=~ "180|183") {
rtpengine_manage("replace-origin
replace-session-connection");
}
if (status=~ "200") {
if(has_body("application/sdp")) {
rtpengine_manage("replace-origin
replace-session-connection");
}
}
}
onreply_route[1] {
if (status=~ "2[0-9][0-9]"){
save("location");
xlog("L_NOTICE", "enregistrement");
}
}
====================