Hi Daniel, that seems to fix the problem :D. Thank you very much.
6(29076) DEBUG: presence [notify.c:927]: ps_build_dlg_t(): CONTACT = sip:1000@93.220.237.128:64632;transport=ws 6(29076) DEBUG: <core> [socket_info.c:583]: grep_sock_info(): grep_sock_info - checking if host==us: 12==12 && [5.45.101.128] == [5.45.101.128] 6(29076) DEBUG: <core> [socket_info.c:587]: grep_sock_info(): grep_sock_info - checking if port 8088 (advertise 0) matches port 8088 6(29076) DEBUG: presence [notify.c:1575]: send_notify_request(): expires 600 status 1 6(29076) DEBUG: presence [notify.c:1728]: shm_dup_cbparam(): === 22/8/37 6(29076) DEBUG: tm [uac.c:243]: t_uac_prepare(): DEBUG:tm:t_uac: next_hop=<sip:1000@93.220.237.128:64632;transport=ws> 6(29076) DEBUG: tm [uac.c:182]: dlg2hash(): DEBUG: dlg2hash: 5285 6(29076) DEBUG: websocket [ws_frame.c:713]: ws_frame_transmit(): Tx message: NOTIFY sip:1000@93.220.237.128:64632;transport=ws SIP/2.0 Via: SIP/2.0/WS 5.45.101.128:8088;branch=z9hG4bK5a41.38587e65000000000000000000000000.0 To: <sip:1...@claybourne.de>;tag=vj3bsbnevo From: <sip:1...@claybourne.de>;tag=6853f4be2e83d57dcdf85008ad4e4098-aa21 CSeq: 2 NOTIFY Call-ID: jb3kmva261v4bht3sj9...@claybourne.de Content-Length: 0 User-Agent: kamailio (4.1.1 (x86_64/linux)) Max-Forwards: 70 Event: presence Contact: <sip:5.45.101.128:8088;transport=ws> Subscription-State: active;expires=600 6(29076) DEBUG: websocket [ws_frame.c:146]: encode_and_send_ws_frame(): encoding WebSocket frame 6(29076) DEBUG: websocket [ws_frame.c:177]: encode_and_send_ws_frame(): supported non-control frame: 0x1 6(29076) DEBUG: <core> [tcp_main.c:2320]: tcpconn_send_put(): tcp_send: send from reader (29076 (6)), reusing fd 6(29076) DEBUG: <core> [tcp_main.c:2556]: tcpconn_do_send(): tcp_send: sending... 6(29076) DEBUG: <core> [tcp_main.c:2590]: tcpconn_do_send(): tcp_send: after real write: c= 0x7faebf0348b0 n=523 fd=6 6(29076) DEBUG: <core> [tcp_main.c:2591]: tcpconn_do_send(): tcp_send: buf= ?~NOTIFY sip:1000@93.220.237.128:64632;transport=ws SIP/2.0 Via: SIP/2.0/WS 5.45.101.128:8088;branch=z9hG4bK5a41.38587e65000000000000000000000000.0 To: <sip:1...@claybourne.de>;tag=vj3bsbnevo From: <sip:1...@claybourne.de>;tag=6853f4be2e83d57dcdf85008ad4e4098-aa21 CSeq: 2 NOTIFY Call-ID: jb3kmva261v4bht3sj9...@claybourne.de Content-Length: 0 User-Agent: kamailio (4.1.1 (x86_64/linux)) Max-Forwards: 70 Event: presence Contact: <sip:5.45.101.128:8088;transport=ws> Subscription-State: active;expires=600 6(29076) INFO: presence [notify.c:1602]: send_notify_request(): NOTIFY sip:1...@claybourne.de via sip:1000@93.220.237.128:64632;transport=ws on behalf of sip:1...@claybourne.de for event presence Just added your suggestion in my config file. # Presence server route route[PRESENCE] { xlog("SCRIPT: Mal sehen 7\n"); if(!is_method("PUBLISH|SUBSCRIBE")) return; #!ifdef WITH_PRESENCE if (!t_newtran()) { sl_reply_error(); exit; }; if(is_method("PUBLISH")) { handle_publish(); t_release(); } else if( is_method("SUBSCRIBE")) { fix_nated_contact(); handle_subscribe(); t_release(); } #!endif # if presence enabled, this part will not be executed if (is_method("PUBLISH") || $rU==$null) { sl_send_reply("404", "Not here"); exit; } return; } Your Project rocks. Can you add this fix to the web socket example config for all others :D? Greetings David Am 31.01.2014 um 06:19 schrieb Daniel-Constantin Mierla <mico...@gmail.com>: > Hello, > > can you try to use fix_nated_contact() for subscribe requests? > > Cheers, > Daniel > > On 28/01/14 23:17, David Claybourne wrote: >> Hi Kamailio-Community, >> >> i have the following problem. Publish and subscribe works as suspected. But >> after saving the presence state from a publish request and notifying the >> users via NOTIFY, users with a websocket connection don't get the notify >> request at all :(. >> >> Here is the version of kamailio i use: >> >> version: kamailio 4.1.1 (x86_64/linux) >> flags: STATS: Off, USE_TCP, USE_TLS, TLS_HOOKS, USE_RAW_SOCKS, >> DISABLE_NAGLE, USE_MCAST, DNS_IP_HACK, SHM_MEM, SHM_MMAP, PKG_MALLOC, >> DBG_QM_MALLOC, USE_FUTEX, FAST_LOCK-ADAPTIVE_WAIT, USE_DNS_CACHE, >> USE_DNS_FAILOVER, USE_NAPTR, USE_DST_BLACKLIST, HAVE_RESOLV_RES >> ADAPTIVE_WAIT_LOOPS=1024, MAX_RECV_BUFFER_SIZE 262144, MAX_LISTEN 16, >> MAX_URI_SIZE 1024, BUF_SIZE 65535, DEFAULT PKG_SIZE 4MB >> poll method support: poll, epoll_lt, epoll_et, sigio_rt, select. >> >> I created a log file and attached the notify event (the problem is that a >> websocket dont have a real IP Address), is there any possibility to use the >> nathelper module for fixing this problem? >> >> I also attached the config file. Thanks for the help >> >> Greetings >> David >> >> Log: >> >> 9(25950) DEBUG: presence [notify.c:1470]: send_notify_request(): dialog >> info: >> 9(25950) DEBUG: presence [notify.c:117]: printf_subs(): pres_uri: >> sip:1...@example.com >> 9(25950) DEBUG: presence [notify.c:118]: printf_subs(): >> watcher_user@watcher_domain: 1...@example.com >> 9(25950) DEBUG: presence [notify.c:119]: printf_subs(): to_user@to_domain: >> 1...@example.com >> 9(25950) DEBUG: presence [notify.c:120]: printf_subs(): >> from_user@from_domain: 1...@example.com >> 9(25950) DEBUG: presence [notify.c:121]: printf_subs(): >> callid/from_tag/to_tag: >> sc19bmkpmluh91btkc4...@example.com/o0cqavak8u/6853f4be2e83d57dcdf85008ad4e4098-9f19 >> 9(25950) DEBUG: presence [notify.c:122]: printf_subs(): >> local_cseq/remote_cseq: 2/4 >> 9(25950) DEBUG: presence [notify.c:123]: printf_subs(): >> local_contact/contact: >> sip:5.45.101.128:8088;transport=ws/sip:1000@7b1g33n1ji.invalid >> 9(25950) DEBUG: presence [notify.c:124]: printf_subs(): record_route: >> 9(25950) DEBUG: presence [notify.c:125]: printf_subs(): sockinfo_str: >> tcp:5.45.101.128:8088 >> 9(25950) DEBUG: presence [notify.c:126]: printf_subs(): event: presence >> 9(25950) DEBUG: presence [notify.c:127]: printf_subs(): status: active >> 9(25950) DEBUG: presence [notify.c:128]: printf_subs(): reason: >> 9(25950) DEBUG: presence [notify.c:129]: printf_subs(): version: 2 >> 9(25950) DEBUG: presence [notify.c:130]: printf_subs(): expires: 595 >> 9(25950) DEBUG: presence [notify.c:132]: printf_subs(): >> updated/updated_winfo: 0/0 >> 9(25950) DEBUG: presence [notify.c:1563]: send_notify_request(): headers: >> Max-Forwards: 70 >> Event: presence >> Contact: <sip:5.45.101.128:8088;transport=ws> >> Subscription-State: active;expires=595 >> Content-Type: application/pidf+xml >> >> 9(25950) DEBUG: presence [notify.c:925]: ps_build_dlg_t(): CONTACT = >> sip:1000@7b1g33n1ji.invalid >> 9(25950) DEBUG: <core> [socket_info.c:583]: grep_sock_info(): >> grep_sock_info - checking if host==us: 12==12 && [5.45.101.128] == >> [5.45.101.128] >> 9(25950) DEBUG: <core> [socket_info.c:587]: grep_sock_info(): >> grep_sock_info - checking if port 8088 (advertise 0) matches port 8088 >> 9(25950) DEBUG: presence [notify.c:1573]: send_notify_request(): expires >> 595 status 1 >> 9(25950) DEBUG: presence [notify.c:1726]: shm_dup_cbparam(): === 22/8/37 >> 9(25950) DEBUG: tm [uac.c:243]: t_uac_prepare(): DEBUG:tm:t_uac: >> next_hop=<sip:1000@7b1g33n1ji.invalid> >> 9(25950) DEBUG: <core> [dns_cache.c:569]: _dns_hash_find(): >> dns_hash_find((0), 33), h=0 >> 9(25950) DEBUG: <core> [dns_cache.c:569]: _dns_hash_find(): >> dns_hash_find(7b1g33n1ji.invalid(18), 1), h=745 >> 9(25950) ERROR: <core> [resolve.c:1733]: sip_hostport2su(): ERROR: >> sip_hostport2su: could not resolve hostname: "7b1g33n1ji.invalid" >> 9(25950) ERROR: tm [ut.h:337]: uri2dst2(): failed to resolve >> "7b1g33n1ji.invalid" >> 9(25950) ERROR: tm [uac.c:266]: t_uac_prepare(): t_uac: no socket found >> 9(25950) ERROR: presence [notify.c:1590]: send_notify_request(): in >> function tmb.t_request_within >> 9(25950) ERROR: presence [notify.c:1677]: notify(): sending Notify not >> successful >> 9(25950) ERROR: presence [notify.c:1275]: publ_notify(): Could not send >> notify for presence >> >> >> >> Config: >> >> #!KAMAILIO >> # >> # Kamailio (OpenSER) SIP Server v4.0 - default configuration script >> # - web: http://www.kamailio.org >> # - git: http://sip-router.org >> # >> # Direct your questions about this file to: <sr-users@lists.sip-router.org> >> # >> # Refer to the Core CookBook at http://www.kamailio.org/wiki/ >> # for an explanation of possible statements, functions and parameters. >> # >> # Several features can be enabled using '#!define WITH_FEATURE' directives: >> # >> # *** To run in debug mode: >> # - define WITH_DEBUG >> # >> # *** To enable mysql: >> # - define WITH_MYSQL >> # >> # *** To enable authentication execute: >> # - enable mysql >> # - define WITH_AUTH >> # - add users using 'kamctl' >> # >> # *** To enable IP authentication execute: >> # - enable mysql >> # - enable authentication >> # - define WITH_IPAUTH >> # - add IP addresses with group id '1' to 'address' table >> # >> # *** To enable persistent user location execute: >> # - enable mysql >> # - define WITH_USRLOCDB >> # >> # *** To enable presence server execute: >> # - enable mysql >> # - define WITH_PRESENCE >> # >> # *** To enable nat traversal execute: >> # - define WITH_NAT >> # - install RTPProxy: http://www.rtpproxy.org >> # - start RTPProxy: >> # rtpproxy -l _your_public_ip_ -s udp:localhost:7722 >> # >> # *** To enable PSTN gateway routing execute: >> # - define WITH_PSTN >> # - set the value of pstn.gw_ip >> # - check route[PSTN] for regexp routing condition >> # >> # *** To enable database aliases lookup execute: >> # - enable mysql >> # - define WITH_ALIASDB >> # >> # *** To enable speed dial lookup execute: >> # - enable mysql >> # - define WITH_SPEEDDIAL >> # >> # *** To enable multi-domain support execute: >> # - enable mysql >> # - define WITH_MULTIDOMAIN >> # >> # *** To enable TLS support execute: >> # - adjust CFGDIR/tls.cfg as needed >> # - define WITH_TLS >> # >> # *** To enable XMLRPC support execute: >> # - define WITH_XMLRPC >> # - adjust route[XMLRPC] for access policy >> # >> # *** To enable anti-flood detection execute: >> # - adjust pike and htable=>ipban settings as needed (default is >> # block if more than 16 requests in 2 seconds and ban for 300 seconds) >> # - define WITH_ANTIFLOOD >> # >> # *** To block 3XX redirect replies execute: >> # - define WITH_BLOCK3XX >> # >> # *** To enable VoiceMail routing execute: >> # - define WITH_VOICEMAIL >> # - set the value of voicemail.srv_ip >> # - adjust the value of voicemail.srv_port >> # >> # *** To enhance accounting execute: >> # - enable mysql >> # - define WITH_ACCDB >> # - add following columns to database >> #!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 >> >> ####### Include Local Config If Exists ######### >> import_file "kamailio-local.cfg" >> >> ####### Defined Values ######### >> >> #LOAD MODULES NEEDED >> #!define WITH_AUTH >> #!define WITH_PRESENCE >> #!define WITH_MYSQL >> #!define WITH_TLS >> #!define WITH_WEBSOCKETS >> #!define WITH_DEBUG >> ##!define WITH_MSRP >> >> #!substdef "!MY_IP_ADDR!5.45.101.128!g" >> #!substdef "!MY_DOMAIN!5.45.101.128!g" >> #!substdef "!MY_WS_PORT!8088!g" >> #!substdef "!MY_WSS_PORT!8089!g" >> #!substdef "!MY_MSRP_PORT!9000!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_ADDR!tls:MY_IP_ADDR:MY_MSRP_PORT!g" >> #!substdef "!MSRP_MIN_EXPIRES!1800!g" >> #!substdef "!MSRP_MAX_EXPIRES!3600!g" >> >> # *** Value defines - IDs used later in config >> #!ifdef WITH_MYSQL >> # - database URL - used to connect to database server by modules such >> # as: auth_db, acc, usrloc, a.s.o. >> #!ifndef DBURL >> #!define DBURL "mysql://kamailio:databasepassword@localhost/kamailio" >> #!endif >> #!endif >> #!ifdef WITH_MULTIDOMAIN >> # - the value for 'use_domain' parameters >> #!define MULTIDOMAIN 1 >> #!else >> #!define MULTIDOMAIN 0 >> #!endif >> >> # - 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 >> #!define FLB_NATSIPPING 7 >> >> ####### Global Parameters ######### >> >> ### LOG Levels: 3=DBG, 2=INFO, 1=NOTICE, 0=WARN, -1=ERR >> #!ifdef WITH_DEBUG >> debug=4 >> log_stderror=yes >> #!else >> debug=2 >> log_stderror=no >> #!endif >> >> memdbg=5 >> memlog=5 >> >> log_facility=LOG_LOCAL0 >> >> fork=yes >> children=4 >> >> /* uncomment the next line to disable TCP (default on) */ >> #disable_tcp=yes >> >> /* 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 */ >> alias="example.com" >> >> /* 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:10.0.0.10:5060 >> >> /* port to listen to >> * - can be specified more than once if needed to listen on many ports */ >> port=5060 >> >> #!ifdef WITH_TLS >> enable_tls=yes >> #!endif >> >> #listen=MY_IP_ADDR >> #!ifdef WITH_WEBSOCKETS >> listen=MY_WS_ADDR >> #!ifdef WITH_TLS >> listen=MY_WSS_ADDR >> #!endif >> #!endif >> #!ifdef WITH_MSRP >> listen=MY_MSRP_ADDR >> #!endif >> >> tcp_connection_lifetime=3604 >> tcp_accept_no_cl=yes >> tcp_rd_buf_size=16384 >> >> #syn_branch=0 >> >> # 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 >> >> ####### 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 (to sources or installation folders) >> #!ifdef WITH_SRCPATH >> mpath="modules_k:modules" >> #!else >> mpath="/usr/local/lib64/kamailio/modules/" >> #!endif >> >> #!ifdef WITH_MYSQL >> loadmodule "db_mysql.so" >> #!endif >> >> loadmodule "mi_fifo.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 "siputils.so" >> loadmodule "xlog.so" >> loadmodule "sanity.so" >> loadmodule "ctl.so" >> loadmodule "cfg_rpc.so" >> loadmodule "mi_rpc.so" >> loadmodule "acc.so" >> >> #!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" >> loadmodule "rtpproxy.so" >> #!endif >> >> #!ifdef WITH_TLS >> loadmodule "tls.so" >> #!endif >> >> #!ifdef WITH_MSRP >> loadmodule "msrp.so" >> loadmodule "htable.so" >> loadmodule "cfgutils.so" >> #!endif >> >> #!ifdef WITH_WEBSOCKETS >> loadmodule "xhttp.so" >> loadmodule "websocket.so" >> loadmodule "nathelper.so" >> #!endif >> >> #!ifdef WITH_ANTIFLOOD >> loadmodule "htable.so" >> loadmodule "pike.so" >> #!endif >> >> #!ifdef WITH_XMLRPC >> loadmodule "xmlrpc.so" >> #!endif >> >> #!ifdef WITH_DEBUG >> loadmodule "debugger.so" >> #!endif >> >> # ----------------- 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) >> # default retransmission timeout: 30sec >> modparam("tm", "fr_timer", 30000) >> # default invite retransmission timeout after 1xx: 120sec >> 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) >> /* 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", 120) >> # set it to 1 to enable GRUU >> modparam("registrar", "gruu_enabled", 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 ----- >> /* enable DB persistency for location entries */ >> #!ifdef WITH_USRLOCDB >> modparam("usrloc", "db_url", DBURL) >> modparam("usrloc", "db_mode", 2) >> modparam("usrloc", "use_domain", MULTIDOMAIN) >> #!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", "db_mode", 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 >> # ----- rtpproxy params ----- >> modparam("rtpproxy", "rtpproxy_sock", "udp:127.0.0.1:7722") >> >> # ----- nathelper params ----- >> modparam("nathelper", "natping_interval", 30) >> modparam("nathelper", "ping_nated_only", 1) >> modparam("nathelper", "sipping_bflag", FLB_NATSIPPING) >> modparam("nathelper", "sipping_from", "sip:pin...@kamailio.org") >> >> # 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", "/usr/local/etc/kamailio/tls.cfg") >> #!endif >> >> #!ifdef WITH_WEBSOCKETS >> # ----- nathelper params ----- >> modparam("nathelper|registrar", "received_avp", "$avp(RECEIVED)") >> # Note: leaving NAT pings turned off here as nathelper is _only_ being used >> for >> # WebSocket connections. NAT pings are not needed as WebSockets have >> # their own keep-alives. >> #!endif >> >> #!ifdef WITH_MSRP >> # ----- htable params ----- >> modparam("htable", "htable", "msrp=>size=8;autoexpire=MSRP_MAX_EXPIRES;") >> #!endif >> >> #!ifdef WITH_ANTIFLOOD >> # ----- pike params ----- >> modparam("pike", "sampling_time_unit", 2) >> modparam("pike", "reqs_density_per_unit", 16) >> 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_XMLRPC >> # ----- xmlrpc params ----- >> modparam("xmlrpc", "route", "XMLRPC"); >> modparam("xmlrpc", "url_match", "^/RPC") >> #!endif >> >> #!ifdef WITH_DEBUG >> # ----- debugger params ----- >> modparam("debugger", "cfgtrace", 1) >> #!endif >> >> ####### 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 { >> >> # per request initial checks >> route(REQINIT); >> >> #!ifdef WITH_WEBSOCKETS >> if (nat_uac_test(64)) { >> # Do NAT traversal stuff for requests from a WebSocket >> # connection - even if it is not behind a NAT! >> # This won't be needed in the future if Kamailio and the >> # WebSocket client support Outbound and Path. >> force_rport(); >> if (is_method("REGISTER")) { >> fix_nated_register(); >> } else { >> if (!add_contact_alias()) { >> xlog("L_ERR", "Error aliasing contact <$ct>\n"); >> sl_send_reply("400", "Bad Request"); >> exit; >> } >> } >> } >> #!endif >> >> # NAT detection >> route(NATDETECT); >> >> # CANCEL processing >> if (is_method("CANCEL")) >> { >> if (t_check_trans()) { >> route(RELAY); >> } >> exit; >> } >> >> # handle requests within SIP dialogs >> route(WITHINDLG); >> >> ### only initial requests (no To tag) >> >> t_check_trans(); >> >> # authentication >> 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 >> } >> >> # dispatch requests to foreign domains >> route(SIPOUT); >> >> ### requests for my local domains >> >> # handle presence related requests >> route(PRESENCE); >> >> # handle registrations >> route(REGISTRAR); >> >> if ($rU==$null) >> { >> # request with no Username in RURI >> sl_send_reply("484","Address Incomplete"); >> exit; >> } >> >> # dispatch destinations to PSTN >> route(PSTN); >> >> # user location service >> route(LOCATION); >> } >> >> >> route[RELAY] { >> >> # enable additional event routes for forwarded requests >> # - serial forking, RTP relaying handling, a.s.o. >> if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE")) { >> if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH"); >> } >> if (is_method("INVITE|SUBSCRIBE|UPDATE")) { >> if(!t_is_set("onreply_route")) t_on_reply("MANAGE_REPLY"); >> } >> if (is_method("INVITE")) { >> if(!t_is_set("failure_route")) t_on_failure("MANAGE_FAILURE"); >> } >> >> if (!t_relay()) { >> sl_reply_error(); >> } >> exit; >> } >> >> # Per SIP request initial checks >> route[REQINIT] { >> #!ifdef WITH_ANTIFLOOD >> # flood dection from same IP and traffic ban for a while >> # be sure you exclude checking trusted peers, such as pstn gateways >> # - local host excluded (e.g., loop to self) >> if(src_ip!=myself) >> { >> if($sht(ipban=>$si)!=$null) >> { >> # ip is already blocked >> xdbg("request from blocked IP - $rm from $fu (IP:$si:$sp)\n"); >> exit; >> } >> if (!pike_check_req()) >> { >> xlog("L_ALERT","ALERT: pike blocking $rm from $fu >> (IP:$si:$sp)\n"); >> $sht(ipban=>$si) = 1; >> exit; >> } >> } >> #!endif >> >> if (!mf_process_maxfwd_header("10")) { >> sl_send_reply("483","Too Many Hops"); >> exit; >> } >> >> if(!sanity_check("1511", "7")) >> { >> xlog("Malformed SIP message from $si:$sp\n"); >> exit; >> } >> } >> >> # Handle requests within SIP dialogs >> route[WITHINDLG] { >> if (has_totag()) { >> # sequential request withing a dialog should >> # take the path determined by record-routing >> if (loose_route()) { >> #!ifdef WITH_WEBSOCKETS >> if ($du == "") { >> if (!handle_ruri_alias()) { >> xlog("L_ERR", "Bad alias <$ru>\n"); >> sl_send_reply("400", "Bad Request"); >> exit; >> } >> } >> #!endif >> route(DLGURI); >> if (is_method("BYE")) { >> setflag(FLT_ACC); # do accounting ... >> setflag(FLT_ACCFAILED); # ... even if the transaction fails >> } >> else if ( is_method("ACK") ) { >> # ACK is forwarded statelessy >> route(NATMANAGE); >> } >> else if ( is_method("NOTIFY") ) { >> # Add Record-Route for in-dialog NOTIFY as per RFC 6665. >> record_route(); >> } >> route(RELAY); >> } else { >> if (is_method("SUBSCRIBE") && uri == myself) { >> # in-dialog subscribe requests >> route(PRESENCE); >> exit; >> } >> if ( is_method("ACK") ) { >> if ( t_check_trans() ) { >> # no loose-route, but stateful ACK; >> # must be an ACK after a 487 >> # or e.g. 404 from upstream server >> route(RELAY); >> exit; >> } else { >> # ACK without matching transaction ... ignore and discard >> exit; >> } >> } >> sl_send_reply("404","Not here"); >> } >> exit; >> } >> } >> >> # Handle SIP registrations >> route[REGISTRAR] { >> if (is_method("REGISTER")) >> { >> if(isflagset(FLT_NATS)) >> { >> setbflag(FLB_NATB); >> # uncomment next line to do SIP NAT pinging >> ## setbflag(FLB_NATSIPPING); >> } >> if (!save("location")) >> sl_reply_error(); >> >> exit; >> } >> } >> >> # USER location service >> route[LOCATION] { >> >> #!ifdef WITH_SPEEDDIAL >> # search for short dialing - 2-digit extension >> if($rU=~"^[0-9][0-9]$") >> if(sd_lookup("speed_dial")) >> route(SIPOUT); >> #!endif >> >> #!ifdef WITH_ALIASDB >> # search in DB-based aliases >> if(alias_db_lookup("dbaliases")) >> route(SIPOUT); >> #!endif >> >> $avp(oexten) = $rU; >> if (!lookup("location")) { >> $var(rc) = $rc; >> route(TOVOICEMAIL); >> t_newtran(); >> switch ($var(rc)) { >> case -1: >> case -3: >> send_reply("404", "Not Found"); >> exit; >> case -2: >> send_reply("405", "Method Not Allowed"); >> exit; >> } >> } >> >> # when routing via usrloc, log the missed calls also >> if (is_method("INVITE")) >> { >> setflag(FLT_ACCMISSED); >> } >> >> route(RELAY); >> exit; >> } >> >> # Presence server route >> route[PRESENCE] { >> if(!is_method("PUBLISH|SUBSCRIBE")) >> return; >> >> #!ifdef WITH_PRESENCE >> if (!t_newtran()) >> { >> sl_reply_error(); >> exit; >> }; >> >> if(is_method("PUBLISH")) >> { >> handle_publish(); >> t_release(); >> } >> else >> if( is_method("SUBSCRIBE")) >> { >> handle_subscribe(); >> t_release(); >> } >> exit; >> #!endif >> # if presence enabled, this part will not be executed >> if (is_method("PUBLISH") || $rU==$null) >> { >> sl_send_reply("404", "Not here"); >> exit; >> } >> return; >> } >> >> # Authentication route >> route[AUTH] { >> #!ifdef WITH_AUTH >> >> #!ifdef WITH_IPAUTH >> if((!is_method("REGISTER")) && allow_source_address()) >> { >> # source IP allowed >> return; >> } >> #!endif >> >> if (is_method("REGISTER") || from_uri==myself) >> { >> # authenticate requests >> if (!auth_check("$fd", "subscriber", "1")) { >> auth_challenge("$fd", "0"); >> exit; >> } >> # user authenticated - remove auth header >> if(!is_method("REGISTER|PUBLISH")) >> consume_credentials(); >> } >> # if caller is not local subscriber, then check if it calls >> # a local destination, otherwise deny, not an open relay here >> if (from_uri!=myself && uri!=myself) >> { >> sl_send_reply("403","Not relaying"); >> exit; >> } >> >> #!endif >> return; >> } >> >> # Caller NAT detection route >> route[NATDETECT] { >> #!ifdef WITH_NAT >> force_rport(); >> if (nat_uac_test("19")) { >> if (is_method("REGISTER")) { >> fix_nated_register(); >> } else { >> add_contact_alias(); >> } >> setflag(FLT_NATS); >> } >> #!endif >> return; >> } >> >> # RTPProxy control >> route[NATMANAGE] { >> #!ifdef WITH_NAT >> if (is_request()) { >> if(has_totag()) { >> if(check_route_param("nat=yes")) { >> setbflag(FLB_NATB); >> } >> } >> } >> if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) >> return; >> >> rtpproxy_manage(); >> >> if (is_request()) { >> if (!has_totag()) { >> add_rr_param(";nat=yes"); >> } >> } >> if (is_reply()) { >> if(isbflagset(FLB_NATB)) { >> add_contact_alias(); >> } >> } >> #!endif >> return; >> } >> >> # URI update for dialog requests >> route[DLGURI] { >> #!ifdef WITH_NAT >> if(!isdsturiset()) { >> handle_ruri_alias(); >> } >> #!endif >> return; >> } >> >> # Routing to foreign domains >> route[SIPOUT] { >> if (!uri==myself) >> { >> append_hf("P-hint: outbound\r\n"); >> route(RELAY); >> } >> } >> >> # PSTN GW routing >> route[PSTN] { >> #!ifdef WITH_PSTN >> # check if PSTN GW IP is defined >> if (strempty($sel(cfg_get.pstn.gw_ip))) { >> xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n"); >> return; >> } >> >> # route to PSTN dialed numbers starting with '+' or '00' >> # (international format) >> # - update the condition to match your dialing rules for PSTN routing >> if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$")) >> return; >> >> # only local users allowed to call >> if(from_uri!=myself) { >> sl_send_reply("403", "Not Allowed"); >> exit; >> } >> >> if (strempty($sel(cfg_get.pstn.gw_port))) { >> $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip); >> } else { >> $ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip) + ":" >> + $sel(cfg_get.pstn.gw_port); >> } >> >> route(RELAY); >> exit; >> #!endif >> >> return; >> } >> >> # XMLRPC routing >> #!ifdef WITH_XMLRPC >> route[XMLRPC] { >> # allow XMLRPC from localhost >> if ((method=="POST" || method=="GET") >> && (src_ip==127.0.0.1)) { >> # close connection only for xmlrpclib user agents (there is a bug in >> # xmlrpclib: it waits for EOF before interpreting the response). >> if ($hdr(User-Agent) =~ "xmlrpclib") >> set_reply_close(); >> set_reply_no_connect(); >> dispatch_rpc(); >> exit; >> } >> send_reply("403", "Forbidden"); >> exit; >> } >> #!endif >> >> # route to voicemail server >> route[TOVOICEMAIL] { >> #!ifdef WITH_VOICEMAIL >> if(!is_method("INVITE")) >> return; >> >> # check if VoiceMail server IP is defined >> if (strempty($sel(cfg_get.voicemail.srv_ip))) { >> xlog("SCRIPT: VoiceMail rotuing enabled but IP not defined\n"); >> return; >> } >> if($avp(oexten)==$null) >> return; >> >> $ru = "sip:" + $avp(oexten) + "@" + $sel(cfg_get.voicemail.srv_ip) >> + ":" + $sel(cfg_get.voicemail.srv_port); >> route(RELAY); >> exit; >> #!endif >> >> return; >> } >> >> # manage outgoing branches >> branch_route[MANAGE_BRANCH] { >> xdbg("new branch [$T_branch_idx] to $ru\n"); >> route(NATMANAGE); >> } >> >> # manage incoming replies >> onreply_route[MANAGE_REPLY] { >> xdbg("incoming reply\n"); >> if(status=~"[12][0-9][0-9]") >> route(NATMANAGE); >> } >> >> # manage failure routing cases >> failure_route[MANAGE_FAILURE] { >> route(NATMANAGE); >> >> if (t_is_canceled()) { >> exit; >> } >> >> #!ifdef WITH_BLOCK3XX >> # block call redirect based on 3xx replies. >> if (t_check_status("3[0-9][0-9]")) { >> t_reply("404","Not found"); >> exit; >> } >> #!endif >> >> #!ifdef WITH_VOICEMAIL >> # serial forking >> # - route to voicemail on busy or no answer (timeout) >> if (t_check_status("486|408")) { >> route(TOVOICEMAIL); >> exit; >> } >> #!endif >> } >> >> #!ifdef WITH_WEBSOCKETS >> onreply_route { >> if ((($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) >> && !(proto == WS || proto == WSS)) || $Rp == MY_MSRP_PORT) { >> xlog("L_WARN", "SIP response received on $Rp\n"); >> drop; >> exit; >> } >> >> if (nat_uac_test(64)) { >> # Do NAT traversal stuff for replies to a WebSocket connection >> # - even if it is not behind a NAT! >> # This won't be needed in the future if Kamailio and the >> # WebSocket client support Outbound and Path. >> add_contact_alias(); >> } >> } >> >> event_route[xhttp:request] { >> set_reply_close(); >> set_reply_no_connect(); >> if ($Rp != MY_WS_PORT >> #!ifdef WITH_TLS >> && $Rp != MY_WSS_PORT >> #!endif >> ) { >> xlog("L_WARN", "HTTP request received on $Rp\n"); >> xhttp_reply("403", "Forbidden", "", ""); >> exit; >> } >> >> xlog("L_DBG", "HTTP Request Received\n"); >> >> if ($hdr(Upgrade)=~"websocket" >> && $hdr(Connection)=~"Upgrade" >> && $rm=~"GET") { >> >> # Validate Host - make sure the client is using the correct >> # alias for WebSockets >> if ($hdr(Host) == $null || !is_myself("sip:" + $hdr(Host))) { >> xlog("L_WARN", "Bad host $hdr(Host)\n"); >> xhttp_reply("403", "Forbidden", "", ""); >> exit; >> } >> >> # Optional... validate Origin - make sure the client is from an >> # authorised website. For example, >> # >> # if ($hdr(Origin) != "http://communicator.MY_DOMAIN" >> # && $hdr(Origin) != "https://communicator.MY_DOMAIN") { >> # xlog("L_WARN", "Unauthorised client $hdr(Origin)\n"); >> # xhttp_reply("403", "Forbidden", "", ""); >> # exit; >> # } >> >> # Optional... perform HTTP authentication >> >> # ws_handle_handshake() exits (no further configuration file >> # processing of the request) when complete. >> if (ws_handle_handshake()) >> { >> # Optional... cache some information about the >> # successful connection >> exit; >> } >> } >> >> xhttp_reply("404", "Not Found", "", ""); >> } >> >> event_route[websocket:closed] { >> xlog("L_INFO", "WebSocket connection from $si:$sp has closed\n"); >> } >> #!endif >> >> #!ifdef WITH_MSRP >> event_route[msrp:frame-in] { >> msrp_reply_flags("1"); >> >> if ((($Rp == MY_WS_PORT || $Rp == MY_WSS_PORT) >> && !(proto == WS || proto == WSS)) && $Rp != MY_MSRP_PORT) { >> xlog("L_WARN", "MSRP request received on $Rp\n"); >> msrp_reply("403", "Action-not-allowed"); >> exit; >> } >> >> if (msrp_is_reply()) { >> msrp_relay(); >> } else if($msrp(method)=="AUTH") { >> if($msrp(nexthops)>0) { >> msrp_relay(); >> exit; >> } >> >> if (!www_authenticate("MY_DOMAIN", "subscriber", >> "$msrp(method)")) { >> if (auth_get_www_authenticate("MY_DOMAIN", "1", >> "$var(wauth)")) { >> msrp_reply("401", "Unauthorized", >> "$var(wauth)"); >> } else { >> msrp_reply("500", "Server Error"); >> } >> exit; >> } >> >> if ($hdr(Expires) != $null) { >> $var(expires) = (int) $hdr(Expires); >> if ($var(expires) < MSRP_MIN_EXPIRES) { >> msrp_reply("423", "Interval Out-of-Bounds", >> "Min-Expires: MSRP_MIN_EXPIRES\r\n"); >> exit; >> } else if ($var(expires) > MSRP_MAX_EXPIRES) { >> msrp_reply("423", "Interval Out-of-Bounds", >> "Max-Expires: MSRP_MAX_EXPIRES\r\n"); >> exit; >> } >> } else { >> $var(expires) = MSRP_MAX_EXPIRES; >> } >> >> $var(cnt) = $var(cnt) + 1; >> pv_printf("$var(sessid)", "s.$(pp).$(var(cnt)).$(RANDOM)"); >> $sht(msrp=>$var(sessid)::srcaddr) = $msrp(srcaddr); >> $sht(msrp=>$var(sessid)::srcsock) = $msrp(srcsock); >> $shtex(msrp=>$var(sessid)) = $var(expires) + 5; >> # - Use-Path: the MSRP address for server + session id >> $var(hdrs) = "Use-Path: msrps://MY_IP_ADDR:MY_MSRP_PORT/" >> + $var(sessid) + ";tcp\r\n" >> + "Expires: " + $var(expires) + "\r\n"; >> msrp_reply("200", "OK", "$var(hdrs)"); >> } else if ($msrp(method)=="SEND" || $msrp(method)=="REPORT") { >> if ($msrp(nexthops)>1) { >> if ($msrp(method)!="REPORT") { >> msrp_reply("200", "OK"); >> } >> msrp_relay(); >> exit; >> } >> $var(sessid) = $msrp(sessid); >> if ($sht(msrp=>$var(sessid)::srcaddr) == $null) { >> # one more hop, but we don't have address in htable >> msrp_reply("481", "Session-does-not-exist"); >> exit; >> } else if ($msrp(method)!="REPORT") { >> msrp_reply("200", "OK"); >> } >> msrp_relay_flags("1"); >> msrp_set_dst("$sht(msrp=>$var(sessid)::srcaddr)", >> "$sht(msrp=>$var(sessid)::srcsock)"); >> msrp_relay(); >> } else { >> msrp_reply("501", "Request-method-not-understood"); >> } >> } >> #!endif >> >> >> _______________________________________________ >> SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list >> sr-users@lists.sip-router.org >> http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users > > -- > Daniel-Constantin Mierla - http://www.asipto.com > http://twitter.com/#!/miconda - http://www.linkedin.com/in/miconda > _______________________________________________ SIP Express Router (SER) and Kamailio (OpenSER) - sr-users mailing list sr-users@lists.sip-router.org http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users