Compare commits

...

281 Commits

Author SHA1 Message Date
  Alan R Evans 03be247cd2 add handle_ruri_alias fot NOTIFY to fix sync-check 3 years ago
  Alan R Evans c93d576dc3 add kazoo.so 3 years ago
  root 42b10adc02 fix fast pickup and update instructions 3 years ago
  root e98885d3e8 proxy-blf configuration 3 years ago
  root 7ca17e2ea3 proxy-reg configuration 3 years ago
  Alan R Evans a1844b8ae9 proxy-call configuration 3 years ago
  root 4bfbfe593b proxy-proxy configuration 3 years ago
  Alan R Evans 593dc13588 add config file location 5 years ago
  Alan R Evans 3fccd80968 add support for postgres backend 5 years ago
  Luis Azedo 3020352097 add dispatcher support for kamailio 5.4 5 years ago
  lazedo 0bbd30790f check for media servers reconnection 5 years ago
  lazedo 30c054bf82 configurable 480 reply from media with session in progress 6 years ago
  Daniel Finke 55b0bf5715 [4.3] Don't overwrite tcp_children for local listener 6 years ago
  lazedo 001f55c6b2 override 480 if call is progress 6 years ago
  lazedo 03a23947d5 fix the check for content-type 6 years ago
  lazedo a2933334ca use descending order to remove preferred route from list 6 years ago
  lazedo f9bfa52a94 use redirect for challenged invites by media servers 6 years ago
  lazedo e9358c6299 support custom dispatcher roles 6 years ago
  Karl Anderson 97d58cd846 cleanup unused redirect logic 6 years ago
  lazedo 6255c37cfe
simplify internal redirects - 4.3 (#127) 6 years ago
  lazedo 796da4e7df sync with kazoo im services 6 years ago
  lazedo ee0b627d8a allow disable of detection mechanism 6 years ago
  lazedo 87e8b4148e bring kazoo-kamailio from master 6 years ago
  lazedo 3fbf6d5ef2 xavp_rm not available until 5.3 6 years ago
  lazedo ac884d8194 remove double auth 6 years ago
  lazedo c8937f7505 process auth for REFER 6 years ago
  lazedo 9ce20f996e add "pass" log to early return 6 years ago
  lazedo 71944ae7b6 early return for in-dialog transactions 6 years ago
  lazedo 5dc142ebc4 order of x-headers 6 years ago
  lazedo 63fec8098a only add x-headers for INVITE|MESSAGE|REFER 6 years ago
  lazedo ae0dbf1ddd add cflags from contact to branch flags 6 years ago
  lazedo 5c91549b6c add NOTIFY for branch_route 6 years ago
  lazedo ae5d0f28d9 allow Token-Proxy override 6 years ago
  lazedo d9a07156ec allow pusher to log contact 6 years ago
  lazedo fe2d40a81d pusher external fault fix 6 years ago
  lazedo 5f07e8c072 pusher nat handling 6 years ago
  lazedo c53a0bb908
allow text/html in message content-type 6 years ago
  lazedo 9c0d879ddd
fix from/to for inbound 6 years ago
  lazedo 3fab3b6fa8
set route-type to onnet 6 years ago
  lazedo cb65cf45e6
Update message-role.cfg 6 years ago
  lazedo 0a4bf7c9ba manage branch in redirect 6 years ago
  Sean Wysor 2c05c2aed3 Update .shipyard.yml 6 years ago
  Sean Wysor 30c9618355 Test dep changes (#117) 6 years ago
  lazedo aa1fec9dda
remove include in local 6 years ago
  Sean Wysor 5d7e1e109a
Update .shipyard.yml 6 years ago
  bitbashing a7e4f02422
Merge pull request #113 from 2600hz/circle-ci-builds-4.3 6 years ago
  Derek Miles 9318161f9e Increasing default EXTERNAL_TO_INTERNAL_NO_RESPONSE_TIMER and INTERNAL_TO_EXTERNAL_NO_RESPONSE_TIMER values to known working values pre any UDP buffer tuning 6 years ago
  swysor 69a7ac3472 removed swap file 6 years ago
  swysor 19d888aa0f updated 4.3 6 years ago
  swysor 0a4ee51a25 setup configs to build packages 6 years ago
  Karl Anderson d0e398bec3 registrar sync binding is using the old format and has a syntax error when enabled 6 years ago
  lazedo 1d0a40676b fix prefered_route check 6 years ago
  lazedo 9a8d560bea simplify next and prefered route 6 years ago
  lazedo 1fa6d4eec0 cleanup 6 years ago
  lazedo c358b42ceb update parking regexp 6 years ago
  lazedo a39b6c4bae add configurable NO_RESPONSE_TIMER 6 years ago
  lazedo d846a15632 support kamailio 5.1/5.2 6 years ago
  lazedo 47046f3435 change some defaults for better user experience 6 years ago
  bitbashing b2c18c86d9
Merge pull request #101 from 2600hz/trusted-4.3 6 years ago
  lazedo fee7835182 remove double escape from json 6 years ago
  lazedo dcb813d7f2 add macro for presence_use_full_entity 7 years ago
  lazedo 55c794c008 keep us in the loop for invite in-dialog requests 7 years ago
  lazedo 784cb70561 this is a targeted reply 7 years ago
  lazedo aabec7673e use sms exchange for delivery report 7 years ago
  lazedo 3e5b6dc898 add federation and simplify reply handling 7 years ago
  lazedo fe1e4d0ede fix spelling 7 years ago
  lazedo 5671d7893f use internal routing for messages 7 years ago
  Luis Azedo e2f19675c0 backport of #100 7 years ago
  bitbashing e03b1813d9
Merge pull request #92 from 2600hz/improvements-4.3 7 years ago
  lazedo 3fba5c0dc7 update presence handling 7 years ago
  lazedo 678cd54505 handle state for presence event 7 years ago
  lazedo 91d3d6f86b change column order to use indexes 7 years ago
  lazedo 637ce55531 use column 7 7 years ago
  lazedo 7e8f70042c check if result of iproute is ip address 7 years ago
  lazedo 772067a794 formatting 7 years ago
  lazedo 8ae0296fff websockets defaults 7 years ago
  lazedo 26cbbfec13 add REFER handling 7 years ago
  lazedo c0cc9501a7 change reparse_on_dns_failover default on tm module 7 years ago
  lazedo 63a2d3a6a3 add X-AUTH-Token from CCVs 7 years ago
  lazedo 23eda1c9fa check event_list diff 7 years ago
  lazedo 6b66c1d1f4 fix antiflood rate log 7 years ago
  lazedo 00bc4a86b4 blocker is a role, no needed for define 7 years ago
  lazedo f7d89cd7bd allow trace failed sanity requests 7 years ago
  lazedo 4eb1dc0758 move sanity script 7 years ago
  lazedo 4ef8835ce1 less restrictive auth 7 years ago
  lazedo fcc2d0904a call status req 7 years ago
  lazedo 58148319ae add Hotdesk-Current-ID and format 7 years ago
  lazedo a7a14f5ddc move block as role, rename keepalive script 7 years ago
  lazedo af4382edc3 move keepalive to a new experimental role 7 years ago
  lazedo 9649e7e978 add ruid to w_location_contact view 7 years ago
  lazedo 2eadcd4bef don't delete registrations on startup 7 years ago
  lazedo 0bc353e552 macros for db_kazoo 7 years ago
  lazedo eb2ce85893 change notify timer interval 7 years ago
  lazedo 172a130fb1 add presence_with_targets_log_level 7 years ago
  lazedo 4261e277e3 add registrar perm error condition & macros & defaults 7 years ago
  lazedo f9235cdd1d add stats to keepalive & change some defaults 7 years ago
  lazedo 241ca7c0d9 add statistics module 7 years ago
  lazedo 7b434329dc registrar stats & cache authn_err 7 years ago
  lazedo a8899cd1fc db changes 7 years ago
  lazedo 490a5be8d2 remove include file 7 years ago
  lazedo 9ae2ed21c3 db module macro 7 years ago
  lazedo 235a4bb8b5 add a block component 7 years ago
  lazedo 21ed266153 move kazoo param to kazoo-bindings & allow db module configuration 7 years ago
  lazedo b435966eda macro/runtime for keepalive failed loglevel 7 years ago
  lazedo f33753d5bc macros/runtime for max notify error and loglevel 7 years ago
  lazedo 5d67f349bd schema update 7 years ago
  lazedo 411634b954 allow options to be loaded from kazoo-kamailio folder 7 years ago
  lazedo a3e967e08a RESET_NON_UDP_ENABLED from env 7 years ago
  lazedo 73d945c4fd runtime for failed threshold 7 years ago
  lazedo 83e89bd837 update keepalive 7 years ago
  lazedo cebd0b11d6 update db schema & views 7 years ago
  lazedo 7195128c9c reset only local options 7 years ago
  lazedo 1733cfef26 don't advertise 127.0.0.1 7 years ago
  lazedo 382f8521d0 add a lock for db ops since we have several workers 7 years ago
  lazedo 4dd00f1612 escape account name 7 years ago
  lazedo 1c5258746d cfgutils lock_set_size param 7 years ago
  lazedo 7e4472f124 add REGISTRAR_DB_REMOVE_EXPIRED_DELAY macro 7 years ago
  lazedo f1acc8fcae disable keepalive for clients that send OPTIONS/NOTIFY 7 years ago
  lazedo 15cab44061 allow runtime configuration of keepalive timeout 7 years ago
  lazedo 50d014a43c handle deregistrations in keepalive 7 years ago
  lazedo dca4afcd79 keepalive defaults 7 years ago
  lazedo d849e98d6a fix table name 7 years ago
  lazedo 40c7de246d remove unused code 7 years ago
  lazedo c6f981a5d4 use db_mode 3 by default on registrar 7 years ago
  lazedo 1a82cb2fa9 add KEEPALIVE_ON_EXPIRED_REGISTRATION 7 years ago
  lazedo f121b5134b comment udp checks 7 years ago
  lazedo dc51608ee4 keepalive cleanup 7 years ago
  lazedo 5758f8c6d3 add keepalive 7 years ago
  lazedo 99f9e80771 option & notify early exit 7 years ago
  lazedo 75acf0ee26 add versions to kazoo specific tables 7 years ago
  lazedo f7f7e3fca3 defaults for nat ping timeout and timer interval 7 years ago
  lazedo e9eb219a92 some tweaks 7 years ago
  lazedo dad34428b7 nat with loop 7 years ago
  lazedo 6857b35c4d apply db diff with primary key 7 years ago
  lazedo 4cad20d6d4 presence nat 7 years ago
  lazedo 1e47348c43 remove watchers on registration expiration 7 years ago
  lazedo ab753be089 log transaction id in registrar 7 years ago
  lazedo 420a4281e6 avoid duplicated pings 7 years ago
  lazedo c6ad6dbb8c macros for tcp parameters 7 years ago
  lazedo ff7874141d add db_url to htable for registrar warm cache 7 years ago
  lazedo 2997c5191c include all sql files from shared dir 7 years ago
  lazedo 9d9fd35023 log contact expiration 7 years ago
  lazedo ae3fc615a4 registrar warm cache 7 years ago
  lazedo 5b47d34d4d websocket with proxy only connections 7 years ago
  lazedo 45e8d5638c reply logs 7 years ago
  lazedo 1a2a6bdeb3 log call-id for park redirect 7 years ago
  lazedo 429a42a6b3 allow exchage configuration for registrar 7 years ago
  lazedo 80f1f1b42d granular reply configuration for presence query 7 years ago
  lazedo 5a2fffaf2b remove dlg from auth 7 years ago
  lazedo a7c27fea0c presence notify logging 7 years ago
  lazedo 34bcc3520c fix relay in dispatcher 7 years ago
  lazedo 1e726da37e setup route & auth 7 years ago
  lazedo 1bddebc043 move auth headers to own file 7 years ago
  lazedo c33bd1cfda nat keepalive options 7 years ago
  lazedo 4c4c07fb6e add empty line for better viewing 7 years ago
  lazedo 23cf96c6aa define L_DEBUG 7 years ago
  lazedo bfec04f8c3 antiflood def moved 7 years ago
  lazedo bb836ad243 tls mod_level and low_mem 7 years ago
  lazedo b4d224e1fd websocker origin_ip 7 years ago
  lazedo 2ecbeda741 allow not logging OPTIONS 7 years ago
  lazedo ec6c9d138b route ANTIFLOOD_LIMIT 7 years ago
  lazedo 1babdafb0d move debugger so other cfg files can declare mod_level 7 years ago
  lazedo a41c15b603 antiflood macros & auth by port 7 years ago
  lazedo 4fa36f07fb move sanity to own cfg file 7 years ago
  lazedo 15a68cbbe2 remove quotes from ips 7 years ago
  lazedo 65e135d00b update ws connection count for proxied connections 7 years ago
  lazedo fd45db66ca change default number of buffer slots 7 years ago
  lazedo 0526ce2f91 registrar nat msg log level 7 years ago
  lazedo 5daf2d9b54 websocket logs and macros 7 years ago
  lazedo 628f661859 more nat related changes 7 years ago
  lazedo d86cca4365 add REGISTRAR_NAT_PING_NAT_ONLY macro and default to 0 7 years ago
  lazedo 2a01496f96 add NAT_SDP route 7 years ago
  lazedo ee94e095c0 fix nat sdp handling 7 years ago
  lazedo 21db836948 16kb default for buffer size 7 years ago
  lazedo 104ac3303e buffer size & slots 7 years ago
  lazedo 5c0df888b2 move AOR back to default 7 years ago
  lazedo 32450fa1b0 allow check for media internal sip addresses 7 years ago
  lazedo 4dab51ee41 optional REGISTRAR_CHECK_AMQP_AVAILABILITY 7 years ago
  lazedo 2a32c9c663 defaults for ip address 7 years ago
  lazedo 4d784e26be add missing defaults 7 years ago
  lazedo 9182cc50cd handle directory flush with cache-only 7 years ago
  lazedo 8ca0cd31f0 missing deltas in mwi / presence 7 years ago
  lazedo 42dce54dd4 log levels for dispatcher 7 years ago
  lazedo ab5c9c69a2 fix log message for min-expires in registrar 7 years ago
  lazedo d13e410d67 change log level in nodes 7 years ago
  lazedo 40a14584f8 allow override of missing expires on REGISTER 7 years ago
  lazedo 0f35dc46b0 change var for logging, fix msg & missing test 7 years ago
  lazedo 20b51d1ff6 less noise in logs unless we want 7 years ago
  lazedo e4b9325583 restrict ack's that need tracing 7 years ago
  lazedo 272409e196 Revert "add option to run (prepare/start)" 7 years ago
  lazedo 742ff3ea17 check database on creation 7 years ago
  lazedo d42460ffcb fix sip trace ack 7 years ago
  lazedo f0de0c7596 add option to run (prepare/start) 7 years ago
  lazedo 03a5c57a6b handle sip trace from one place 7 years ago
  lazedo 013da14864 remove default for amqp 7 years ago
  lazedo 6ba389fcea start moving role specific definitions 7 years ago
  lazedo ee35f2f129 use more meaningful method 7 years ago
  lazedo f672b8926b substdefs for listeners need the IP_ADDRESS resolved 7 years ago
  lazedo 5c3a592c4d origin restriction by default 7 years ago
  lazedo b4b9b670eb more defaults and squashed fast pickup into presence 7 years ago
  lazedo cff16eb6c6 better defaults for ip and hostname 7 years ago
  lazedo 53900274eb remove trailing white spaces 7 years ago
  lazedo c25515bed5 change log level to show by zone 7 years ago
  lazedo fd90d9df19 more bindings and logs 7 years ago
  lazedo 48ba777d00 move search & reset to api 7 years ago
  lazedo a21c799de2 update amqp logging 7 years ago
  lazedo 4c9afb9c94 name the bindings 7 years ago
  lazedo 07de9ebac4 remove FLT_AOR check 7 years ago
  lazedo d58d9481af duplicate definition of FLB_NATB 7 years ago
  lazedo 4014155c1f handle in dialog requests for nat 7 years ago
  lazedo dafab4644d set KZ_NAT_FIX_SDP_REPLY default to 0 7 years ago
  lazedo 88b8e0199e log local generated requests 7 years ago
  lazedo cb5cb9b7ff rework nat 7 years ago
  lazedo f5bb8319ba redefine flags 7 years ago
  lazedo 7d7516b666 indentation 7 years ago
  lazedo 419bed5d83 rework nat with set_contact_alias/handle_ruri_alias 7 years ago
  lazedo 6a0087277b flag AOR usage and move route to registrar-role 7 years ago
  lazedo 1996b28b8b initialize debug settings with macro 7 years ago
  lazedo 88aef4191c flag T38 requests 7 years ago
  lazedo 4bae98240e add some flags 7 years ago
  lazedo ea7712425c memlog must be lower than debug 7 years ago
  lazedo b71fcb0ba9 decouple nat port/contact tests 7 years ago
  lazedo 8ab98e235b add delta logging to registrar 7 years ago
  lazedo df8b23a32c fix log line 7 years ago
  lazedo 5a625d0217 allow tracking all presence packages 7 years ago
  lazedo c4c62c19ed simpler log line 7 years ago
  lazedo 5d56b6eb72 do not try to resize if it doesn't fit 7 years ago
  lazedo 4acd6a26bb presence detail should query based on active watchers 7 years ago
  lazedo 419a670e54 rework presence cleanup 7 years ago
  lazedo 5e4615e173 fix log message for reset zone 7 years ago
  lazedo 02125e77a6 add index to dispatcher 7 years ago
  lazedo 29b6983db5 handle the case where listener is not available for a zone 7 years ago
  lazedo 0d5b9b89b7 less noise in logs 7 years ago
  lazedo 928755686d change default due to loopback channels 7 years ago
  lazedo 6f6e403401 update count and cleanup queries 7 years ago
  lazedo 761a085cb2 allow opt-out str 5 processing andalso change at runtime 7 years ago
  lazedo 1275e9cfd7 remove sanity htable counter 7 years ago
  lazedo c4aa9e0516 remove uac params 7 years ago
  lazedo 646e2e86ab remove 302 condition 7 years ago
  lazedo 93c798b4d2 revert dns enablement 7 years ago
  lazedo 1983d7a458 change log level for publisher cleanup 7 years ago
  lazedo 6ea09368d4 presence reset updates 7 years ago
  lazedo f08248d30e join the event too 7 years ago
  lazedo e4c0a9435a track media instance-id 7 years ago
  lazedo 58a4390cd5 !trydefs for dispatcher groups and runtime selection 7 years ago
  lazedo b8aad0bf3a add extra sets for dispatcher classify 7 years ago
  lazedo 022c0dd8b0 expires in location table is timestamp 7 years ago
  lazedo 4cea7663d6 count distinct callid for presentity count 7 years ago
  lazedo 94c4f74b2d move cseq to trydef 7 years ago
  lazedo e147eae4be increase cseq_offset 7 years ago
  lazedo 968773a653 add runtime variable to force kazoo query on register 7 years ago
  lazedo ce04932247 set log level to notice in core 7 years ago
  lazedo dd9b7133e9 use kamcmd to stop kamailio 7 years ago
  lazedo b8b915eaef mhomed as a #!trydef 7 years ago
  lazedo 05e93bb8cd indentation & remove rr in handle_in_dialog, settings for rr 7 years ago
  lazedo 29831aee90 use proper variable for resetting associations 7 years ago
  lazedo 08c9548a32 check ramdisk size and ensure minimum free space 7 years ago
  lazedo cda63e4ab9 remove stale indication on challenge 7 years ago
  lazedo fa80fef784 use evrexec for deferred init 7 years ago
  lazedo 8349bd727e move rtimer load to default 7 years ago
  lazedo aabcf4a7fb simplify init deferred 7 years ago
  lazedo b249ca299f trydefs 7 years ago
  lazedo 7d1af72c07 use $sel for selectors 7 years ago
  lazedo d5a1f82fd9 remove commented code 7 years ago
  lazedo 5d3f9dfc0d deferred reload for dispatcher 7 years ago
  lazedo 378af34ecd allow extensibility on custom init 7 years ago
  lazedo cdc8bd9b7c remove commented lines 7 years ago
  lazedo e708a00460 HELP-40268 impose a maximum calls per presentity 7 years ago
  lazedo 70e7aef558 allow db downgrade 7 years ago
  lazedo 17092c0bf4 when querying kazoo channels for parking, use *3 so that it handles *5 7 years ago
  lazedo 6bfc74d65c mount & umount review 7 years ago
  lazedo 12eb4bf819 distraction 7 years ago
  lazedo 6c3f23da02 fix comparison & return from ram_disk_enabled 7 years ago
  lazedo 67c96e7009 keep current behaviour 7 years ago
  lazedo be2cdba506 missing files 7 years ago
  lazedo 5437a8e86d fast pickup for *5, looks into *3 7 years ago
  lazedo 7703c1ede3 WIP 7 years ago
  lazedo 14b5b3e702 ignore online/offline probe 7 years ago
  Daniel Finke da7a5a99f5 Add KZQ_HAS_PRESENTITY to db_queries_mysql 7 years ago
  lazedo e113303e9c fix sip trace config initialization 7 years ago
  lazedo e583749e74
add db param to KazooDB 7 years ago
249 changed files with 52383 additions and 3211 deletions
Split View
  1. +84
    -0
      .circleci/config.yml
  2. +86
    -0
      .shipyard.yml
  3. +103
    -0
      POSTGRES.md
  4. +3
    -4
      kamailio-proxy-blf/accounting-role.cfg
  5. +6
    -0
      kamailio-proxy-blf/acl-role.cfg
  6. +140
    -0
      kamailio-proxy-blf/antiflood-role.cfg
  7. +130
    -0
      kamailio-proxy-blf/auth.cfg
  8. +23
    -0
      kamailio-proxy-blf/authorization-role.cfg
  9. +39
    -0
      kamailio-proxy-blf/blocker-role.cfg
  10. +0
    -0
      kamailio-proxy-blf/certs/.placeholder
  11. +14
    -0
      kamailio-proxy-blf/db_kazoo.cfg
  12. +4
    -0
      kamailio-proxy-blf/db_mysql.cfg
  13. +4
    -0
      kamailio-proxy-blf/db_postgres.cfg
  14. +33
    -0
      kamailio-proxy-blf/db_queries_kazoo.cfg
  15. +1
    -0
      kamailio-proxy-blf/db_queries_mysql.cfg
  16. +9
    -0
      kamailio-proxy-blf/db_queries_postgres.cfg
  17. +46
    -0
      kamailio-proxy-blf/db_scripts/check-kazoodb-sql.sh
  18. +9
    -0
      kamailio-proxy-blf/db_scripts/create-kazoodb-sql.sh
  19. +34
    -0
      kamailio-proxy-blf/db_scripts/db_extra_check.sql
  20. +14
    -0
      kamailio-proxy-blf/db_scripts/db_init_watcher_triggers.sql
  21. +152
    -0
      kamailio-proxy-blf/db_scripts/db_kazoo-specific
  22. +5811
    -0
      kamailio-proxy-blf/db_scripts/kamailio_initdb_postgres.sql
  23. +56
    -0
      kamailio-proxy-blf/db_scripts/kazoodb-sql.sh
  24. +0
    -0
      kamailio-proxy-blf/db_scripts/mysql-specific
  25. +0
    -0
      kamailio-proxy-blf/db_scripts/postgres-specific
  26. +20
    -0
      kamailio-proxy-blf/db_scripts/vw_presentities.sql
  27. +6
    -0
      kamailio-proxy-blf/db_scripts/vw_w_keepalive_contact.sql
  28. +6
    -0
      kamailio-proxy-blf/db_scripts/vw_w_location_contact.sql
  29. +6
    -0
      kamailio-proxy-blf/db_scripts/vw_w_watchers_contact.sql
  30. +6
    -0
      kamailio-proxy-blf/db_scripts/vw_wdispatcher.sql
  31. +962
    -0
      kamailio-proxy-blf/default.cfg
  32. +88
    -0
      kamailio-proxy-blf/defs-amqp.cfg
  33. +95
    -0
      kamailio-proxy-blf/defs.cfg
  34. +306
    -0
      kamailio-proxy-blf/dispatcher-role-5.1.cfg
  35. +309
    -0
      kamailio-proxy-blf/dispatcher-role-5.2.cfg
  36. +309
    -0
      kamailio-proxy-blf/dispatcher-role-5.4.cfg
  37. +309
    -0
      kamailio-proxy-blf/dispatcher-role-5.5.cfg
  38. +17
    -3
      kamailio-proxy-blf/kamailio.cfg
  39. +156
    -0
      kamailio-proxy-blf/kazoo-bindings.cfg
  40. +343
    -0
      kamailio-proxy-blf/keepalive-role.cfg
  41. +156
    -0
      kamailio-proxy-blf/local.cfg
  42. +102
    -0
      kamailio-proxy-blf/message-role.cfg
  43. +116
    -0
      kamailio-proxy-blf/nat-traversal-role.cfg
  44. +86
    -38
      kamailio-proxy-blf/nodes-role.cfg
  45. +65
    -27
      kamailio-proxy-blf/presence-fast-pickup.cfg
  46. +213
    -0
      kamailio-proxy-blf/presence-notify.cfg
  47. +24
    -23
      kamailio-proxy-blf/presence-query.cfg
  48. +39
    -20
      kamailio-proxy-blf/presence-reset.cfg
  49. +585
    -0
      kamailio-proxy-blf/presence-role.cfg
  50. +53
    -16
      kamailio-proxy-blf/pusher-role.cfg
  51. +0
    -0
      kamailio-proxy-blf/rate-limiter-role.cfg
  52. +588
    -0
      kamailio-proxy-blf/registrar-role.cfg
  53. +1
    -1
      kamailio-proxy-blf/registrar-sync-role.cfg
  54. +0
    -0
      kamailio-proxy-blf/responder-role.cfg
  55. +67
    -0
      kamailio-proxy-blf/sanity.cfg
  56. +97
    -0
      kamailio-proxy-blf/sip_trace-role.cfg
  57. +5
    -1
      kamailio-proxy-blf/tls-role.cfg
  58. +0
    -0
      kamailio-proxy-blf/tls.cfg
  59. +0
    -0
      kamailio-proxy-blf/traffic-filter-role.cfg
  60. +147
    -0
      kamailio-proxy-blf/websockets-role.cfg
  61. +21
    -0
      kamailio-proxy-call/accounting-role.cfg
  62. +273
    -0
      kamailio-proxy-call/acl-role.cfg
  63. +140
    -0
      kamailio-proxy-call/antiflood-role.cfg
  64. +130
    -0
      kamailio-proxy-call/auth.cfg
  65. +23
    -0
      kamailio-proxy-call/authorization-role.cfg
  66. +39
    -0
      kamailio-proxy-call/blocker-role.cfg
  67. +1
    -0
      kamailio-proxy-call/certs/.placeholder
  68. +14
    -0
      kamailio-proxy-call/db_kazoo.cfg
  69. +4
    -0
      kamailio-proxy-call/db_mysql.cfg
  70. +4
    -0
      kamailio-proxy-call/db_postgres.cfg
  71. +33
    -0
      kamailio-proxy-call/db_queries_kazoo.cfg
  72. +2
    -2
      kamailio-proxy-call/db_queries_mysql.cfg
  73. +23
    -0
      kamailio-proxy-call/db_queries_postgres.cfg
  74. +46
    -0
      kamailio-proxy-call/db_scripts/check-kazoodb-sql.sh
  75. +9
    -0
      kamailio-proxy-call/db_scripts/create-kazoodb-sql.sh
  76. +34
    -0
      kamailio-proxy-call/db_scripts/db_extra_check.sql
  77. +14
    -0
      kamailio-proxy-call/db_scripts/db_init_watcher_triggers.sql
  78. +152
    -0
      kamailio-proxy-call/db_scripts/db_kazoo-specific
  79. +5811
    -0
      kamailio-proxy-call/db_scripts/kamailio_initdb_postgres.sql
  80. +56
    -0
      kamailio-proxy-call/db_scripts/kazoodb-sql.sh
  81. +44
    -0
      kamailio-proxy-call/db_scripts/mysql-specific
  82. +44
    -0
      kamailio-proxy-call/db_scripts/postgres-specific
  83. +20
    -0
      kamailio-proxy-call/db_scripts/vw_presentities.sql
  84. +6
    -0
      kamailio-proxy-call/db_scripts/vw_w_keepalive_contact.sql
  85. +6
    -0
      kamailio-proxy-call/db_scripts/vw_w_location_contact.sql
  86. +6
    -0
      kamailio-proxy-call/db_scripts/vw_w_watchers_contact.sql
  87. +6
    -0
      kamailio-proxy-call/db_scripts/vw_wdispatcher.sql
  88. +970
    -0
      kamailio-proxy-call/default.cfg
  89. +88
    -0
      kamailio-proxy-call/defs-amqp.cfg
  90. +95
    -0
      kamailio-proxy-call/defs.cfg
  91. +306
    -0
      kamailio-proxy-call/dispatcher-role-5.1.cfg
  92. +309
    -0
      kamailio-proxy-call/dispatcher-role-5.2.cfg
  93. +309
    -0
      kamailio-proxy-call/dispatcher-role-5.4.cfg
  94. +309
    -0
      kamailio-proxy-call/dispatcher-role-5.5.cfg
  95. +17
    -0
      kamailio-proxy-call/dmq-role.cfg
  96. +52
    -0
      kamailio-proxy-call/kamailio.cfg
  97. +156
    -0
      kamailio-proxy-call/kazoo-bindings.cfg
  98. +343
    -0
      kamailio-proxy-call/keepalive-role.cfg
  99. +159
    -0
      kamailio-proxy-call/local.cfg
  100. +102
    -0
      kamailio-proxy-call/message-role.cfg

+ 84
- 0
.circleci/config.yml View File

@ -0,0 +1,84 @@
version: 2
workflows:
version: 2
build_branch:
jobs:
- build_centos7
build_release:
jobs:
- build_centos7:
filters:
tags:
only: /^\d+\.\d+\.\d+$/
branches:
ignore: /.*/
jobs:
build_centos7:
docker:
- image: offical2600hz/metapackager:1.0-centos-7
user: circleci
shell: /bin/bash --login
working_directory: /home/circleci/2600hz/the_app
environment:
CIRCLE_ARTIFACTS: /tmp/circleci-artifacts
CIRCLE_TEST_REPORTS: /tmp/circleci-test-results
BASH_ENV: "/home/circleci/2600hz/.bashrc"
BUILD_ROOT: "/home/circleci/2600hz/packager"
CORE_ROOT: "/home/circleci/2600hz/the_app"
BUILD_SOURCES: "/home/circleci/2600hz/packager/SOURCES"
BUILD_RPMS: "/home/circleci/2600hz/packager/RPMS"
APP_DIR: "/home/circleci/2600hz/the_app"
steps:
- checkout
- run:
name: Setting up Directories
command: |
APP=${CIRCLE_PROJECT_REPONAME#meta-}
echo -e "export APP=${APP}\n" >> $BASH_ENV
- run:
name: Generating version info
command: |
cd $BUILD_ROOT
VERSION=$(./version)
RELEASE=$(./release)
PACKAGE_NAME=$(./package_name)
echo "export PACKAGE_NAME=${PACKAGE_NAME}" >> $BASH_ENV
echo "export VERSION=${VERSION}" >> $BASH_ENV
echo "export RELEASE=${RELEASE}" >> $BASH_ENV
PACKAGE_NAME=$(./package_name)
echo "export PACKAGE_NAME=${PACKAGE_NAME}" >> $BASH_ENV
echo "build version for ${PACKAGE_NAME} version: ${VERSION} release: ${RELEASE}"
- run:
name: Generating CHANGELOG and VERSION files
command: |
cd $BUILD_ROOT
echo " - generate build version and changelog"
./package_docs
- run:
name: Preparing source for packaging
command: |
echo " - preparing source"
cp -R ${APP_DIR}/* ${BUILD_SOURCES}/
cd $BUILD_SOURCES
echo " - removing files that should not be packaged in the source tar"
rm -rf ${BUILD_SOURCES}/.??*
rm -rf ${BUILD_SOURCES}/doc*
rm -rf ${BUILD_SOURCES}/*.md
echo " - creating the source tar"
cd $BUILD_ROOT
ARTIFACTS_NAME=${PACKAGE_NAME}-${VERSION}
mkdir -p ${ARTIFACTS_NAME}
cp -r ${BUILD_SOURCES}/* ${ARTIFACTS_NAME}/.
tar -cf ${ARTIFACTS_NAME}.tar ${ARTIFACTS_NAME}
cp ${ARTIFACTS_NAME}.tar ${BUILD_SOURCES}/.
- run:
name: Building package
command: |
cd $BUILD_ROOT
./build
- store_artifacts:
path: /home/circleci/2600hz/packager/RPMS

+ 86
- 0
.shipyard.yml View File

@ -0,0 +1,86 @@
name: kazoo-configs-kamailio
base_branch: origin/4.3
base_core: null
template: spec.tmpl
package:
centos7:
name: kazoo-configs-kamailio
group: Productivity/Telephony
license: MPL1.1
build_arch: noarch
build_requires:
- rpm-build
summary: Kazoo specific configuration for Kamailio
description: |
The Kazoo platform uses Kamailio to provide SIP services
as well as dispatch requests to FreeSWITCH. This package
is an elaborate Kamailio configuration based on 'roles' that
configure and perform these actions. If you need help you
can contact us via the dev mailing list or on IRC at #2600hz
on FreeNode.
dist: .el7.centos
requires:
sudo: {}
source: '%{_build_tar}'
prep: '%setup -q'
install: |
mkdir -p %{buildroot}/etc/kazoo
cp -r kamailio %{buildroot}/etc/kazoo
cp CHANGELOG VERSION %{buildroot}/etc/kazoo/kamailio
chmod +x %{buildroot}/etc/kazoo/kamailio/db_scripts/*.sh
find %{buildroot}/etc/kazoo/kamailio -type f > filelist.txt
sed -i 's#%{buildroot}##g' filelist.txt
to_replace="local.cfg tls.cfg"
for NOREPLACE in ${to_replace}
do
sed -i "s!/etc/kazoo/kamailio/$NOREPLACE!%config(noreplace) /etc/kazoo/kamailio/$NOREPLACE!g" filelist.txt
done
cat filelist.txt
mkdir -p %{buildroot}/usr/sbin
cp -r system/sbin/* %{buildroot}/usr/sbin
chmod +x %{buildroot}/usr/sbin/*
mkdir -p %{buildroot}/etc/rsyslog.d
rm -rf system/rsyslog.d/1-default-config-override.conf
rm -rf system/rsyslog.d/5-rate-limits.conf
cp -r system/rsyslog.d/*.conf %{buildroot}/etc/rsyslog.d
mkdir -p %{buildroot}/etc/logrotate.d
cp -r system/logrotate.d/*.conf %{buildroot}/etc/logrotate.d
mkdir -p %{buildroot}/etc/security/limits.d
cp -r system/security/limits.d/*.conf %{buildroot}/etc/security/limits.d
mkdir -p %{buildroot}/usr/lib/systemd/system
cp system/systemd/* %{buildroot}/usr/lib/systemd/system
files:
doc:
- CHANGELOG
- VERSION
list: filelist.txt
dir: /etc/kazoo/kamailio
config:
- mode: noreplace
path: /etc/rsyslog.d/*kamailio*
- mode: noreplace
path: /etc/logrotate.d/*kamailio*
- mode: noreplace
path: /etc/security/limits.d/*kamailio*
path:
- /usr/sbin/kazoo-kamailio
- /usr/lib/systemd/system/kazoo-kamailio.service
post: systemctl -q enable kazoo-kamailio.service
preun: '%{?systemd_preun kazoo-kamailio.service}'
postun: '%{?systemd_postun kazoo-kamailio.service}'
url: 'http://www.2600hz.org'
vendor: 2600Hz
metapackage:
-
name: meta-kazoo-kamailio
package: kazoo-configs-kamailio
type: required
branch: '4.3'

+ 103
- 0
POSTGRES.md View File

@ -0,0 +1,103 @@
## Notes on upgrading to Kamailio 5.5 and moving to Postgres backend.
Thus removing the dependency on KazooDB which is closed source.
First completely remove the current installation
```
Removing existing kazoo-kamailo:
yum remove kazoo-kamailio
yum remove kamailio
yum remove kazoo-configs-kamailio
```
Next install the lastest Kamailio (currently 5.5.0)
```
yum -y install yum-utils
yum-config-manager --add-repo https://rpm.kamailio.org/centos/kamailio.repo
yum install kamailio kamailio-kazoo kamailio-outbound kamailio-presence kamailio-tls kamailio-utils kamailio-uuid kamailio-websocket kamailio-xmpp kamailio-postgresql
```
Now install latest postgres (currently 12.7)
```
# Install the repository RPM:
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-6-x86_64/pgdg-redhat-repo-latest.noarch.rpm
sudo yum install -y postgresql12-server
/usr/pgsql-12/bin/postgresql-12-setup initdb
sudo chkconfig postgresql-12 on
sudo service postgresql-12 start
```
Create Kamailio DB
```
su postgres -c '/usr/pgsql-12/bin/createdb kamailio'
```
Add DB user and grant privileges
```
sudo su postgres -c psql
CREATE USER kamailio WITH PASSWORD 'kamailio';
GRANT ALL privileges on database kamailio to kamailio;
```
Modify default postgres authentication to allow kamailio access
```
vi /var/lib/pgsql/12/data/pg_hba.conf
# "local" is for Unix domain socket connections only
local all all password
# IPv4 local connections:
host all all 127.0.0.1/32 password
# IPv6 local connections:
host all all ::1/128 password
```
Restart postgres and check kamailio access to DB
```
systemctl restart postgresql-12
psql -U kamailio -d postgres://kamailio:kamailio@127.0.0.1/kamailio
```
Get the postgres kamailio configs:
```
git clone https://github.com/kageds/kazoo-configs-kamailio /etc/kazoo
cd /etc/kazoo/
git checkout itlevel3-4.3
ln -s kamailio-proxy-proxy|call|reg|blf kamailio
```
Initialize the kamailio database with all the required tables:
```
psql -U kamailio -d postgres://kamailio:kamailio@127.0.0.1/kamailio -f /etc/kazoo/kamailo/db_scripts/kamailio_initdb_postgres.sql
```
Notice that the backend DB in local.cfg is now postgres
```
#!trydef KZ_DB_MODULE postgres
#!substdef "!KAMAILIO_DBMS!postgres!g"
#!substdef "!KAZOO_DB_URL!postgres://kamailio:kamailio@127.0.0.1/kamailio!g"
```
Tell kamailio where the configuration files are
```
vi /etc/sysconfig/kamailio
#
# Kamailio startup options
#
# Amount of shared memory to allocate for the running Kamailio server (in Mb)
#SHM_MEMORY=64
# Amount of per-process (package) memory to allocate for Kamailio (in Mb)
#PKG_MEMORY=4
# Enable the server to leave a core file when it crashes.
# Set this to 'yes' to enable kamailio to leave a core file when it crashes
# or 'no' to disable this feature. This option is case sensitive and only
# accepts 'yes' and 'no' and only in lowercase letters.
# On some systems (e.g. Ubuntu 6.10, Debian 4.0) it is necessary to specify
# a directory for the core files to get a dump. Look into the kamailio
# init file for an example configuration.
DUMP_CORE=no
CFGFILE=/etc/kazoo/kamailio/kamailio.cfg
```
Start kamailio (NOT kazoo-kamailio)
```
systemctl enable kamailio
systemctl start kamailio
```

kamailio/accounting-role.cfg → kamailio-proxy-blf/accounting-role.cfg View File


kamailio/acl-role.cfg → kamailio-proxy-blf/acl-role.cfg View File


+ 140
- 0
kamailio-proxy-blf/antiflood-role.cfg View File

@ -0,0 +1,140 @@
#!trydef ANTIFLOOD_RATE_WINDOW 2
#!trydef ANTIFLOOD_RATE_DENSITY 50
#!trydef ANTIFLOOD_RATE_EXPIRE 4
#!trydef ANTIFLOOD_FAILED_AUTH_WINDOW 300
#!trydef ANTIFLOOD_FAILED_AUTH_DENSITY 4
#!trydef ANTIFLOOD_FAILED_AUTH_USE_PORT 1
#!trydef ANTIFLOOD_FAILED_AUTH_ACTION 2
#!trydef ANTIFLOOD_RATE_LIMIT_ENABLED 1
#!trydef ANTIFLOOD_AUTH_LIMIT_ENABLED 1
#!trydef ANTIFLOOD_RATE_DROP 1
#!trydef ANTIFLOOD_CACHE_PERIOD 300
#!substdef "!ANTIFLOOD_SUBST_CACHE_PERIOD!$def(ANTIFLOOD_CACHE_PERIOD)!g"
######## Flood Prevention Hash Tables ########
modparam("htable", "htable", "antiflood=>size=16;autoexpire=ANTIFLOOD_SUBST_CACHE_PERIOD;initval=0")
######## Flood Prevention Module ########
loadmodule "pike.so"
modparam("pike", "sampling_time_unit", ANTIFLOOD_RATE_WINDOW)
modparam("pike", "reqs_density_per_unit", ANTIFLOOD_RATE_DENSITY)
modparam("pike", "remove_latency", ANTIFLOOD_RATE_EXPIRE)
kazoo.antiflood_failed_auth_use_port = ANTIFLOOD_FAILED_AUTH_USE_PORT descr "should we keep track of ip and port for auth failures"
kazoo.antiflood_failed_auth_action = ANTIFLOOD_FAILED_AUTH_ACTION descr "0 - log, 1 - drop, 2 - reply with 403"
kazoo.antiflood_rate_limit_enabled = ANTIFLOOD_RATE_LIMIT_ENABLED descr "antiflood rate limit enabled"
kazoo.antiflood_auth_limit_enabled = ANTIFLOOD_AUTH_LIMIT_ENABLED descr "antiflood auth limit enabled"
kazoo.antiflood_rate_drop = ANTIFLOOD_RATE_DROP descr "should we drop on rate limit"
route[ANTIFLOOD_LIMIT]
{
if($sel(cfg_get.kazoo.antiflood_rate_limit_enabled) == 1) {
route(ANTIFLOOD_RATE_LIMIT);
}
if($sel(cfg_get.kazoo.antiflood_auth_limit_enabled) == 1) {
route(ANTIFLOOD_AUTH_LIMIT);
}
}
route[ANTIFLOOD_RATE_LIMIT]
{
if (has_totag()
|| isflagset(FLAG_TRUSTED_SOURCE)
|| isflagset(FLAG_INTERNALLY_SOURCED)) {
return;
}
# use pike to control the rates
if (!pike_check_req()) {
if($sel(cfg_get.kazoo.antiflood_rate_drop) == 1) {
xlog("L_WARN", "$ci|end|dropping request from $fu due to rate of requests with source $si:$sp\n");
drop();
} else {
xlog("L_WARN", "$ci|allowed|request from $fu exceeded rate of requests with source $si:$sp\n");
}
}
}
route[ANTIFLOOD_AUTH_LIMIT]
{
if (has_totag()
|| isflagset(FLAG_TRUSTED_SOURCE)
|| isflagset(FLAG_INTERNALLY_SOURCED)) {
return(1);
}
$var(auth_key) = "";
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) {
$var(auth_key) = $_s("$Au::$si::$sp");
} else {
$var(auth_key) = $_s("$Au::$si");
}
if ($Au != $null &&
$sht(antiflood=>$var(auth_key)::count) >= ANTIFLOOD_FAILED_AUTH_DENSITY
) {
$shtex(antiflood=>$var(auth_key)::count) = ANTIFLOOD_FAILED_AUTH_WINDOW;
$sht(antiflood=>$var(auth_key)::last) = $Ts;
if($sel(cfg_get.kazoo.antiflood_failed_auth_action) == 1) {
xlog("L_WARNING", "$ci|end|dropping request authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
drop();
} else if($sel(cfg_get.kazoo.antiflood_failed_auth_action) == 2) {
xlog("L_NOTICE", "$ci|end|authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
append_to_reply("Retry-After: 3600\r\n");
send_reply("403", "Forbidden");
exit;
} else {
xlog("L_NOTICE", "$ci|log|authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
}
}
}
route[ANTIFLOOD_SUCCESSFUL_AUTH]
{
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) {
sht_rm_name_re("antiflood=>$(Au{re.subst,/\\./\\\\./g})::$(si{re.subst,/\\./\\\\./g})::$sp::.*");
} else {
sht_rm_name_re("antiflood=>$(Au{re.subst,/\\./\\\\./g})::$(si{re.subst,/\\./\\\\./g})::.*");
}
}
route[ANTIFLOOD_RESET_AUTH]
{
$var(user) = $(kzE{kz.json,Username}) + "@" + $(kzE{kz.json,Realm});
sht_rm_name_re("antiflood=>$(var(user){re.subst,/\\./\\\\./g})::.*");
}
route[ANITFLOOD_FAILED_AUTH]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
}
$var(auth_key) = "";
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) {
$var(auth_key) = $_s("$Au::$si::$sp");
} else {
$var(auth_key) = $_s("$Au::$si");
}
$var(count) = $shtinc(antiflood=>$var(auth_key)::count);
$sht(antiflood=>$var(auth_key)::last) = $Ts;
xlog("L_INFO", "$ci|log|$var(count) errounous authorization response for $Au $si:$sp\n");
if ($var(count) >= ANTIFLOOD_FAILED_AUTH_DENSITY) {
$var(exp) = $Ts - ANTIFLOOD_FAILED_AUTH_WINDOW;
if($sht(antiflood=>$var(auth_key)::last) > $var(exp)) {
xlog("L_NOTICE", "$ci|end|request at authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
append_to_reply("Retry-After: 3600\r\n");
send_reply("403", "Forbidden");
exit;
}
}
}
event_route[htable:expired:antiflood]
{
xlog("L_NOTICE", "antiflood expired record $shtrecord(key) => $shtrecord(value)\n");
}

+ 130
- 0
kamailio-proxy-blf/auth.cfg View File

@ -0,0 +1,130 @@
route[AUTH]
{
if (!is_method("INVITE|MESSAGE|REFER")) {
return;
}
#!ifdef DISPATCHER_ROLE
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(SETUP_AUTH_HEADERS);
}
#!endif
}
route[AUTH_HEADERS]
{
remove_hf_re("^X-");
if (!is_method("INVITE|MESSAGE|REFER")) {
return;
}
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(c) = $var(c) - 1;
}
}
route[AUTH_HEADERS_JSON]
{
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
$var(headers_json) = "";
$var(sep) = "";
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(headers_json) = $_s($var(headers_json)$var(sep)"$(var(out){param.name,$var(idx)})" : "$(var(out){param.valueat,$var(idx)}{s.unescape.param})");
$var(c) = $var(c) - 1;
$var(sep) = " , ";
}
$var(headers_json) = $_s({ $var(headers_json) });
}
route[SETUP_AUTH_HEADERS]
{
$xavp(hf=>X-AUTH-IP) = $si;
$xavp(hf[0]=>X-AUTH-PORT) = $sp;
#!ifdef REGISTRAR_ROLE
$avp(is_registered) = "false";
$xavp(regcfg=>match_received) = $su;
if (registered("location","$fu", 2, 1) != 1) return;
$avp(is_registered) = "true";
#!ifdef WITH_AUTH_TOKEN
route(AUTH_TOKEN);
#!else
route(AUTH_CCVS);
#!endif
#!endif
}
#!ifdef REGISTRAR_ROLE
route[AUTH_TOKEN]
{
if($(xavp(ulattrs=>token){s.len}) > 0) {
$xavp(hf[0]=>X-AUTH-Token) = $xavp(ulattrs=>token);
} else {
if($(xavp(ulattrs=>Authorizing-ID){s.len}) > 0 && $(xavp(ulattrs=>Account-ID){s.len})) {
$xavp(hf[0]=>X-AUTH-Token) = $_s($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID})@$(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}));
}
}
}
route[AUTH_CCVS]
{
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}{s.len}) > 0 && $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type}{s.len}) > 0)
$xavp(hf[0]=>X-AUTH-Token) = $_s($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID})@$(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}));
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Authorizing-Type) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Authorizing-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Username}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Username) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Username});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Realm}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Realm) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Realm});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-Realm) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-Name) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name}{s.escape.param});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Presence-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Owner-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Hotdesk-Current-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Hotdesk-Current-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Hotdesk-Current-ID});
}
#!endif

+ 23
- 0
kamailio-proxy-blf/authorization-role.cfg View File

@ -0,0 +1,23 @@
## to be enhanced
route[AUTHORIZATION_CHECK]
{
if (!is_method("MESSAGE|NOTIFY|SUBSCRIBE|PUBLISH"))
return;
if(has_totag())
return;
if (isflagset(FLAG_INTERNALLY_SOURCED))
return;
if (isflagset(FLAG_TRUSTED_SOURCE))
return;
$xavp(regcfg=>match_received) = $su;
if(!(registered("location", "$fu", 2, 1) == 1 && $(xavp(ulattrs=>custom_channel_vars){s.len}) > 1)) {
xlog("L_INFO", "$ci|log|not authorized $fu from $si:$sp\n");
send_reply("503", "Not Registered");
exit;
}
}

+ 39
- 0
kamailio-proxy-blf/blocker-role.cfg View File

@ -0,0 +1,39 @@
######## BLOCK BY IP[PORT] ########
#!trydef KZ_BLOCK_ENABLE 1
#!trydef KZ_BLOCK_LOG_LEVEL 1
#!trydef KZ_BLOCK_LOG_BUFFER 0
#!trydef KZ_BLOCK_DRY_RUN 0
#!ifdef KZ_BLOCK_COLD_CACHE
#!substdef "!BLOCK_S_WARM_CACHE!!g"
#!else
#!substdef "!BLOCK_S_WARM_CACHE!dbtable=block_cache;dbmode=1;!g"
#!endif
modparam("htable", "htable", "block=>size=8;BLOCK_S_WARM_CACHE")
modparam("statistics","variable", "block:blocked_requests")
kazoo.block_enable = KZ_BLOCK_ENABLE descr "enable block processing"
kazoo.block_log_level = KZ_BLOCK_LOG_LEVEL descr "block log level"
kazoo.block_log_buffer = KZ_BLOCK_LOG_BUFFER descr "log the received buffer"
kazoo.block_dry_run = KZ_BLOCK_DRY_RUN descr "log but keep processing"
## global param to enable route
received_route_mode=1
event_route[core:msg-received]
{
if($sel(cfg_get.kazoo.block_enable) == 1) {
if($sht(block=>$rcv(srcip)) || $sht(block=>$rcv(srcip)::$rcv(srcport))) {
if($sel(cfg_get.kazoo.block_log_buffer) == 1) {
xlog("$(sel(cfg_get.kazoo.block_log_level){s.int})", "|block|request from [$rcv(srcip):$rcv(srcport)] to [$rcv(rcvip):$rcv(rcvport)] was blocked => [$rcv(buf)]\n");
} else {
xlog("$(sel(cfg_get.kazoo.block_log_level){s.int})", "|block|request from [$rcv(srcip):$rcv(srcport)] to [$rcv(rcvip):$rcv(rcvport)] was blocked\n");
}
if($sel(cfg_get.kazoo.block_dry_run) == 0) {
drop;
}
}
}
}

kamailio/certs/.placeholder → kamailio-proxy-blf/certs/.placeholder View File


+ 14
- 0
kamailio-proxy-blf/db_kazoo.cfg View File

@ -0,0 +1,14 @@
#### db_kazoo module ###
#!trydef KZ_DB_HOOK_TRACE 1
#!trydef KZ_DB_TRACE 0
#!trydef KZ_DB_TRACE_LOG_LEVEL 3
#!trydef KZ_DB_TRACE_FILTER 110
loadmodule "db_kazoo.so"
modparam("db_kazoo", "trace_hook", KZ_DB_HOOK_TRACE)
modparam("db_kazoo", "trace_enable", KZ_DB_TRACE)
modparam("db_kazoo", "trace_log_level", KZ_DB_TRACE_LOG_LEVEL)
modparam("db_kazoo", "trace_filter", KZ_DB_TRACE_FILTER)
include_file "db_queries_kazoo.cfg"

+ 4
- 0
kamailio-proxy-blf/db_mysql.cfg View File

@ -0,0 +1,4 @@
#### db_mysql module ###
loadmodule "db_mysql.so"
include_file "db_queries_mysql.cfg"

+ 4
- 0
kamailio-proxy-blf/db_postgres.cfg View File

@ -0,0 +1,4 @@
#### db_postgres module ###
loadmodule "db_postgres.so"
include_file "db_queries_postgres.cfg"

+ 33
- 0
kamailio-proxy-blf/db_queries_kazoo.cfg View File

@ -0,0 +1,33 @@
####### Database queries ########
#!substdef "!KZQ_CHECK_MEDIA_SERVER_INSERT!insert into dispatcher (setid, destination, flags, attrs, description) select \$var(SetId), \"\$var(MediaUrl)\", \$var(flags), \"\$var(attrs)\", \"added by nodes role\" where not exists(select * from dispatcher where destination = \"\$var(MediaUrl)\")!g"
#!substdef "!KZQ_COUNT_ALL_SUBSCRIBERS!select a.event, count(distinct watcher_uri) count_unique, count(*) count from event_list a left outer join active_watchers b on a.event = b.event group by a.event!g"
#!substdef "!KZQ_COUNT_PRESENTITIES!select event, (select count(*) from presentity b where username = \"\$(var(payload){kz.json,From}{uri.user})\" and domain = \"\$(var(payload){kz.json,From}{uri.domain})\" and b.event = a.event) count from event_list a!g"
#!substdef "!KZQ_COUNT_SUBSCRIBERS!select event, (select count(*) from active_watchers b where presentity_uri = \"\$var(presentity)\" and b.event = a.event) count from event_list a union all select \"self\", count(distinct callid) from presentities where presentity_uri = \"\$var(presentity)\" and callid <> \"\$var(callid)\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_EVENT_PRESENCE_RESET_DELETE!delete from presentity where domain=\"\$(kzE{kz.json,Realm})\" and username = \"\$(kzE{kz.json,Username})\"!g"
#!substdef "!KZQ_HANDLE_NEW_SUBSCRIBE_DELETE1!delete from active_watchers where callid = \"\$ci\"!g"
#!substdef "!KZQ_HANDLE_NEW_SUBSCRIBE_DELETE2!delete from active_watchers where presentity_uri=\"\$var(presentity_uri)\" and event=\"\$hdr(Event)\" and watcher_username=\"\$fU\" and to_user=\"\$tU\" and watcher_domain=\"\$fd\"!g"
#!substdef "!KZQ_PRESENCE_SEARCH_SUMMARY!select * from active_watchers where to_domain = \"\$var(Domain)\"!g"
#!substdef "!KZQ_PRESENCE_SEARCH_DETAIL!select a.*, b.time, b.result, b.sent_msg, b.received_msg from active_watchers a left outer join active_watchers_log b on a.presentity_uri = b.presentity_uri and a.event = b.event and a.callid = b.callid where a.presentity_uri = \"\$var(presentity_uri)\" !g"
#!substdef "!KZQ_HAS_PRESENTITY!select count(*) as count from presentity where username = \"\$subs(to_user)\" and domain = \"\$subs(to_domain)\" and event = \"\$subs(event)\"!g"
#!substdef "!KZQ_REPLACE_WATCHERS_LOG!REPLACE INTO active_watchers_log (presentity_uri, watcher_username, watcher_domain, event, callid, to_user, to_domain, user_agent, time, result, sent_msg, received_msg) VALUES (\"\$subs(uri)\", \"\$subs(watcher_username)\", \"\$subs(watcher_domain)\", \"\$subs(event)\",\"\$subs(callid)\",\"\$subs(to_user)\",\"\$subs(to_domain)\", '\$(subs(user_agent){s.escape.common}{s.replace,\\\',''}{s.replace,\$\$,})', \$TS, \$notify_reply(\$rs), '\$(mb{s.escape.common}{s.replace,\\\',''}{s.replace,\$\$,})', '\$(notify_reply(\$mb){s.escape.common}{s.replace,\\\',''}{s.replace,\$\$,})')!g"
# # #!substdef "!KZQ_RESET_PUBLISHER_UPDATE!update active_watchers set expires = \$TS where id in (select b.id from presentity a inner join active_watchers b on a.username = b.to_user and a.domain = b.to_domain and a.event = b.event where a.sender = \"\$var(MediaUrl)\")!g"
#!substdef "!KZQ_RESET_PUBLISHER_UPDATE!INSERT INTO tmp_probe select distinct a.event, a.presentity_uri, 0 from presentities a inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where sender = \"\$var(MediaUrl)\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_PRESENCE_RESET!delete from presentity where sender = \"\$var(MediaUrl)\"!g"
# # #!substdef "!KZQ_RESET_ACCOUNT_UPDATE!update active_watchers set expires = \$TS where watcher_domain=\"\$(kzE{kz.json,Realm})\"!g"
#!substdef "!KZQ_RESET_ACCOUNT_UPDATE!INSERT INTO tmp_probe select distinct a.event, a.presentity_uri, 0 from presentities a inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where domain=\"\$(kzE{kz.json,Realm})\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_RESET_ACCOUNT_RESET!delete from presentity where domain=\"\$(kzE{kz.json,Realm})\"!g"
#!substdef "!KZQ_RESET_PUBLISHER_ZONE_UPDATE!INSERT INTO tmp_probe select distinct a.event, a.presentity_uri, 0 from presentities a inner join wdispatcher c on a.sender = c.destination inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where zone = \"\$var(Zone)\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_PRESENCE_ZONE_RESET!delete from presentity where id in(select a.id from presentities a join wdispatcher c on a.sender = c.destination where zone = \"\$var(Zone)\")!g"
#!substdef "!KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_EXPIRES!DELETE FROM active_watchers WHERE expires > 0 AND datetime(expires, 'unixepoch') < datetime('now', '-90 seconds')!g"
#!substdef "!KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_PRESENTITY!DELETE FROM ACTIVE_WATCHERS WHERE PRESENTITY_URI=\"\$subs(uri)\" AND EVENT=\"\$subs(event)\" AND FROM_USER = \"\$subs(from_user)\" AND FROM_DOMAIN=\"\$subs(from_domain)\" AND CALLID <> \"\$subs(callid)\"!g"
#!substdef "!KZQ_DELETE_FROM_PRESENTITY_WHERE_EXPIRES!DELETE FROM PRESENTITY WHERE expires > 0 AND datetime(expires, 'unixepoch') < datetime('now')!g"
#!substdef "!KZQ_DELETE_FROM_PRESENTITY_WHERE_DIALOG_TERMINATED!DELETE FROM PRESENTITY WHERE ID IN(select id from presentities where event = 'dialog' and state = 'terminated' and received < datetime('now', '-5 minutes'))!g"

kamailio/db_queries_mysql.cfg → kamailio-proxy-blf/db_queries_mysql.cfg View File


kamailio/db_queries_postgres.cfg → kamailio-proxy-blf/db_queries_postgres.cfg View File


+ 46
- 0
kamailio-proxy-blf/db_scripts/check-kazoodb-sql.sh View File

@ -0,0 +1,46 @@
#!/bin/sh
TEMP_DB_LOCATION=/tmp/db
TEMP_DB=${TEMP_DB_LOCATION}/kazoo.db
rm -rf ${TEMP_DB_LOCATION}
. $(dirname $0)/kazoodb-sql.sh --source-only
file=$(sql_db_prepare)
sql_setup $file ${TEMP_DB_LOCATION}
DB_VERSION=`KazooDB -db ${TEMP_DB} "select sum(table_version) from version;"`
DB_CURRENT_DB=${DB_LOCATION:-/etc/kazoo/kamailio}/kazoo.db
DB_CURRENT_VERSION=`KazooDB -db ${DB_CURRENT_DB} "select sum(table_version) from version;"`
if [[ $DB_CURRENT_VERSION -ne $DB_VERSION ]]; then
echo "db required version is ${DB_VERSION}, existing version is ${DB_CURRENT_VERSION}, applying diff"
KazooDB-diff --schema ${DB_CURRENT_DB} ${TEMP_DB} | KazooDB -db ${DB_CURRENT_DB}
KazooDB-diff --primarykey --table version ${DB_CURRENT_DB} ${TEMP_DB} | KazooDB -db ${DB_CURRENT_DB}
KazooDB-diff --primarykey --table event_list ${DB_CURRENT_DB} ${TEMP_DB} | KazooDB -db ${DB_CURRENT_DB}
fi
for VIEW in `ls ${DB_SCRIPT_DIR}/vw_*.sql`; do
filename=$(basename -- "$VIEW")
filename="${filename%.*}"
viewname=${filename#*_}
v1=$(KazooDB -db ${DB_CURRENT_DB} "select sql from sqlite_master where type='view' and name='$viewname'" 2> /dev/null | tr -d ' ' | md5sum | cut -d ' ' -f1)
v2=$(cat $VIEW | tr -d ' ' | md5sum | cut -d ' ' -f1)
if [[ "$v1" != "$v2" ]]; then
echo "rebuilding view $viewname"
KazooDB -db ${DB_CURRENT_DB} "drop view if exists $viewname;"
KazooDB -db ${DB_CURRENT_DB} < $VIEW
fi
done
if [ -f ${DB_SCRIPT_DIR}/db_extra_check.sql ]; then
. ${DB_SCRIPT_DIR}/db_extra_check.sql --source-only
do_db_extra_check;
fi
for INIT in `ls ${DB_SCRIPT_DIR}/db_init_*.sql`; do
KazooDB -db ${DB_CURRENT_DB} < $INIT
done

+ 9
- 0
kamailio-proxy-blf/db_scripts/create-kazoodb-sql.sh View File

@ -0,0 +1,9 @@
#!/bin/sh -e
. $(dirname $0)/kazoodb-sql.sh --source-only
file=$(sql_db_prepare)
echo "setting up kazoo db from init script $file"
sql_setup $file
exit 0

+ 34
- 0
kamailio-proxy-blf/db_scripts/db_extra_check.sql View File

@ -0,0 +1,34 @@
do_db_extra_check() {
# location
if [[ $RESET_NON_UDP_ENABLED == "true" ]]; then
KazooDB -db ${DB_CURRENT_DB} "delete from location where socket not like 'udp:%';"
fi
##KazooDB -db ${DB_CURRENT_DB} "delete from location where expires > 0 and datetime(expires) < datetime('now', '-30 seconds');"
KazooDB -db ${DB_CURRENT_DB} "delete from location_attrs where not exists(select id from location where ruid = location_attrs.ruid);"
## presence
if [[ $RESET_NON_UDP_ENABLED == "true" ]]; then
KazooDB -db ${DB_CURRENT_DB} "delete from active_watchers where socket_info not like 'udp:%';"
fi
KazooDB -db ${DB_CURRENT_DB} "delete from active_watchers where expires > 0 and datetime(expires, 'unixepoch') < datetime('now', '-10 seconds');"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where expires > 0 AND datetime(expires, 'unixepoch') < datetime('now', '-10 seconds');"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where id in(select id from presentities where state in('terminated','available'));"
KazooDB -db ${DB_CURRENT_DB} "delete from active_watchers_log where id in(select id from active_watchers_log a where not exists(select callid from active_watchers b where b.callid = a.callid and b.watcher_username = a.watcher_username and b.watcher_domain = a.watcher_domain));"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where id in(select id from presentities a where not exists(select * from active_watchers where presentity_uri = a.presentity_uri));"
## notify watchers of pending calls
## 'create temp table as' because it will be dropped as soon as we ended the session
KazooDB -db ${DB_CURRENT_DB} "drop table if exists tmp_probe;"
KazooDB -db ${DB_CURRENT_DB} "create table tmp_probe as select distinct a.event, a.presentity_uri, cast(2 as integer) action from presentities a inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where state in('early', 'confirmed', 'onthephone', 'busy');"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where id in(select id from presentities where state in('early', 'confirmed', 'onthephone', 'busy'));"
## keepalive
if [[ $RESET_NON_UDP_ENABLED == "true" ]]; then
KazooDB -db ${DB_CURRENT_DB} "delete from keepalive where sockinfo NOT LIKE 'udp%';"
fi
KazooDB -db ${DB_CURRENT_DB} "update keepalive set selected = 0, time_sent = datetime('now') where selected < 3;"
}

+ 14
- 0
kamailio-proxy-blf/db_scripts/db_init_watcher_triggers.sql View File

@ -0,0 +1,14 @@
CREATE TRIGGER if not exists active_watchers_watcher_uri_insert
AFTER INSERT ON active_watchers
FOR EACH ROW
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;
CREATE TRIGGER if not exists active_watchers_watcher_uri_update
AFTER UPDATE ON active_watchers
FOR EACH ROW
WHEN OLD.watcher_username <> NEW.watcher_username OR OLD.watcher_domain <> NEW.watcher_domain
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;

+ 152
- 0
kamailio-proxy-blf/db_scripts/db_kazoo-specific View File

@ -0,0 +1,152 @@
#!/bin/sh
sql_db_pre_setup() {
cat << EOF
PRAGMA foreign_keys=OFF;
PRAGMA wal=on;
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=25;
BEGIN TRANSACTION;
EOF
}
sql_setup() {
DB_KAZOO_LOCATION=${2:-${DB_KAZOO_LOCATION:-/etc/kazoo/kamailio/db}}
mkdir -p ${DB_KAZOO_LOCATION}
KazooDB -db ${DB_KAZOO_LOCATION}/kazoo.db < $1 > /dev/null
}
sql_header() {
cat << EOF
EOF
}
sql_extra_tables() {
cat << EOF
CREATE TABLE active_watchers_log (
id INTEGER PRIMARY KEY NOT NULL,
presentity_uri VARCHAR(128) NOT NULL COLLATE NOCASE,
watcher_username VARCHAR(64) NOT NULL COLLATE NOCASE,
watcher_domain VARCHAR(64) NOT NULL COLLATE NOCASE,
to_user VARCHAR(64) NOT NULL COLLATE NOCASE,
to_domain VARCHAR(64) NOT NULL COLLATE NOCASE,
event VARCHAR(64) DEFAULT 'presence' NOT NULL,
callid VARCHAR(255) NOT NULL,
time INTEGER NOT NULL,
result INTEGER NOT NULL,
sent_msg BLOB NOT NULL,
received_msg BLOB NOT NULL,
user_agent VARCHAR(255) DEFAULT '' COLLATE NOCASE,
CONSTRAINT active_watchers_active_watchers_log_idx UNIQUE (presentity_uri, watcher_username, watcher_domain, event)
);
INSERT INTO version (table_name, table_version) values ('active_watchers_log','1');
CREATE TABLE keepalive (
id INTEGER PRIMARY KEY NOT NULL,
contact VARCHAR(2048) NOT NULL COLLATE NOCASE,
received VARCHAR(32) NOT NULL COLLATE NOCASE,
sockinfo VARCHAR(128) NOT NULL COLLATE NOCASE,
time_inserted timestamp DEFAULT CURRENT_TIMESTAMP,
time_sent timestamp DEFAULT CURRENT_TIMESTAMP,
slot INTEGER NOT NULL,
selected INTEGER DEFAULT 0,
failed INTEGER DEFAULT 0,
CONSTRAINT keepalive_idx UNIQUE (contact),
CONSTRAINT keepalive_idx_2 UNIQUE (slot, failed, contact)
);
CREATE INDEX keepalive_idx_3 ON keepalive (slot, selected, time_sent);
CREATE INDEX keepalive_idx_4 ON keepalive (received, selected);
INSERT INTO version (table_name, table_version) values ('keepalive','4');
ALTER TABLE active_watchers ADD COLUMN watcher_uri varchar(64) NOT NULL DEFAULT "sip:no_watcher@no_domain";
CREATE TRIGGER active_watchers_watcher_uri_insert
AFTER INSERT ON active_watchers
FOR EACH ROW
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;
CREATE TRIGGER active_watchers_watcher_uri_update
AFTER UPDATE ON active_watchers
FOR EACH ROW
WHEN OLD.watcher_username <> NEW.watcher_username OR OLD.watcher_domain <> NEW.watcher_domain
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;
CREATE UNIQUE INDEX active_watchers_contact ON active_watchers (contact, id);
CREATE INDEX active_watchers_event_watcher_uri ON active_watchers (event, watcher_uri);
CREATE INDEX location_attrs_ruid ON location_attrs (ruid);
CREATE UNIQUE INDEX location_ruid ON location (ruid);
create table auth_cache as select * from htable;
INSERT INTO version (table_name, table_version) select 'auth_cache', table_version from version where table_name = 'htable';
create table block_cache as select * from htable;
INSERT INTO version (table_name, table_version) select 'block_cache', table_version from version where table_name = 'htable';
create view presentities as select id, cast(printf("sip:%s@%s",username,domain) as varchar(64)) presentity_uri ,
username, domain, event, cast(substr(etag, instr(etag,"@")+1) as varchar(64)) callid,
datetime(received_time, 'unixepoch') as received,
datetime(expires, 'unixepoch') as expire_date,
expires, cast(sender as varchar(30)) sender,
lower(cast( case when event = "dialog"
then substr(body, instr(BODY,"<state>")+7, instr(body,"</state>") - instr(body,"<state>") - 7)
when event = "presence"
then case when instr(body,"<dm:note>") == 0
then replace(substr(body, instr(body,"<note>")+6, instr(body,"</note>") - instr(body,"<note>") - 6), " ", "")
else replace(substr(body, instr(body,"<dm:note>")+9, instr(body,"</dm:note>") - instr(body,"<dm:note>") - 9), " ", "")
end
when event = "message-summary"
then case when instr(body,"Messages-Waiting: yes") = 0
then "Waiting"
else "Not-Waiting"
end
end as varchar(12))) state
from presentity;
create view wdispatcher as select *,
cast(substr(attrs, instr(attrs, "zone=")+5, instr(attrs, ";profile")-instr(attrs, "zone=")-5) as varchar(20)) zone,
cast(substr(attrs, instr(attrs, "idx=")+4, instr(attrs, ";node")-instr(attrs, "idx=")-4) as integer) idx,
cast(substr(attrs, instr(attrs, "node=")+5) as varchar(50)) node
from dispatcher;
create unique index if not exists idx_dispatcher_destination on dispatcher(destination);
CREATE VIEW w_keepalive_contact as
SELECT id, slot, selected, failed, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from keepalive;
CREATE VIEW w_location_contact as
SELECT id, ruid, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from location;
CREATE VIEW w_watchers_contact as
select id, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from active_watchers;
EOF
}
sql_footer() {
cat << EOF
EOF
}

+ 5811
- 0
kamailio-proxy-blf/db_scripts/kamailio_initdb_postgres.sql
File diff suppressed because it is too large
View File


+ 56
- 0
kamailio-proxy-blf/db_scripts/kazoodb-sql.sh View File

@ -0,0 +1,56 @@
#!/bin/sh -e
KAMAILIO_SHARE_DIR=${KAMAILIO_SHARE_DIR:-/usr/share/kamailio}
DB_ENGINE=${DB_ENGINE:-db_kazoo}
RESULTED_SQL=${RESULTED_SQL:-/tmp/kamailio_initdb.sql}
. $(dirname $0)/$DB_ENGINE-specific --source-only
sql_filelist() {
echo `ls -A1 ${KAMAILIO_SHARE_DIR}/${DB_ENGINE}/*.sql | grep -v standard | tr '\n' '\0' | xargs -0 -n 1 basename | sort`
}
sql_all_header() {
cat << EOF
CREATE TABLE version (
table_name VARCHAR(32) NOT NULL,
table_version INTEGER DEFAULT 0 NOT NULL,
PRIMARY KEY(table_name)
);
INSERT INTO version VALUES('version',1);
EOF
}
sql_all_extra_tables() {
cat << EOF
CREATE TABLE event_list ( event varchar(25) PRIMARY KEY NOT NULL);
INSERT INTO event_list VALUES('dialog');
INSERT INTO event_list VALUES('presence');
INSERT INTO event_list VALUES('message-summary');
INSERT INTO version VALUES('event_list',1);
EOF
}
sql_all_footer() {
cat << EOF
COMMIT;
EOF
}
sql_db_prepare() {
sql_db_pre_setup > $RESULTED_SQL
sql_all_header >> $RESULTED_SQL
sql_header >> $RESULTED_SQL
for i in $(sql_filelist); do
cat $KAMAILIO_SHARE_DIR/$DB_ENGINE/$i >> $RESULTED_SQL
done
sql_all_extra_tables >> $RESULTED_SQL
sql_extra_tables >> $RESULTED_SQL
sql_footer >> $RESULTED_SQL
sql_all_footer >> $RESULTED_SQL
echo "$RESULTED_SQL"
}

kamailio/db_scripts/mysql-specific → kamailio-proxy-blf/db_scripts/mysql-specific View File


kamailio/db_scripts/postgres-specific → kamailio-proxy-blf/db_scripts/postgres-specific View File


+ 20
- 0
kamailio-proxy-blf/db_scripts/vw_presentities.sql View File

@ -0,0 +1,20 @@
CREATE VIEW presentities as
select id, cast(printf("sip:%s@%s",username,domain) as varchar(64)) presentity_uri ,
username, domain, event, cast(substr(etag, instr(etag,"@")+1) as varchar(64)) callid,
datetime(received_time, 'unixepoch') as received,
datetime(expires, 'unixepoch') as expire_date,
expires, cast(sender as varchar(30)) sender,
lower(cast( case when event = "dialog"
then substr(body, instr(BODY,"<state>")+7, instr(body,"</state>") - instr(body,"<state>") - 7)
when event = "presence"
then case when instr(body,"<dm:note>") == 0
then replace(substr(body, instr(body,"<note>")+6, instr(body,"</note>") - instr(body,"<note>") - 6), " ", "")
else replace(substr(body, instr(body,"<dm:note>")+9, instr(body,"</dm:note>") - instr(body,"<dm:note>") - 9), " ", "")
end
when event = "message-summary"
then case when instr(body,"Messages-Waiting: yes") = 0
then "Waiting"
else "Not-Waiting"
end
end as varchar(12))) state
from presentity

+ 6
- 0
kamailio-proxy-blf/db_scripts/vw_w_keepalive_contact.sql View File

@ -0,0 +1,6 @@
CREATE VIEW w_keepalive_contact as
select id, slot, selected, failed, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from keepalive

+ 6
- 0
kamailio-proxy-blf/db_scripts/vw_w_location_contact.sql View File

@ -0,0 +1,6 @@
CREATE VIEW w_location_contact as
select id, ruid, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from location

+ 6
- 0
kamailio-proxy-blf/db_scripts/vw_w_watchers_contact.sql View File

@ -0,0 +1,6 @@
CREATE VIEW w_watchers_contact as
select id, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from active_watchers

+ 6
- 0
kamailio-proxy-blf/db_scripts/vw_wdispatcher.sql View File

@ -0,0 +1,6 @@
CREATE VIEW wdispatcher as
select *,
cast(substr(attrs, instr(attrs, "zone=")+5, instr(attrs, ";profile")-instr(attrs, "zone=")-5) as varchar(20)) zone,
cast(substr(attrs, instr(attrs, "duid=")+5, instr(attrs, ";node")-instr(attrs, "duid=")-5) as integer) idx,
cast(substr(attrs, instr(attrs, "node=")+5) as varchar(50)) node
from dispatcher

+ 962
- 0
kamailio-proxy-blf/default.cfg View File

@ -0,0 +1,962 @@
## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
####### Flags #######
#!trydef FLAG_INTERNALLY_SOURCED 1
#!trydef FLAG_ASSOCIATE_SERVER 2
#!trydef FLAG_SKIP_NAT_CORRECTION 3
#!trydef FLAG_ASSOCIATE_USER 4
#!trydef FLAG_TRUSTED_SOURCE 5
#!trydef FLAG_SESSION_PROGRESS 6
#!trydef FLAG_IS_REPLY 7
#!trydef FLAG_SIP_TRACE 8
#!trydef FLT_AOR 9
#!trydef FLT_T38 10
#!trydef FLT_NATS 11
#!trydef FLAG_LOCAL_REQUEST 12
#!trydef FLAG_LOCAL_ROUTE 17
#!trydef FLAG_NETWORK_CLASSIFIED 18
####### Global Parameters #########
fork = yes
children = CHILDREN
server_signature = no
server_header = "Server: Kazoo"
user_agent_header = "User-Agent: Kazoo"
shm_force_alloc = yes
mlock_pages = yes
phone2tel = 1
max_while_loops = MAX_WHILE_LOOPS
pv_buffer_size = PV_BUFFER_SIZE
pv_buffer_slots = PV_BUFFER_SLOTS
mem_join=1
####### Logging Parameters #########
debug = KAZOO_LOG_LEVEL
memdbg = 10
memlog = L_BUG
corelog = L_ERR
mem_summary = KZ_MEM_SUMMARY
log_stderror = no
log_facility = LOG_LOCAL0
log_name="kamailio"
####### Alias Parameters #########
auto_aliases = yes
####### Binding Parameters #########
tos = IPTOS_LOWDELAY
####### TCP Parameters #########
tcp_children = TCP_CHILDREN
disable_tcp = no
tcp_max_connections = TCP_MAX_CONNECTIONS
tcp_connection_lifetime = TCP_CONNECTION_LIFETIME
tcp_accept_aliases = no
tcp_async = yes
tcp_connect_timeout = TCP_CONNECTION_TIMEOUT
tcp_conn_wq_max = 65536
tcp_crlf_ping = yes
tcp_delayed_ack = yes
tcp_fd_cache = yes
tcp_keepalive = TCP_KEEP_ALIVE
tcp_keepcnt = TCP_KEEP_COUNT
tcp_keepidle = TCP_KEEP_IDLE
tcp_keepintvl = TCP_KEEP_INTERVAL
tcp_linger2 = 30
tcp_rd_buf_size = 80000
tcp_send_timeout = TCP_SEND_TIMEOUT
tcp_wq_blk_size = 2100
tcp_wq_max = 10485760
####### UDP Parameters #########
udp4_raw = 0
#udp4_raw_mtu = 800
# # pmtu_discovery = no
#udp_mtu = 800
# #udp_mtu_try_proto = TCP
####### DNS Parameters #########
dns = no
rev_dns = no
dns_try_ipv6 = no
use_dns_cache = on
dns_cache_del_nonexp = yes
dns_cache_flags = 1
dns_cache_gc_interval = 120
dns_cache_init = 0
dns_cache_mem = 1000
dns_cache_negative_ttl = 60
dns_try_naptr = no
use_dns_failover = off
dns_srv_lb = off
####### SCTP Parameters #########
disable_sctp = yes
####### multi homed #########
mhomed=KZ_MULTI_HOMED
######## Kamailio mqueue module ########
loadmodule "mqueue.so"
######## Kamailio outbound module ########
loadmodule "outbound.so"
######## Kamailio stun module ########
loadmodule "stun.so"
######## Kamailio path module ########
loadmodule "path.so"
######## Kamailio control connector module ########
loadmodule "ctl.so"
modparam("ctl", "binrpc_buffer_size", 4096)
loadmodule "cfg_rpc.so"
######## Kamailio config utils module ########
loadmodule "cfgutils.so"
modparam("cfgutils", "lock_set_size", 4)
######## Kamailio corex module ########
loadmodule "corex.so"
######## Kamailio uuid module ########
loadmodule "uuid.so"
######## Kamailio core extensions module ########
loadmodule "kex.so"
######## Transaction (stateful) module ########
loadmodule "tm.so"
loadmodule "tmx.so"
modparam("tm", "auto_inv_100", 1)
modparam("tm", "auto_inv_100_reason", "Attempting to connect your call")
modparam("tm", "cancel_b_method", 2)
modparam("tm", "ruri_matching", 0)
modparam("tm", "failure_reply_mode", 3)
modparam("tm", "failure_exec_mode", 1)
modparam("tm", "reparse_on_dns_failover", 0)
# modparam("tm", "fr_timer", 30000)
# modparam("tm", "fr_inv_timer", 120000)
######## Stateless replier module ########
loadmodule "sl.so"
######## Record-Route and Route module ########
loadmodule "rr.so"
modparam("rr", "enable_full_lr", RR_FULL_LR)
modparam("rr", "enable_double_rr", RR_DOUBLE_RR)
modparam("rr", "force_send_socket", RR_FORCE_SOCKET)
######## Max-Forward processor module ########
loadmodule "maxfwd.so"
modparam("maxfwd", "max_limit", 50)
######## SIP utilities [requires sl] ########
loadmodule "siputils.so"
######## Text operations module ########
loadmodule "textopsx.so"
######## sdp operations module ########
loadmodule "sdpops.so"
######## Generic Hash Table container in shared memory ########
loadmodule "htable.so"
modparam("htable", "htable", "associations=>size=16;autoexpire=7200")
modparam("htable", "htable", "redirects=>size=16;autoexpire=5")
modparam("htable", "db_url", "KAZOO_DB_URL")
####### RTIMER module ##########
loadmodule "rtimer.so"
####### evrexec module ##########
loadmodule "evrexec.so"
modparam("evrexec", "exec", "name=evrexec:DEFERRED_INIT;wait=20000000;workers=1;")
######## Advanced logger module ########
loadmodule "xlog.so"
######## UAC ########
loadmodule "uac.so"
######## AVP's ########
loadmodule "avp.so"
loadmodule "avpops.so"
######## UAC Redirection module ########
loadmodule "uac_redirect.so"
#### json rpc ####
loadmodule "jsonrpcs.so"
####### SQL OPS module ##########
loadmodule "sqlops.so"
modparam("sqlops","sqlcon", "cb=>KAZOO_DB_URL")
modparam("sqlops","sqlcon", "exec=>KAZOO_DB_URL")
####### DEBUG ######
loadmodule "debugger.so"
modparam("debugger", "mod_hash_size", 5)
modparam("debugger", "mod_level_mode", 1)
modparam("debugger", "mod_level", "core=1")
####### STATISTICS ######
loadmodule "statistics.so"
####### DATABASE module ##########
include_file "db_KAMAILIO_DBMS.cfg"
###### kazoo bindings ######
include_file "kazoo-bindings.cfg"
####### Role Configurations ##########
#!ifdef AUTHORIZATION_ROLE
include_file "authorization-role.cfg"
#!endif
#!ifdef DISPATCHER_ROLE
include_file "dispatcher-role-MAJOR.cfg"
#!endif
#!ifdef REGISTRAR_ROLE
include_file "registrar-role.cfg"
#!endif
#!ifdef PRESENCE_ROLE
include_file "presence-role.cfg"
#!endif
#!ifdef MESSAGE_ROLE
include_file "message-role.cfg"
#!endif
#!ifdef NAT_TRAVERSAL_ROLE
include_file "nat-traversal-role.cfg"
#!endif
#!ifdef WEBSOCKETS_ROLE
include_file "websockets-role.cfg"
#!endif
#!ifdef TLS_ROLE
include_file "tls-role.cfg"
#!endif
#!ifdef ACCOUNTING_ROLE
include_file "accounting-role.cfg"
#!endif
#!ifdef ANTIFLOOD_ROLE
include_file "antiflood-role.cfg"
#!endif
#!ifdef TRAFFIC_FILTER_ROLE
include_file "traffic-filter-role.cfg"
#!endif
#!ifdef ACL_ROLE
include_file "acl-role.cfg"
#!endif
#!ifdef RATE_LIMITER_ROLE
include_file "rate-limiter-role.cfg"
#!endif
#!ifdef PUSHER_ROLE
include_file "pusher-role.cfg"
#!endif
#!ifdef RESPONDER_ROLE
include_file "responder-role.cfg"
#!endif
#!ifdef NODES_ROLE
include_file "nodes-role.cfg"
#!endif
#!ifdef SIP_TRACE_ROLE
include_file "sip_trace-role.cfg"
#!endif
#!ifdef KEEPALIVE_ROLE
include_file "keepalive-role.cfg"
#!endif
#!ifdef BLOCKER_ROLE
include_file "blocker-role.cfg"
#!endif
## sanity ##
include_file "sanity.cfg"
## auth ##
include_file "auth.cfg"
####### Permissions module ##########
loadmodule "permissions.so"
modparam("permissions", "db_url", "KAZOO_DB_URL")
modparam("permissions", "db_mode", 1)
###### local route ######
socket_workers=5
listen=tcp:127.0.0.1:5090
####### Routing Logic ########
route
{
route(LOCAL_REQUEST);
route(SANITY_CHECK);
route(CHECK_RETRANS);
#!ifdef ANTIFLOOD_ROLE
route(ANTIFLOOD_LIMIT);
#!endif
#!ifdef TRAFFIC_FILTER_ROLE
route(FILTER_REQUEST);
#!endif
#!ifdef ACL_ROLE
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER_ROLE
route(DOS_PREVENTION);
#!endif
route(LOG_REQUEST);
route(CLASSIFY_SOURCE);
#!ifdef NAT_TRAVERSAL_ROLE
route(NAT_DETECT);
#!endif
route(HANDLE_OPTIONS);
#!ifdef SIP_TRACE_ROLE
route(SIP_TRACE);
#!endif
route_if_exists("CUSTOM_START_ROUTES");
route(HANDLE_NOTIFY);
#!ifdef AUTHORIZATION_ROLE
route(AUTHORIZATION_CHECK);
#!endif
#!ifdef MESSAGE_ROLE
route(HANDLE_MESSAGE);
#!else
if (is_method("MESSAGE")) {
sl_send_reply("405", "Method Not Allowed");
exit;
}
#!endif
#!ifdef PRESENCE_ROLE
route(HANDLE_SUBSCRIBE);
route(HANDLE_PUBLISH);
#!endif
#!ifdef REGISTRAR_ROLE
route(HANDLE_REGISTER);
#!endif
route(HANDLE_REFER);
route(HANDLE_IN_DIALOG_REQUESTS);
route(PREPARE_INITIAL_REQUESTS);
#!ifdef PUSHER_ROLE
route(PUSHER_ROUTE);
#!endif
#!ifdef RESPONDER_ROLE
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(HANDLE_RESPOND);
}
#!endif
route(AUTH);
route(SETUP);
}
#!trydef KZ_LOG_REQUEST_OPTIONS 0
kazoo.log_request_options = KZ_LOG_REQUEST_OPTIONS descr "log OPTIONS requests, default is 0 for preserving log size"
route[LOG_REQUEST]
{
if($sel(cfg_get.kazoo.log_request_options) == 0 && is_method("OPTIONS")) {
$var(log_request_level) = L_DBG;
} else {
$var(log_request_level) = L_INFO;
}
# log the basic info regarding this call
xlog("$var(log_request_level)", "$ci|start|received $pr request $rm $ou\n");
xlog("$var(log_request_level)", "$ci|log|source $si:$sp -> $RAi:$RAp\n");
xlog("$var(log_request_level)", "$ci|log|from $fu\n");
xlog("$var(log_request_level)", "$ci|log|to $tu\n");
}
route[CHECK_RETRANS]
{
# handle retransmissions
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}
}
route[CLASSIFY_SOURCE]
{
#!ifdef DISPATCHER_ROLE
route(DISPATCHER_CLASSIFY_SOURCE);
#!endif
if (allow_source_address(TRUSTED_ADR_GROUP)) {
xlog("$var(log_request_level)", "$ci|log|request from trusted IP\n");
setflag(FLAG_TRUSTED_SOURCE);
}
if (isflagset(FLAG_INTERNALLY_SOURCED) || is_myself($si)) {
setflag(FLAG_TRUSTED_SOURCE);
}
}
route[HANDLE_OPTIONS]
{
if (!is_method("OPTIONS")) {
return;
}
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC_FILTER_ROLE
if (!isflagset(FLAG_TRUSTED_SOURCE)) {
route(FILTER_REQUEST_DOMAIN);
}
#!endif
sl_send_reply("200", "Rawr!!");
#!ifdef KEEPALIVE_ROLE
route(KEEPALIVE_ON_OPTIONS);
#!endif
}
exit;
}
route[HANDLE_NOTIFY]
{
if (!is_method("NOTIFY")) return;
if (has_totag()) return;
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
if (loose_route()) {
xlog("L_INFO", "$ci|log|Able to loose-route. Cool beans!\n");
}
#!ifdef REGISTRAR_ROLE
if (registered("location")) {
lookup("location");
xlog("L_INFO", "$ci|log|routing to $ruid\n");
}
#!endif
## verify we're not routing to ourselves
if(is_myself($du)) {
xlog("L_INFO", "$ci|log|notify from internal to invalid destination $ruid\n");
sl_send_reply("200", "Rawr!!");
exit;
}
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC_FILTER_ROLE
if (!isflagset(FLAG_TRUSTED_SOURCE)) {
route(FILTER_REQUEST_DOMAIN);
}
#!endif
if($hdr(Event) == "keep-alive") {
xlog("L_INFO", "$ci|stop|replying to keep alive\n");
sl_send_reply("405", "Stay Alive / Method Not Allowed");
} else {
xlog("L_INFO", "$ci|stop|consuming event $hdr(Event)\n");
sl_send_reply("200", "Rawr!!");
}
#!ifdef KEEPALIVE_ROLE
route(KEEPALIVE_ON_NOTIFY);
#!endif
}
exit;
}
route[HANDLE_REFER]
{
if (!is_method("REFER")) {
return;
}
if(is_present_hf("Referred-By")) {
$var(referred_by) = $hdr(Referred-By);
} else {
$var(referred_by) = $_s(<sip:$Au>;created=true);
}
route(AUTH);
if($avp(is_registered) = "true") {
$var(referred_by) = $_s($var(referred_by);endpoint_id=$(xavp(ulattrs=>token){re.subst,/(.*)@(.*)/\1/});account_id=$(xavp(ulattrs=>token){re.subst,/(.*)@(.*)/\2/}));
}
remove_hf_re("^Referred-By");
append_hf("Referred-By: $var(referred_by)\r\n");
}
route[HANDLE_IN_DIALOG_REQUESTS]
{
if (!has_totag()) return;
if (is_method("INVITE")) {
setflag(FLAG_SESSION_PROGRESS);
record_route();
}
if (loose_route()) {
#!ifdef NAT_TRAVERSAL_ROLE
if(!isdsturiset()) {
handle_ruri_alias();
}
if ( is_method("ACK") ) {
# ACK is forwarded statelessly
route(NAT_MANAGE);
}
#!endif
#!ifdef ACCOUNTING_ROLE
if (is_method("BYE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
xlog("L_INFO", "$ci|log|loose_route in-dialog message\n");
# Called on in-dialog requests
# If the request in an Invite for on hold from external to internal,
# associate the contact with the media server
# if Invite for on hold, we need to associate the contact URI with the next hop
if (is_method("INVITE") && !isflagset(FLAG_INTERNALLY_SOURCED) && is_audio_on_hold()) {
setflag(FLAG_ASSOCIATE_USER);
}
# If the request in an Invite for t38 from internal,
# mark the request with FLT_T38
if (is_method("INVITE") && isflagset(FLAG_INTERNALLY_SOURCED) && sdp_with_media("image")) {
xlog("L_DEBUG", "$ci|log|T38 RE-INVITE\n");
setflag(FLT_T38);
}
if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
} else if (isflagset(FLAG_INTERNALLY_SOURCED)) {
xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route\n");
route(RELAY);
} else if (t_check_trans()) {
xlog("L_INFO", "$ci|log|allow message for a known transaction\n");
route(RELAY);
} else {
xlog("L_INFO", "$ci|log|message had a to-tag but can't be loose routed\n");
sl_send_reply("481", "Call Leg/Transaction Does Not Exist");
}
exit();
}
route[PREPARE_INITIAL_REQUESTS]
{
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
} else {
sl_send_reply("481", "Call leg/transaction does not exist");
}
exit();
} else if (is_method("ACK")) {
if (t_check_trans()) {
route(RELAY);
}
exit();
}
if (is_method("UPDATE")) {
xlog("L_WARN", "$ci|end|update outside dialog not allowed\n");
send_reply("403", "Dialog does not exist");
break;
}
if (is_method("BYE|PRACK")) {
xlog("L_WARN", "$ci|end|originating subsequent requests outside dialog not allowed\n");
send_reply("403", "Dialog does not exist");
break;
}
if (loose_route()) {
#!ifdef REGISTRAR_ROLE
$xavp(regcfg=>match_received) = $su;
if(registered("location", "$rz:$Au", 2) == 1) {
xlog("L_INFO", "$ci|log|allowing initial route-set for $Au\n");
} else {
#!endif
xlog("L_WARN", "$ci|end|dropping initial request with route-set\n");
sl_send_reply("403", "No pre-loaded routes");
exit();
#!ifdef REGISTRAR_ROLE
}
#!endif
}
record_route();
}
route[SETUP]
{
#!ifdef DISPATCHER_ROLE
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(DISPATCHER_FIND_ROUTES);
}
#!endif
#!ifdef REGISTRAR_ROLE
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(ROUTE_TO_AOR);
}
#!endif
route(RELAY);
}
route[BRANCH_HEADERS]
{
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(AUTH_HEADERS);
} else {
remove_hf_re("^X-");
}
}
# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
xlog("L_DEBUG", "$ci|branch|new branch [$T_branch_idx] to $ru => $du\n");
#!ifdef NAT_TRAVERSAL_ROLE
route(NAT_MANAGE);
#!endif
route(BRANCH_HEADERS);
route_if_exists("CUSTOM_BRANCH_HEADERS");
}
route[RELAY]
{
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE|NOTIFY|REFER")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
route(EXTERNAL_TO_INTERNAL_RELAY);
}
exit();
}
route[INTERNAL_TO_EXTERNAL_RELAY]
{
#!ifdef ACCOUNTING_ROLE
if (is_method("INVITE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
t_on_reply("EXTERNAL_REPLY");
t_set_fr(0, $sel(cfg_get.kazoo.to_external_no_response_timer));
t_relay();
}
route[EXTERNAL_TO_INTERNAL_RELAY]
{
#!ifdef ACCOUNTING_ROLE
if (is_method("INVITE") && is_present_hf("Proxy-Authorization")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
t_on_reply("INTERNAL_REPLY");
t_on_failure("INTERNAL_FAULT");
t_set_fr(0, $sel(cfg_get.kazoo.to_internal_no_response_timer));
t_relay();
}
onreply_route[EXTERNAL_REPLY]
{
xlog("L_INFO", "$ci|log|external reply $T_reply_code $T_reply_reason\n");
#!ifdef NAT_TRAVERSAL_ROLE
if(status=~"[12][0-9][0-9]") {
route(NAT_MANAGE);
}
#!endif
#!ifdef ACL_ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER_ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);
#!endif
}
onreply_route[INTERNAL_REPLY]
{
# this route handles replies that are comming from our media server
if ($rs < 300) {
xlog("L_INFO", "$ci|log|internal reply $T_reply_code $T_reply_reason\n");
xlog("L_DEBUG", "$ci|log|source $si:$sp\n");
}
#!ifdef NAT_TRAVERSAL_ROLE
if(status=~"[12][0-9][0-9]") {
route(NAT_MANAGE);
}
#!endif
#!ifdef ACL_ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER_ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);
#!endif
if (is_method("INVITE") &&
!isflagset(FLAG_SESSION_PROGRESS) &&
t_check_status("(180)|(183)|(200)")
) {
xlog("L_INFO", "$ci|log|call setup, now ignoring abnormal termination\n");
setflag(FLAG_SESSION_PROGRESS);
# clear the redirect
if ($avp(AVP_REDIRECT_KEY) != $null && $sht(redirects=>$avp(AVP_REDIRECT_KEY)) != $null) {
xlog("L_INFO", "$ci|log|removing redirect mapping $avp(AVP_REDIRECT_KEY)\n");
$sht(redirects=>$avp(AVP_REDIRECT_KEY)) = $null;
}
}
if ($rs < 300) {
xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)\n");
}
}
failure_route[INTERNAL_FAULT]
{
# this branch handles failures (>=300) to our media servers,
# which we can sometimes overcome by routing to another server
# if the failure cause was due to the transaction being
# cancelled then we are complete
if (t_is_canceled()) {
xlog("L_INFO", "$ci|log|transaction was cancelled\n");
exit;
}
if (!is_method("INVITE") || has_totag()) {
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
xlog("L_INFO", "$ci|pass|$si:$sp\n");
return;
}
# Handle redirects
if (t_check_status("302") && $T_rpl($hdr(X-Redirect-Server)) != $null) {
route(INTERNAL_REDIRECT);
}
remove_hf_re("^X-.*");
# handle challenges replies from media server, we want to route to same media server
if (t_check_status("407")) {
xlog("L_INFO", "$ci|log|media $xavp(ds_dst=>uri) challenged the invite, creating redirect\n");
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->" + @ruri.user + "@" + @ruri.host;
$sht(redirects=>$var(redirect)) = $xavp(ds_dst=>uri);
# change 6xx to 4xx
} else if (t_check_status("6[0-9][0-9]") && !t_check_status("600|603|604|606")) {
$var(new_code) = "4" + $(T_reply_code{s.substr,1,0});
xlog("L_INFO", "$ci|failure|sending $T_reply_code reply as $var(new_code) $T_reply_reason\n");
t_reply("$(var(new_code){s.int})", "$T_reply_reason");
# if the failure case was something that we should recover
# from then try to find a new media server
} else if ($T_reply_reason =~ "call barred") {
xlog("L_INFO", "$ci|failure|ignoring call barred\n");
} else if (isflagset(FLAG_SESSION_PROGRESS)) {
xlog("L_INFO", "$ci|failure|ignoring failure after session progress\n");
if (t_check_status("480")) {
xlog("L_INFO", "$ci|failure|overriding reply code 480 with $sel(cfg_get.kazoo.override_media_reply_480)\n");
send_reply("$(sel(cfg_get.kazoo.override_media_reply_480){s.int})", "Endpoint Not Available");
}
} else if (t_check_status("403") && $T_reply_reason=="Forbidden") {
xlog("L_WARNING", "$ci|failure|Failed auth from IP $si\n");
} else if (t_check_status("(401)|(486)")) {
xlog("L_INFO", "$ci|failure|auth reply $T_reply_code $T_reply_reason\n");
} else if (t_check_status("402")) {
xlog("L_INFO", "$ci|failure|overriding reply code 402 with 486\n");
send_reply("486", "Insufficient Funds");
} else if (t_check_status("(4[0-9][0-9])|(5[0-9][0-9])")) {
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
#!ifdef DISPATCHER_ROLE
route(DISPATCHER_NEXT_ROUTE);
#!endif
send_reply("486", "Unable to Comply");
} else {
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
send_reply("$T_reply_code", "$T_reply_reason");
}
xlog("L_INFO", "$ci|pass|$si:$sp\n");
}
route[INTERNAL_REDIRECT]
{
xlog("L_INFO", "$ci|log|redirect to $T_rpl($hdr(X-Redirect-Server))\n");
$du = $T_rpl($hdr(X-Redirect-Server));
t_on_branch("MANAGE_BRANCH");
t_on_reply("INTERNAL_REPLY");
t_on_failure("INTERNAL_FAULT");
t_set_fr(0, 1000);
t_relay();
exit();
}
onsend_route {
if (isflagset(FLAG_ASSOCIATE_USER)) {
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
xlog("L_INFO", "$ci|log|associate traffic from $var(user_source) with media server sip:$sndto(ip):$sndto(port)\n");
$sht(associations=>$var(user_source))= "sip:" + $sndto(ip) + ":" + $sndto(port);
}
#!ifdef SIP_TRACE_ROLE
if (is_method("ACK") && isflagset(FLAG_SIP_TRACE)) {
sip_trace();
}
#!endif
if(!isflagset(FLAG_LOCAL_ROUTE)) {
xlog("L_INFO", "$ci|pass|$sndfrom(ip):$sndfrom(port) -> $sndto(ip):$sndto(port)\n");
}
}
route[ROUTE_TO_AOR]
{
if ($hdr(X-KAZOO-AOR) == $null) {
return;
}
xlog("L_INFO", "$ci|log|using AOR $hdr(X-KAZOO-AOR)\n");
if ($hdr(X-KAZOO-INVITE-FORMAT) == "contact") {
if(lookup("location", "$hdr(X-KAZOO-AOR)") > 0){
xlog("L_INFO", "$ci|end|routing to contact $ru\n");
handle_ruri_alias();
} else {
xlog("L_INFO", "$ci|end|lookup for AOR $hdr(X-KAZOO-AOR) failed\n");
sl_send_reply("410", "Not registered");
exit;
}
} else if (reg_fetch_contacts("location", "$hdr(X-KAZOO-AOR)", "callee")) {
$du = $(ulc(callee=>received));
$fs = $(ulc(callee=>socket));
$bf = $bf | $(ulc(callee=>cflags));
xlog("L_INFO", "$ci|log|routing $hdr(X-KAZOO-AOR) to $du via $fs\n");
} else {
xlog("L_INFO", "$ci|end|user is not registered\n");
sl_send_reply("410", "Not registered");
exit;
}
}
event_route[tm:local-request]
{
setflag(FLAG_LOCAL_REQUEST);
xlog("L_DEBUG", "$ci|local|start $pr request $rm $ou\n");
xlog("L_DEBUG", "$ci|local|source $si:$sp -> $dd:$dp\n");
xlog("L_DEBUG", "$ci|local|from $fu\n");
xlog("L_DEBUG", "$ci|local|to $tu\n");
#!ifdef SIP_TRACE_ROLE
route(SIP_TRACE);
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_LOCAL_REQUEST);
#!endif
}
event_route[evrexec:DEFERRED_INIT]
{
xlog("L_INFO", "processing deferred init\n");
#!ifdef PRESENCE_ROLE
route(PRESENCE_DEFERRED_INIT);
#!endif
#!import_file "custom-init.cfg"
}
route[LOCAL_REQUEST]
{
if(src_ip != myself || $hdr(X-TM-Local) == $null) {
return;
}
xlog("L_DEBUG", "internal route $hdr(X-TM-Local)\n");
setflag(FLAG_LOCAL_ROUTE);
#!ifdef SIP_TRACE_ROLE
route(SIP_TRACE);
#!endif
$var(LocalRoute) = $hdr(X-TM-Local);
remove_hf_re("^X-TM-Local");
route_if_exists("$var(LocalRoute)");
exit;
}
#!import_file "custom-routes.cfg"
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 88
- 0
kamailio-proxy-blf/defs-amqp.cfg View File

@ -0,0 +1,88 @@
## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
####### amqp defs ########
#!ifndef AMQP_DEFAULTS_INCLUDED
#!define AMQP_DEFAULTS_INCLUDED
#!trydef MY_AMQP_MAX_CHANNELS 25
#!trydef MY_AMQP_CONSUMER_PROCESSES 4
#!trydef MY_AMQP_CONSUMER_WORKERS 16
#!trydef MY_AMQP_HEARTBEATS 5
#!ifndef MY_AMQP_ZONE
#!substdef "!MY_AMQP_ZONE!local!g"
#!endif
#!ifdef PRESENCE_ROLE
#!trydef MY_AMQP_PUA_MODE 1
#!else
#!trydef MY_AMQP_PUA_MODE 0
#!endif
#!ifndef MY_AMQP_URL
#!ifdef AMQP_URL1
#!substdef "!MY_AMQP_URL!$def(AMQP_URL1)!g"
#!else
#!substdef "!MY_AMQP_URL!amqp://guest:guest@127.0.0.1:5672!g"
#!endif
#!endif
#!ifndef MY_AMQP_SECONDARY_URL
#!ifdef AMQP_URL2
#!substdef "!MY_AMQP_SECONDARY_URL!$def(AMQP_URL2)!g"
#!endif
#!endif
#!ifndef MY_AMQP_TERTIARY_URL
#!ifdef AMQP_URL3
#!substdef "!MY_AMQP_TERTIARY_URL!$def(AMQP_URL3)!g"
#!endif
#!endif
#!ifndef MY_AMQP_QUATERNARY_URL
#!ifdef AMQP_URL4
#!substdef "!MY_AMQP_QUATERNARY_URL!$def(AMQP_URL4)!g"
#!endif
#!endif
#!ifndef MY_AMQP_QUINARY_URL
#!ifdef AMQP_URL5
#!substdef "!MY_AMQP_QUINARY_URL!$def(AMQP_URL5)!g"
#!endif
#!endif
#!ifndef MY_AMQP_SENARY_URL
#!ifdef AMQP_URL6
#!substdef "!MY_AMQP_SENARY_URL!$def(AMQP_URL6)!g"
#!endif
#!endif
#!ifndef MY_AMQP_SEPTENARY_URL
#!ifdef AMQP_URL7
#!substdef "!MY_AMQP_SEPTENARY_URL!$def(AMQP_URL7)!g"
#!endif
#!endif
#!ifndef MY_AMQP_OCTONARY_URL
#!ifdef AMQP_URL8
#!substdef "!MY_AMQP_OCTONARY_URL!$def(AMQP_URL8)!g"
#!endif
#!endif
#!ifndef MY_AMQP_NONARY_URL
#!ifdef AMQP_URL9
#!substdef "!MY_AMQP_NONARY_URL!$def(AMQP_URL9)!g"
#!endif
#!endif
#!ifndef MY_AMQP_DENARY_URL
#!ifdef AMQP_URL10
#!substdef "!MY_AMQP_DENARY_URL!$def(AMQP_URL10)!g"
#!endif
#!endif
#!endif
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 95
- 0
kamailio-proxy-blf/defs.cfg View File

@ -0,0 +1,95 @@
## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
####### defs ########
#!ifndef DEFAULTS_INCLUDED
#!define DEFAULTS_INCLUDED
#!substdef "!MAJOR!$(version(num){re.subst,/^(([^\.])*\.([^\.])*)\..*/\1/})!g"
#!trydef EXTERNAL_TO_INTERNAL_NO_RESPONSE_TIMER 3500
#!trydef INTERNAL_TO_EXTERNAL_NO_RESPONSE_TIMER 3500
#!trydef OVERRIDE_MEDIA_REPLY_480 603
kazoo.to_internal_no_response_timer = EXTERNAL_TO_INTERNAL_NO_RESPONSE_TIMER descr "external to internal no response timer"
kazoo.to_external_no_response_timer = INTERNAL_TO_EXTERNAL_NO_RESPONSE_TIMER descr "internal to external no response timer"
kazoo.override_media_reply_480 = OVERRIDE_MEDIA_REPLY_480 descr "sip code to send upstream when media returns 480 with session in progress"
#!ifndef MY_HOSTNAME
#!substdef "!MY_HOSTNAME!$HN(f)!g"
#!endif
#!ifndef MY_IP_ADDRESS
#!ifdef MY_LOCAL_IP
#!substdef "!MY_IP_ADDRESS!$def(MY_LOCAL_IP)!g"
#!else
#!substdef "!MY_IP_ADDRESS!$HN(i)!g"
#!endif
#!endif
#!ifndef WEBSOCKET_NO_ORIGIN_RESTRICTION
#!ifndef MY_WEBSOCKET_DOMAIN
#!substdef "!MY_WEBSOCKET_DOMAIN!$HN(d)!g"
#!endif
#!endif
#!trydef KAZOO_LOG_LEVEL L_INFO
#!trydef PV_BUFFER_SIZE 16384
#!trydef PV_BUFFER_SLOTS 30
#!trydef KZ_MEM_SUMMARY 0
#!trydef KZ_DB_MODULE kazoo
#!substdef "!KAMAILIO_DBMS!$def(KZ_DB_MODULE)!g"
#!ifndef KAZOO_DATA_DIR
#!substdef "!KAZOO_DATA_DIR!/etc/kazoo/kamailio/db!g"
#!endif
#!ifndef KAZOO_DB_URL
#!substdef "!KAZOO_DB_URL!kazoo:///KAZOO_DATA_DIR/kazoo.db!g"
#!endif
#!ifndef MAX_WHILE_LOOPS
#!substdef "!MAX_WHILE_LOOPS!500!g"
#!endif
#### tcp parameters ##
#!trydef CHILDREN 25
#!trydef TCP_CHILDREN 25
#!trydef TCP_MAX_CONNECTIONS 4096
#!trydef TCP_CONNECTION_LIFETIME 3605
#!trydef TCP_CONNECTION_TIMEOUT 5
#!trydef TCP_KEEP_ALIVE yes
#!trydef TCP_KEEP_COUNT 3
#!trydef TCP_KEEP_IDLE 30
#!trydef TCP_KEEP_INTERVAL 30
#!trydef TCP_SEND_TIMEOUT 3
#!include_file "defs-amqp.cfg"
#!ifndef MEDIA_SERVERS_HASH_SIZE
#!substdef "!MEDIA_SERVERS_HASH_SIZE!256!g"
#!endif
#!trydef RR_FULL_LR 1
#!trydef RR_DOUBLE_RR 1
#!trydef RR_FORCE_SOCKET 1
#!ifndef KZ_DISABLE_WEBSOCKETS_REGISTRAR_PORT
#!trydef KZ_WEBSOCKETS_REGISTRAR_PORT 7000
#!endif
#!ifndef KZ_DISABLE_TLS_REGISTRAR_PORT
#!trydef KZ_TLS_REGISTRAR_PORT 7000
#!endif
#!trydef KZ_MULTI_HOMED 0
#!endif
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 306
- 0
kamailio-proxy-blf/dispatcher-role-5.1.cfg View File

@ -0,0 +1,306 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "dst_avp", "$avp(ds_dst)")
modparam("dispatcher", "attrs_avp", "$avp(ds_attrs)")
modparam("dispatcher", "grp_avp", "$avp(ds_grp)")
modparam("dispatcher", "cnt_avp", "$avp(ds_cnt)")
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
#!import_file "dispatcher-network-params.cfg"
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
#!import_file "dispatcher-network-classify.cfg"
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $sel(cfg_get.kazoo.dispatcher_primary_group);
$var(ds_backup_group) = $sel(cfg_get.kazoo.dispatcher_secondary_group);
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
add_path();
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
add_path();
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
#!import_file "dispatcher-network-find.cfg"
$var(ds_group) = $var(ds_primary_group);
if (!ds_select_dst("$var(ds_primary_group)", "$sel(cfg_get.kazoo.dispatcher_algorithm)") || $(avp(ds_dst)[0]) == $null) {
# we selected from primary group, try again in backup group
if (!ds_select_dst("$var(ds_backup_group)", "$sel(cfg_get.kazoo.dispatcher_algorithm)") || $(avp(ds_dst)[0]) == $null) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
} else {
$var(ds_group) = $var(ds_backup_group);
}
}
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_retries) = 0;
}
route[DISPATCHER_PREFERRED_ROUTE]
{
######
# check if the preferred route is active
######
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $avp(ds_dst)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
######
# filters current list from prefered route
# * saves the current list to temp avp removing the preferred route if it exists
# * resets current list
# * copies the temp back to list
# sets the prefered at top
# sets $du (destination) to prefered
######
$var(i) = 0;
while($(avp(ds_dst)[$var(i)]) != $null) {
if($(avp(ds_dst)[$var(i)]) != $var(prefered_route)) {
$avp(tmp_ds_dst) = $(avp(ds_dst)[$var(i)]);
}
$var(i) = $var(i) + 1;
}
$(avp(ds_dst)[*]) = $null;
$var(i) = 0;
while($(avp(tmp_ds_dst)[$var(i)]) != $null) {
$avp(ds_dst) = $(avp(tmp_ds_dst)[$var(i)]);
$var(i) = $var(i) + 1;
}
$avp(ds_dst) = $var(prefered_route);
$du = $var(prefered_route);
$(avp(tmp_ds_dst)[*]) = $null;
return 1;
}
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
$var(remaining) = $(sel(cfg_get.kazoo.dispatcher_max_retries){s.int}) - $avp(ds_retries);
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|remaining failed retry attempts: $var(remaining)\n");
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# reset the final reply timer
$avp(final_reply_timer) = 3;
# relay the request to the new media server
route(RELAY);
exit();
}
}
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_NOTICE", "Destination up: $ru\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
#!import_file "dispatcher-custom-media-check.cfg"
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_NOTICE", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 309
- 0
kamailio-proxy-blf/dispatcher-role-5.2.cfg View File

@ -0,0 +1,309 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
#!trydef KZ_DISPATCHER_PRINT_ROUTES 1
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
kazoo.dispatcher_print_routes = KZ_DISPATCHER_PRINT_ROUTES descr "should we log the selected routes"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
modparam("dispatcher", "xavp_dst", "ds_dst")
modparam("dispatcher", "xavp_ctx", "ds_ctx")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
route_if_exists("DISPATCHER_CUSTOM_NETWORK_CLASSIFY");
if (!isflagset(FLAG_NETWORK_CLASSIFIED)) {
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $(sel(cfg_get.kazoo.dispatcher_primary_group){s.int});
$var(ds_backup_group) = $(sel(cfg_get.kazoo.dispatcher_secondary_group){s.int});
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
route_if_exists("DISPATCHER_CUSTOM_SET_GROUPS");
$var(ds_group) = $var(ds_primary_group);
$var(ds_alg) = $sel(cfg_get.kazoo.dispatcher_algorithm);
if(ds_list_exists("$var(ds_backup_group)")) {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg);$var(ds_backup_group)=$var(ds_alg));
} else {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg));
}
ds_select_routes("$var(ds_rule)", "2");
if ($xavp(ds_ctx=>cnt) == 0) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
}
route(PRINT_ROUTES);
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->"
+ @ruri.user + "@" + @ruri.host;
if ($sht(redirects=>$var(redirect)) != $null) {
$var(prefered_route) = $sht(redirects=>$var(redirect));
xlog("L_INFO", "$ci|route|found redirect for $var(redirect) to $var(prefered_route)\n");
$avp(AVP_REDIRECT_KEY) = $var(redirect);
route(DISPATCHER_PREFERRED_ROUTE);
} else if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_group) = $xavp(ds_dst=>grp);
$avp(ds_retries) = 0;
ds_set_dst();
}
route[DISPATCHER_PREFERRED_ROUTE]
{
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $xavp(ds_dst=>uri)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
$var(i) = $xavp(ds_ctx=>cnt) - 1;
while($var(i) >= 0) {
if($xavp(ds_dst[$var(i)]=>uri) == $var(prefered_route)) {
$xavp(ds_dst[$var(i)]) = $null;
}
$var(i) = $var(i) - 1;
}
$xavp(ds_dst=>uri) = $var(prefered_route);
$xavp(ds_dst[0]=>grp) = $var(setid);
$xavp(ds_dst[0]=>attrs) = $var(attrs);
return 1;
}
route[PRINT_ROUTES]
{
if($sel(cfg_get.kazoo.dispatcher_print_routes) == 0) return;
$var(i) = 0;
while($xavp(ds_dst[$var(i)]=>uri) != $null) {
xlog("L_INFO", "$ci|route|group $xavp(ds_dst[$var(i)]=>grp) => $xavp(ds_dst[$var(i)]=>uri) => zone $(xavp(ds_dst[$var(i)]=>attrs){param.value,zone})\n");
$var(i) = $var(i) + 1;
}
}
#!import_file "dispatcher-next-route.cfg"
#!ifndef CUSTOM_DISPATCHER_NEXT_ROUTE
# Try next destinations in failure route
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# relay the request to the new media server
route(RELAY);
exit;
}
}
#!endif
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_WARNING", "Destination up: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_WARNING", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 309
- 0
kamailio-proxy-blf/dispatcher-role-5.4.cfg View File

@ -0,0 +1,309 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
#!trydef KZ_DISPATCHER_PRINT_ROUTES 1
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
kazoo.dispatcher_print_routes = KZ_DISPATCHER_PRINT_ROUTES descr "should we log the selected routes"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
modparam("dispatcher", "xavp_dst", "ds_dst")
modparam("dispatcher", "xavp_ctx", "ds_ctx")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
route_if_exists("DISPATCHER_CUSTOM_NETWORK_CLASSIFY");
if (!isflagset(FLAG_NETWORK_CLASSIFIED)) {
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $(sel(cfg_get.kazoo.dispatcher_primary_group){s.int});
$var(ds_backup_group) = $(sel(cfg_get.kazoo.dispatcher_secondary_group){s.int});
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
route_if_exists("DISPATCHER_CUSTOM_SET_GROUPS");
$var(ds_group) = $var(ds_primary_group);
$var(ds_alg) = $sel(cfg_get.kazoo.dispatcher_algorithm);
if(ds_list_exists("$var(ds_backup_group)")) {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg);$var(ds_backup_group)=$var(ds_alg));
} else {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg));
}
ds_select_routes("$var(ds_rule)", "2");
if ($xavp(ds_ctx=>cnt) == 0) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
}
route(PRINT_ROUTES);
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->"
+ @ruri.user + "@" + @ruri.host;
if ($sht(redirects=>$var(redirect)) != $null) {
$var(prefered_route) = $sht(redirects=>$var(redirect));
xlog("L_INFO", "$ci|route|found redirect for $var(redirect) to $var(prefered_route)\n");
$avp(AVP_REDIRECT_KEY) = $var(redirect);
route(DISPATCHER_PREFERRED_ROUTE);
} else if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_group) = $xavp(ds_dst=>grp);
$avp(ds_retries) = 0;
ds_set_dst();
}
route[DISPATCHER_PREFERRED_ROUTE]
{
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $xavp(ds_dst=>uri)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
$var(i) = $xavp(ds_ctx=>cnt) - 1;
while($var(i) >= 0) {
if($xavp(ds_dst[$var(i)]=>uri) == $var(prefered_route)) {
$xavp(ds_dst[$var(i)]) = $null;
}
$var(i) = $var(i) - 1;
}
$xavp(ds_dst=>uri) = $var(prefered_route);
$xavp(ds_dst[0]=>grp) = $var(setid);
$xavp(ds_dst[0]=>attrs) = $var(attrs);
return 1;
}
route[PRINT_ROUTES]
{
if($sel(cfg_get.kazoo.dispatcher_print_routes) == 0) return;
$var(i) = 0;
while($xavp(ds_dst[$var(i)]=>uri) != $null) {
xlog("L_INFO", "$ci|route|group $xavp(ds_dst[$var(i)]=>grp) => $xavp(ds_dst[$var(i)]=>uri) => zone $(xavp(ds_dst[$var(i)]=>attrs){param.value,zone})\n");
$var(i) = $var(i) + 1;
}
}
#!import_file "dispatcher-next-route.cfg"
#!ifndef CUSTOM_DISPATCHER_NEXT_ROUTE
# Try next destinations in failure route
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# relay the request to the new media server
route(RELAY);
exit;
}
}
#!endif
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_WARNING", "Destination up: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_WARNING", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 309
- 0
kamailio-proxy-blf/dispatcher-role-5.5.cfg View File

@ -0,0 +1,309 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
#!trydef KZ_DISPATCHER_PRINT_ROUTES 1
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
kazoo.dispatcher_print_routes = KZ_DISPATCHER_PRINT_ROUTES descr "should we log the selected routes"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
modparam("dispatcher", "xavp_dst", "ds_dst")
modparam("dispatcher", "xavp_ctx", "ds_ctx")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
route_if_exists("DISPATCHER_CUSTOM_NETWORK_CLASSIFY");
if (!isflagset(FLAG_NETWORK_CLASSIFIED)) {
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $(sel(cfg_get.kazoo.dispatcher_primary_group){s.int});
$var(ds_backup_group) = $(sel(cfg_get.kazoo.dispatcher_secondary_group){s.int});
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
route_if_exists("DISPATCHER_CUSTOM_SET_GROUPS");
$var(ds_group) = $var(ds_primary_group);
$var(ds_alg) = $sel(cfg_get.kazoo.dispatcher_algorithm);
if(ds_list_exists("$var(ds_backup_group)")) {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg);$var(ds_backup_group)=$var(ds_alg));
} else {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg));
}
ds_select_routes("$var(ds_rule)", "2");
if ($xavp(ds_ctx=>cnt) == 0) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
}
route(PRINT_ROUTES);
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->"
+ @ruri.user + "@" + @ruri.host;
if ($sht(redirects=>$var(redirect)) != $null) {
$var(prefered_route) = $sht(redirects=>$var(redirect));
xlog("L_INFO", "$ci|route|found redirect for $var(redirect) to $var(prefered_route)\n");
$avp(AVP_REDIRECT_KEY) = $var(redirect);
route(DISPATCHER_PREFERRED_ROUTE);
} else if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_group) = $xavp(ds_dst=>grp);
$avp(ds_retries) = 0;
ds_set_dst();
}
route[DISPATCHER_PREFERRED_ROUTE]
{
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $xavp(ds_dst=>uri)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
$var(i) = $xavp(ds_ctx=>cnt) - 1;
while($var(i) >= 0) {
if($xavp(ds_dst[$var(i)]=>uri) == $var(prefered_route)) {
$xavp(ds_dst[$var(i)]) = $null;
}
$var(i) = $var(i) - 1;
}
$xavp(ds_dst=>uri) = $var(prefered_route);
$xavp(ds_dst[0]=>grp) = $var(setid);
$xavp(ds_dst[0]=>attrs) = $var(attrs);
return 1;
}
route[PRINT_ROUTES]
{
if($sel(cfg_get.kazoo.dispatcher_print_routes) == 0) return;
$var(i) = 0;
while($xavp(ds_dst[$var(i)]=>uri) != $null) {
xlog("L_INFO", "$ci|route|group $xavp(ds_dst[$var(i)]=>grp) => $xavp(ds_dst[$var(i)]=>uri) => zone $(xavp(ds_dst[$var(i)]=>attrs){param.value,zone})\n");
$var(i) = $var(i) + 1;
}
}
#!import_file "dispatcher-next-route.cfg"
#!ifndef CUSTOM_DISPATCHER_NEXT_ROUTE
# Try next destinations in failure route
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# relay the request to the new media server
route(RELAY);
exit;
}
}
#!endif
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_WARNING", "Destination up: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_WARNING", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

kamailio/kamailio.cfg → kamailio-proxy-blf/kamailio.cfg View File


+ 156
- 0
kamailio-proxy-blf/kazoo-bindings.cfg View File

@ -0,0 +1,156 @@
######## kazoo bindings ########
###
###
#!trydef KZ_PUA_PRESENCE_USE_FULL_ENTITY 1
####### Kazoo Integration module ##########
loadmodule "kazoo.so"
modparam("kazoo", "pua_mode", MY_AMQP_PUA_MODE)
modparam("kazoo", "amqp_primary_zone", "MY_AMQP_ZONE")
modparam("kazoo", "amqp_query_timeout_avp", "$avp(kz_timeout)")
modparam("kazoo", "node_hostname", "MY_HOSTNAME")
modparam("kazoo", "amqp_heartbeats", MY_AMQP_HEARTBEATS)
modparam("kazoo", "amqp_max_channels", MY_AMQP_MAX_CHANNELS)
modparam("kazoo", "amqp_consumer_processes", MY_AMQP_CONSUMER_PROCESSES)
modparam("kazoo", "amqp_consumer_workers", MY_AMQP_CONSUMER_WORKERS)
modparam("kazoo", "presence_use_full_entity", KZ_PUA_PRESENCE_USE_FULL_ENTITY)
## amqp connections
#!ifdef MY_AMQP_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_URL")
#!endif
#!ifdef MY_AMQP_SECONDARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_SECONDARY_URL")
#!endif
#!ifdef MY_AMQP_TERTIARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_TERTIARY_URL")
#!endif
#!ifdef MY_AMQP_QUATERNARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_QUATERNARY_URL")
#!endif
#!ifdef MY_AMQP_QUINARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_QUINARY_URL")
#!endif
#!ifdef MY_AMQP_SENARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_SENARY_URL")
#!endif
#!ifdef MY_AMQP_SEPTENARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_SEPTENARY_URL")
#!endif
#!ifdef MY_AMQP_OCTONARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_OCTONARY_URL")
#!endif
#!ifdef MY_AMQP_NONARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_NONARY_URL")
#!endif
#!ifdef MY_AMQP_DENARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_DENARY_URL")
#!endif
event_route[kazoo:mod-init]
{
#!ifdef PRESENCE_ROLE
route(PRESENCE_BINDINGS);
#!endif
#!ifdef MESSAGE_ROLE
route(MESSAGE_BINDINGS);
#!endif
#!ifdef REGISTRAR_ROLE
route(REGISTRAR_BINDINGS);
#!endif
#!ifdef NODES_ROLE
route(NODES_BINDINGS);
#!endif
#!ifdef ACL_ROLE
route(ACL_BINDINGS);
#!endif
#!import_file "kazoo-custom-bindings.cfg"
}
event_route[kazoo:consumer-event]
{
xlog("L_DEBUG","unhandled AMQP event, payload: $kzE\n");
}
event_route[kazoo:consumer-event-connection-open]
{
xlog("L_DEBUG","connection to $(kzE{kz.json,host}) opened\n");
}
event_route[kazoo:consumer-event-connection-error]
{
xlog("L_ERR","amqp|error|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|$(kzE{kz.json,message})\n");
}
event_route[kazoo:consumer-event-connection-message]
{
xlog("L_DEBUG","amqp|msg|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|$(kzE{kz.json,message})\n");
}
event_route[kazoo:consumer-event-connection-closed]
{
xlog("L_DEBUG","amqp|closed|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|connection to $(kzE{kz.json,host}) closed\n");
}
event_route[kazoo:consumer-event-connection-zone-available]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is available\n");
}
event_route[kazoo:consumer-event-connection-zone-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
event_route[kazoo:consumer-event-connection-available]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is available\n");
}
event_route[kazoo:consumer-event-connection-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
event_route[kazoo:consumer-event-connection-zone-listener-available]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is available\n");
}
event_route[kazoo:consumer-event-connection-zone-listener-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
event_route[kazoo:consumer-event-connection-listener-zone-available]
{
xlog("L_NOTICE","amqp|connection|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|listener available\n");
}
event_route[kazoo:consumer-event-connection-listener-zone-unavailable]
{
xlog("L_WARN","amqp|connection|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|listener unavailable\n");
#!ifdef PRESENCE_ROLE
route(PRESENCE_ZONE_UNAVAILABLE);
#!endif
}
event_route[kazoo:consumer-event-connection-listener-available]
{
xlog("L_DEBUG","amqp|connection|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|listener available\n");
}
event_route[kazoo:consumer-event-connection-listener-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 343
- 0
kamailio-proxy-blf/keepalive-role.cfg View File

@ -0,0 +1,343 @@
######## KEEPALIVE PINGING ########
#!trydef KEEPALIVE_ENABLED 1
#!trydef KEEPALIVE_NAT_ONLY 0
#!trydef KEEPALIVE_UDP_ONLY 0
#!trydef KEEPALIVE_TIMERS 4
#!trydef KEEPALIVE_INTERVAL 60
#!trydef KEEPALIVE_TIMEOUT 5000
#!trydef KEEPALIVE_FAILED_THRESHOLD 2
#!trydef KEEPALIVE_EXPIRE_SUBSCRIPTIONS 1
#!trydef KEEPALIVE_EXPIRE_REGISTRATIONS 1
#!trydef KEEPALIVE_FAILED_ACTION 1
#!trydef KEEPALIVE_FAILED_LOG_LEVEL 0
#!trydef KEEPALIVE_EXPIRED_SUBSCRIPTION_ACTION 1
#!trydef KEEPALIVE_EXPIRED_REGISTRATION_ACTION 1
#!trydef KEEPALIVE_ON_SUBSCRIPTION_ACTION 1
#!trydef KEEPALIVE_ON_REGISTRATION_ACTION 1
#!substdef "!KEEPALIVE_S_FROM_URI!sip:keepalive@MY_HOSTNAME!g"
#!substdef "!KEEPALIVE_S_TIMERS!$def(KEEPALIVE_TIMERS)!g"
kazoo.keepalive_udp_only = KEEPALIVE_UDP_ONLY descr "should we send keepalive for udp only"
kazoo.keepalive_nat_only = KEEPALIVE_NAT_ONLY descr "should we send keepalive for nat phones only"
kazoo.keepalive_timeout = KEEPALIVE_TIMEOUT descr "timeout in ms for keepalive transaction"
kazoo.keepalive_failed_threshold = KEEPALIVE_FAILED_THRESHOLD descr "how many times can a device fail to respond to OPTIONS"
kazoo.keepalive_expire_subscriptions = KEEPALIVE_EXPIRE_SUBSCRIPTIONS descr "expires subscriptions that do not respond to OPTIONS"
kazoo.keepalive_expire_registrations = KEEPALIVE_EXPIRE_REGISTRATIONS descr "expires registrations that do not respond to OPTIONS"
kazoo.keepalive_failed_log_level = KEEPALIVE_FAILED_LOG_LEVEL descr "loglevel for keepalive failed reply"
kazoo.keepalive_failed_action = KEEPALIVE_FAILED_ACTION descr "action for devices that exceed the threshold. 1 = disable, 2 = delete"
kazoo.keepalive_interval = KEEPALIVE_INTERVAL descr "interval in seconds between attempts to send OPTIONS to device"
kazoo.keepalive_expired_registration_action = KEEPALIVE_EXPIRED_REGISTRATION_ACTION descr "action when registrar expires a registration, 1 = delete , 2 = disable, 0 = none"
kazoo.keepalive_expired_subscription_action = KEEPALIVE_EXPIRED_SUBSCRIPTION_ACTION descr "action when presence expires a subscription, 1 = delete , 2 = disable, 0 = none"
kazoo.keepalive_on_registration_action = KEEPALIVE_ON_REGISTRATION_ACTION descr "action on registration, 1 = insert in keepalive , 0 = none"
kazoo.keepalive_on_subscription_action = KEEPALIVE_ON_SUBSCRIPTION_ACTION descr "action on subscription, 1 = insert in keepalive , 0 = none"
kazoo.keepalive_enable = KEEPALIVE_ENABLED descr "enable keepalive, 1 = on , 0 = off"
modparam("rtimer", "timer", "name=keepalive_timer;interval=1;mode=KEEPALIVE_S_TIMERS;")
modparam("rtimer", "exec", "timer=keepalive_timer;route=KEEPALIVE_TIMER")
modparam("rtimer", "timer", "name=keepalive_db_timer;interval=1;mode=1;")
modparam("rtimer", "exec", "timer=keepalive_db_timer;route=KEEPALIVE_DB_TIMER")
##modparam("rtimer", "timer", "name=keepalive_cleanup;interval=5;mode=1;")
##modparam("rtimer", "exec", "timer=keepalive_cleanup;route=KEEPALIVE_CLEANUP")
modparam("mqueue","mqueue", "name=keepalive_db_queue")
modparam("statistics","variable", "keepalive:success")
modparam("statistics","variable", "keepalive:failure")
modparam("statistics","variable", "keepalive:db:success")
modparam("statistics","variable", "keepalive:db:failure")
modparam("statistics","variable", "keepalive:client_options")
modparam("statistics","variable", "keepalive:client_notify")
modparam("statistics","variable", "keepalive:disabled")
modparam("statistics","variable", "keepalive:removed")
modparam("statistics","variable", "keepalive:expired_registrations")
modparam("statistics","variable", "keepalive:expired_subscriptions")
modparam("statistics","variable", "keepalive:from_registration")
modparam("statistics","variable", "keepalive:from_subscription")
modparam("statistics","variable", "keepalive:removed_from_registration")
modparam("statistics","variable", "keepalive:removed_from_subscription")
modparam("statistics","variable", "keepalive:disabled_from_expired_registration")
modparam("statistics","variable", "keepalive:removed_from_expired_registration")
modparam("statistics","variable", "keepalive:disabled_from_expired_subscription")
modparam("statistics","variable", "keepalive:removed_from_expired_subscription")
modparam("htable", "htable", "keepalive=>size=32;")
route[KEEPALIVE_DB_TIMER]
{
$var(runloop) = 1;
while(mq_fetch("keepalive_db_queue") == 1 && $var(runloop) < MAX_WHILE_LOOPS) {
$var(ci) = $mqk(keepalive_db_queue);
xlog("L_DEBUG", "Query : $var(ci) => $mqv(keepalive_db_queue)\n");
$var(sqlres) = sql_query("cb", "$mqv(keepalive_db_queue)");
xlog("L_DEBUG", "Query result : $var(sqlres)\n");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$var(ci)|log|error running query : $mqv(keepalive_db_queue)\n");
} else {
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("$var(ci)", "$var(stat_update)");
$var(nrows) = $sqlrows(cb);
xlog("L_DEBUG", "$var(ci)|log|end UPDATED $var(nrows) => $var(stat_update)\n");
if($var(nrows) == 0) {
xlog("L_DEBUG", "$var(ci)|log|error no rows affected when running query\n");
}
}
$var(runloop) = $var(runloop) + 1;
}
}
route[KEEPALIVE_CLEANUP]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
$var(Query) = $_s(UPDATE keepalive SET SELECTED = 9 WHERE slot = $var(slot) AND selected = 0 and failed > $sel(cfg_get.kazoo.keepalive_failed_threshold));
# $var(Query) = $_s(UPDATE keepalive SET SELECTED = 9 where selected < 3 and failed > $sel(cfg_get.kazoo.keepalive_failed_threshold));
sql_query("cb", "$var(Query)");
if($sqlrows(cb) > 0) {
if($sel(cfg_get.kazoo.keepalive_expire_registrations) == 1) {
if($def(REGISTRAR_DB_MODE) == 3) {
$var(Query) = $_s(update location set expires = last_modified where id in(select b.id from w_keepalive_contact a inner join w_location_contact b on a.contact = b.contact where selected = 9));
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("keepalive:expired_registrations", "$var(stat_update)");
} else {
$var(Query) = $_s(update location set expires = last_modified where id in(select b.id from w_keepalive_contact a inner join w_location_contact b on a.contact = b.contact where selected = 9));
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("keepalive:expired_registrations", "$var(stat_update)");
}
}
if($sel(cfg_get.kazoo.keepalive_expire_subscriptions) == 1) {
$var(Query) = $_s(DELETE FROM active_watchers where id in(select b.id from w_keepalive_contact a inner join w_watchers_contact b on a.contact = b.contact where selected = 9));
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("keepalive:expired_subscriptions", "$var(stat_update)");
}
if($sel(cfg_get.kazoo.keepalive_failed_action) == 2) {
## disable
$var(Query) = $_s(UPDATE keepalive SET SELECTED = 10 where selected = 9);
$var(stat) = "keepalive:disabled";
} else if($sel(cfg_get.kazoo.keepalive_failed_action) == 1) {
## delete - will be recreated on registration/subscription with same contact
$var(Query) = $_s(DELETE FROM keepalive where selected = 9);
$var(stat) = "keepalive:removed";
}
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("$var(stat)", "$var(stat_update)");
}
}
route[KEEPALIVE_TIMER]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
$var(base_slot) = $rtimer_worker * $sel(cfg_get.kazoo.keepalive_interval);
$var(slot) = $var(base_slot) + $var(tick);
$var(Query) = $_s(UPDATE keepalive SET selected = 1 WHERE slot = $var(slot) AND selected = 0 AND time_sent < datetime('now', '-$sel(cfg_get.kazoo.keepalive_interval) seconds'));
## xlog("L_NOTICE", "SQLTIMER ($var(base_slot) + $var(tick))> $var(Query)\n");
$var(sqlres) = sql_query("cb", "$var(Query)");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$rtimer_worker|$var(tick)|log|error running query : $var(Query)\n");
} else {
$var(nrows) = $sqlrows(cb);
xlog("L_DEBUG", "$rtimer_worker|$var(tick)|log|selected $var(nrows) endpoints to ping\n");
}
route(KEEPALIVE_CLEANUP);
$var(Query) = $_s(SELECT id, contact, sockinfo from keepalive WHERE slot = $var(slot) AND selected = 1);
xlog("L_DEBUG", "$rtimer_worker|$var(tick)|timer|SQL => $var(Query)\n");
$var(result) =sql_xquery("cb", "$var(Query)", "ra");
if($var(result) == 1) {
while($xavp(ra) != $null) {
$var(loop) = 0;
while($xavp(ra) != $null && $var(loop) < MAX_WHILE_LOOPS) {
route(KEEPALIVE_SEND_PING);
pv_unset("$xavp(ra)");
$var(loop) = $var(loop) + 1;
}
}
}
$var(Query) = $_s(UPDATE keepalive SET selected = 2 WHERE slot = $var(slot) AND selected = 1);
$var(sqlres) = sql_query("cb", "$var(Query)");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$rtimer_worker|$var(tick)|log|error running query : $var(Query)\n");
}
$var(tick) = $var(tick) + 1;
if($var(tick) > $sel(cfg_get.kazoo.keepalive_interval)) {
$var(tick) = 0;
}
}
route[KEEPALIVE_SEND_PING]
{
$var(CallId) = $uuid(g);
xlog("L_DEBUG", "$var(CallId)|$rtimer_worker|timer|SENDING PING FROM $xavp(ra=>local_contact) TO => $xavp(ra=>contact)\n");
$uac_req(method)="OPTIONS";
$uac_req(hdrs) = "X-TM-Local: KEEPALIVE_PING\r\nX-TM-SockInfo: " + $xavp(ra=>sockinfo) + "\r\n";
$uac_req(turi) = $xavp(ra=>contact);
$uac_req(ruri) = $xavp(ra=>contact);
$uac_req(furi) = $_s(KEEPALIVE_S_FROM_URI;nat_id=$xavp(ra=>id));
$uac_req(ouri) = "sip:127.0.0.1:5090;transport=tcp";
$uac_req(callid) = $var(CallId);
uac_req_send();
}
onreply_route[KEEPALIVE_REPLY]
{
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE REPLY $(tu{nameaddr.uri})\n");
$var(Query) = $_s(UPDATE keepalive SET selected = 0, failed = 0, time_sent = datetime('now') WHERE id = $(fu{uri.param,nat_id}) AND SELECTED = 2);
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE UPDATE SQL => '$var(Query)'\n");
mq_add("keepalive_db_queue", "keepalive:db:success", "$var(Query)");
update_stat("keepalive:success", "+1");
resetflag(FLAG_SIP_TRACE);
}
failure_route[KEEPALIVE_FAULT]
{
xlog("$(sel(cfg_get.kazoo.keepalive_failed_log_level){s.int})", "$ci|keepalive|received error $T_reply_code $T_reply_reason from $(tu{nameaddr.uri})\n");
$var(Query) = $_s(UPDATE keepalive SET selected = 0, failed = failed + 1, time_sent = datetime('now') WHERE id = $(fu{uri.param,nat_id}) AND SELECTED = 2);
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE REMOVE SQL => '$var(Query)'\n");
mq_add("keepalive_db_queue", "keepalive:db:failure", "$var(Query)");
update_stat("keepalive:failure", "+1");
resetflag(FLAG_SIP_TRACE);
}
route[KEEPALIVE_PING]
{
$fs = $hdr(X-TM-SockInfo);
remove_hf_re("^X-TM-SockInfo");
force_rport();
handle_ruri_alias();
record_route();
xlog("L_DEBUG", "$ci|local|sending $proto keepalive using $fs to $ru => $du => $tu\n");
t_on_reply("KEEPALIVE_REPLY");
t_on_failure("KEEPALIVE_FAULT");
t_set_fr(0, $sel(cfg_get.kazoo.keepalive_timeout));
t_relay();
}
route[KEEPALIVE_ON_REGISTRATION]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($sel(cfg_get.kazoo.keepalive_on_registration_action) == 0) {
return;
}
if($proto == "ws" || $proto == "wss") {
return;
}
if($sht(keepalive=>$si~$sp~$prid) != $null) {
return;
}
if (isbflagset(FLB_NATB)) {
if(!isbflagset(FLB_NATSIPPING)) {
return;
}
} else {
if($sel(cfg_get.kazoo.keepalive_nat_only) == 1) {
return;
}
}
$var(alias) = $(avp(AVP_RECV_PARAM){uri.host}) + "~" + $(avp(AVP_RECV_PARAM){uri.port}) + "~" + $prid;
$var(contact) = $(ct{nameaddr.uri}) + ";alias=" + $var(alias);
$var(local_contact) = "sip:" + $Ri + ":" + $Rp + ";transport=" + $proto;
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE ON REG $var(save_result) $proto $RAut $var(contact) $var(alias) $(ct{nameaddr.uri}) $ct $avp(AVP_RECV_PARAM) $tu $xavp(ulrcd=>ruid) , $xavp(ulrcd=>contact) , $xavp(ulrcd=>expires)\n");
if($var(save_result) == 3) {
$var(sql) = $_s(DELETE FROM keepalive WHERE contact = "$var(contact)");
$var(stat) = "keepalive:removed_from_registration";
} else {
$var(max_slots) = $sel(cfg_get.kazoo.keepalive_interval) * KEEPALIVE_S_TIMERS;
$var(slot) = $(var(contact){s.corehash, $var(max_slots)});
$var(sql) = $_s(INSERT OR IGNORE INTO keepalive (contact, received, sockinfo, slot) values("$var(contact)", "$var(alias)", "$(RAut{uri.tosocket})", $var(slot)));
$var(stat) = "keepalive:from_registration";
}
mq_add("keepalive_db_queue", "$var(stat)", "$var(sql)");
return;
}
route[KEEPALIVE_ON_SUBSCRIBE]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($sel(cfg_get.kazoo.keepalive_on_subscription_action) == 0) {
return;
}
if($sht(keepalive=>$si~$sp~$prid) != $null) {
return;
}
$var(max_slots) = $sel(cfg_get.kazoo.keepalive_interval) * KEEPALIVE_S_TIMERS;
$var(slot) = $(subs(contact){s.corehash, $var(max_slots)});
$var(alias) = $(subs(contact){uri.param,alias});
$var(sql) = $_s(INSERT OR IGNORE INTO keepalive (contact, received, sockinfo, slot) values("$subs(contact)", "$var(alias)", "$subs(sockinfo)", $var(slot)));
mq_add("keepalive_db_queue", "keepalive:from_subscription", "$var(sql)");
}
route[KEEPALIVE_ON_EXPIRED_REGISTRATION]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($sel(cfg_get.kazoo.keepalive_expired_registration_action) == 2) {
## disable
$var(Query) = $_s(UPDATE keepalive SET SELECTED = 10 where selected < 3 and contact like "$ulc(exp=>addr)%");
mq_add("keepalive_db_queue", "keepalive:disabled_from_expired_registration", "$var(Query)");
} else if($sel(cfg_get.kazoo.keepalive_expired_registration_action) == 1) {
## delete - will be recreated on registration with same contact
$var(Query) = $_s(DELETE FROM keepalive where selected < 3 and contact like "$ulc(exp=>addr)%");
mq_add("keepalive_db_queue", "keepalive:removed_from_expired_registration", "$var(Query)");
}
}
route[KEEPALIVE_ON_OPTIONS]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($shtinc(keepalive=>$si~$sp~$prid) == 1) {
$var(Query) = $_s(UPDATE keepalive set selected = 3 where received = "$si~$sp~$prid" and selected <> 3 );
mq_add("keepalive_db_queue", "keepalive:client_options", "$var(Query)");
}
}
route[KEEPALIVE_ON_NOTIFY]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($shtinc(keepalive=>$si~$sp~$prid) == 1) {
$var(Query) = $_s(UPDATE keepalive set selected = 4 where received = "$si~$sp~$prid" and selected <> 4 );
mq_add("keepalive_db_queue", "keepalive:client_notify", "$var(Query)");
}
}

+ 156
- 0
kamailio-proxy-blf/local.cfg View File

@ -0,0 +1,156 @@
################################################################################
## ROLES
################################################################################
## Enabled Roles
# # #!trydef DISPATCHER_ROLE
#!trydef NAT_TRAVERSAL_ROLE
#!trydef REGISTRAR_ROLE
#!trydef PRESENCE_ROLE
#!trydef RESPONDER_ROLE
#!trydef NODES_ROLE
## Disabled Roles - remove all but the last '#' to enable
# # #!trydef TRAFFIC_FILTER_ROLE
# # #!trydef WEBSOCKETS_ROLE
# # #!trydef TLS_ROLE
# # #!trydef ANTIFLOOD_ROLE
# # #!trydef RATE_LIMITER_ROLE
# # #!trydef ACL_ROLE
# # #!trydef MESSAGE_ROLE
# # #!trydef PUSHER_ROLE
# # #!trydef REGISTRAR_SYNC_ROLE
# # #!trydef PRESENCE_NOTIFY_SYNC_ROLE
# # #!trydef SIP_TRACE_ROLE
################################################################################
## SERVER INFORMATION
################################################################################
## UNCOMMENT & CHANGE "kamailio.2600hz.com" TO YOUR SERVERS HOSTNAME
# # #!substdef "!MY_HOSTNAME!kamailio.2600hz.com!g"
## UNCOMMENT & CHANGE "127.0.0.1" TO YOUR SERVERS IP ADDRESS
## Usually your public IP. If you need
## to listen on addtional ports or IPs
## add them in "BINDINGS" at the bottom.
# # #!substdef "!MY_IP_ADDRESS!127.0.0.1!g"
## CHANGE "kazoo://guest:guest@127.0.0.1:5672" TO THE AMQP URL
## This should be the primary RabbitMQ server
## in the zone that this server will service.
# # #!substdef "!MY_AMQP_URL!amqp://guest:guest@127.0.0.1:5672!g"
################################################################################
## WEBSOCKETS
################################################################################
##
## These parameters are only required if you are using websockets
##
## MY_WEBSOCKET_DOMAIN
## This value must be present in the HTTP
## Origin header on a new websocket request
## or it will be rejected. default value is
## domain of this server.
## #!substdef "!MY_WEBSOCKET_DOMAIN!2600hz.com!g"
##
## WEBSOCKET_NO_ORIGIN_RESTRICTION
## if defined, it will disable the origin validation.
##
## #!trydef WEBSOCKET_NO_ORIGIN_RESTRICTION
##
################################################################################
## DATABASE
################################################################################
## This parameter is OPTIONAL
## If you would like to use an external database
## remove all but the last '#' and configure the connector
## accordingly. The example shows how to use postgres.
## See the kamailio documentation for more details.
#!trydef KZ_DB_MODULE postgres
#!substdef "!KAMAILIO_DBMS!postgres!g"
#!substdef "!KAZOO_DB_URL!postgres://kamailio:kamailio@127.0.0.1/kamailio!g"
################################################################################
## UDP PARAMETERS
################################################################################
## This parameter is OPTIONAL
## If large UDP packets are dropped by the
## interface try uncommenting this option.
## However, you MUST match this to your
## network adapter! If they do not match,
## all UDP packets over this limit WILL FAIL!
## E.g.: Add MTU=1472 to the /etc/sysconfig/network-scripts/XXX
# udp4_raw_mtu = 1472
################################################################################
## BINDINGS
################################################################################
## This parameter is OPTIONAL.
## when set to 1,
## It will try to locate outbound interface
## on multihomed host. By default forward
## requests use the incoming socket disregarding
## the destination location. When enabled Kamailio
## will select a socket that can reach the
## destination. This reduces performance.
##!define KZ_MULTI_HOMED 1
################################################################################
## KZ_DISABLE_REGISTRAR_PORTS
################################################################################
## This parameter is OPTIONAL.
## It will disable publishing single proxy port on registrar success messages
## By default single port proxy is send on registrar success messages
## for websockets/tls protocols. the default port is 7000
## which enables config less in freeswitch for handling webrtc/tls
## ie, no certs in freeswitch, no webrtc/tls listeners on freeswitch
## by disabling single port proxy, ecallmgr needs to be started with
## 'use_transport_for_fs_path' set to true in its environment configuration
##
###!define KZ_DISABLE_WEBSOCKETS_REGISTRAR_PORT 1
###!define KZ_DISABLE_TLS_REGISTRAR_PORT 1
##
## you can also change the ports used for single port redirect
##!define KZ_WEBSOCKETS_REGISTRAR_PORT 5060
##!define KZ_TLS_REGISTRAR_PORT 5060
##
## also available for udp/tcp if it works for you
##!define KZ_UDP_REGISTRAR_PORT 7000
##!define KZ_TCP_REGISTRAR_PORT 7000
################################################################################
## SIP traffic mirroring to SIP_TRACE server
################################################################################
## This parameter is OPTIONAL.
## If you have installed SIP_TRACE server (Homer as example),
## then you can mirror INVITE and MESSAGE here
# # #!define SIP_TRACE_URI "sip:127.0.0.1:9060"
# # #!define HEP_CAPTURE_ID 1
## YOU SHOULD NOT HAVE TO CHANGE THESE!
## By setting MY_IP_ADDRESS above these will resolve
## to the proper bindings. These are here
## for those with complex layouts who know
## what they are doing :)
#!substdef "!UDP_SIP!udp:MY_IP_ADDRESS:5060!g"
#!substdef "!TCP_SIP!tcp:MY_IP_ADDRESS:5060!g"
#!substdef "!TLS_SIP!tls:MY_IP_ADDRESS:5061!g"
#!substdef "!UDP_ALG_SIP!udp:MY_IP_ADDRESS:7000!g"
#!substdef "!TCP_ALG_SIP!tcp:MY_IP_ADDRESS:7000!g"
#!substdef "!TLS_ALG_SIP!tls:MY_IP_ADDRESS:7001!g"
#!substdef "!TCP_WS!tcp:MY_IP_ADDRESS:5064!g"
#!substdef "!UDP_WS_SIP!udp:MY_IP_ADDRESS:5064!g"
#!substdef "!TLS_WSS!tls:MY_IP_ADDRESS:5065!g"
#!substdef "!UDP_WSS_SIP!udp:MY_IP_ADDRESS:5065!g"
## YOU SHOULD NOT HAVE TO CHANGE THESE!
## This will bind the default SIP listeners
## as determined above. The tls-role and
## websocket-role will use the appropriate
## definitions if enabled. These are here
## for those with complex layouts who know
## what they are doing :)
listen=UDP_SIP
listen=TCP_SIP
listen=UDP_ALG_SIP
listen=TCP_ALG_SIP

+ 102
- 0
kamailio-proxy-blf/message-role.cfg View File

@ -0,0 +1,102 @@
route[HANDLE_MESSAGE]
{
if (!is_method("MESSAGE")) return;
if (isflagset(FLAG_INTERNALLY_SOURCED) || src_ip == myself) return;
xlog("L_INFO", "$ci|log|MESSAGE from $fu to $tu\n");
route(AUTH);
$xavp(regcfg=>match_received) = $su;
if($avp(is_registered) != "true") {
sl_send_reply("403", "Forbidden");
exit;
} else {
if($hdr(Content-Type) =~ "text/plain" ||
$hdr(Content-Type) =~ "text/html") {
route(MESSAGE_INBOUND);
} else {
xlog("L_WARN", "$ci|end|dropping MESSAGE $hdr(Content-Type)\n");
sl_send_reply("200", "OK");
exit;
}
}
}
route[MESSAGE_INBOUND]
{
$var(key) = "kamailio@MY_HOSTNAME";
route(AUTH_HEADERS_JSON);
$var(Payload) = $_s({"Event-Category" : "sms", "Event-Name" : "inbound", "Call-ID" : "$ci", "Message-ID" : "$ci", "Route-Type" : "onnet", "Route-ID" : "$(var(key){kz.encode})", "From" : "$fU", "To" : "$tU", "Body" : "$rb", "Custom-SIP-Headers" : $var(headers_json), "Msg-ID" : "$uuid(g)"});
$var(exchange) = "im";
$var(RoutingKey) = $_s(sms.inbound.onnet.$(ci{kz.encode}));
xlog("L_INFO", "$ci|msg|sending inbound message $var(RoutingKey) => $var(Payload)\n");
kazoo_publish($var(exchange), $var(RoutingKey), $var(Payload));
sl_send_reply("200", "OK");
exit;
}
event_route[kazoo:consumer-event-sms-outbound]
{
xlog("L_INFO", "$(kzE{kz.json,Message-ID})|log|received message outbound for $(kzE{kz.json,Endpoints[0].To-DID})\n");
$var(from_uri) = $_s(sip:$(kzE{kz.json,From})@$(kzE{kz.json,Custom-Vars.Realm}));
$var(to_uri) = $_s(sip:$(kzE{kz.json,Endpoints[0].To-Username})@$(kzE{kz.json,Endpoints[0].To-Realm}));
$uac_req(method)="MESSAGE";
$uac_req(body)= $kzE;
$uac_req(hdrs)="X-TM-Local: MESSAGE_ROUTE\r\nX-KAZOO-AOR: " + $var(to_uri)+ "\r\nContent-Type: text/plain\r\n";
$uac_req(turi) = $var(to_uri);
$uac_req(ruri) = $var(to_uri);
$uac_req(furi) = $var(from_uri);
$uac_req(ouri) = "sip:127.0.0.1:5090;transport=tcp";
$uac_req(callid) = $(kzE{kz.json,Message-ID});
xlog("L_INFO", "$(kzE{kz.json,Message-ID})|log|sending message from $var(from_uri) to $var(to_uri) \n");
uac_req_send();
}
route[MESSAGE_ROUTE]
{
remove_hf_re("^X-");
route(ROUTE_TO_AOR);
$var(JObj) = $rb;
set_body("$(var(JObj){kz.json,Body})", "text/plain");
$avp(message_id) = $(var(JObj){kz.json,Message-ID});
$avp(msg_id) = $(var(JObj){kz.json,Msg-ID});
$avp(server_id) = $(var(JObj){kz.json,Server-ID});
t_on_reply("MESSAGE_REPLY");
t_on_failure("MESSAGE_FAULT");
t_relay();
}
onreply_route[MESSAGE_REPLY]
{
if($T_reply_code < 300) {
xlog("L_INFO", "$ci|log|sending success delivery message to $avp(server_id)\n");
$var(Payload) = $_s({"Event-Category" : "message", "Event-Name" : "delivery", "Call-ID" : "$ci", "Message-ID" : "$avp(message_id)" , "Delivery-Result-Code" : "sip:$T_reply_code", "Msg-ID" : "$avp(msg_id)" , "Status" : "delivered"});
$var(exchange) = "targeted";
$var(RK) = $avp(server_id);
kazoo_publish($var(exchange), $var(RK), $var(Payload));
}
}
failure_route[MESSAGE_FAULT]
{
xlog("L_INFO", "$ci|log|sending failure delivery message to $avp(server_id)\n");
$var(Payload) = $_s({"Event-Category" : "message", "Event-Name" : "delivery", "Call-ID" : "$ci", "Message-ID" : "$avp(message_id)" , "Delivery-Result-Code" : "sip:$T_reply_code", "Msg-ID" : "$avp(msg_id)" , "Status" : "failure"});
$var(exchange) = "targeted";
$var(RK) = $avp(server_id);
kazoo_publish($var(exchange), $var(RK), $var(Payload));
}
route[MESSAGE_BINDINGS]
{
$var(key) = "kamailio@MY_HOSTNAME";
$var(payload) = $_s({"name": "sms", "exchange": "im", "type": "topic", "queue": "MSG-QUEUE-MY_HOSTNAME", "routing": "sms.outbound.$(var(key){kz.encode}).*", "no_ack": false, "federate": true });
kazoo_subscribe("$var(payload)");
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 116
- 0
kamailio-proxy-blf/nat-traversal-role.cfg View File

@ -0,0 +1,116 @@
######## NAT Traversal module - signaling functions ########
#!ifndef NATHELPER_LOADED
loadmodule "nathelper.so"
#!trydef NATHELPER_LOADED
#!endif
modparam("nathelper", "received_avp", "$avp(AVP_RECV_PARAM)")
modparam("nathelper", "sipping_from", "sip:registrar@MY_HOSTNAME")
#!ifdef WEBSOCKETS_ROLE
#!trydef KZ_NAT_DETECT 83
#!else
#!trydef KZ_NAT_DETECT 19
#!endif
#!trydef KZ_NAT_FIX_SDP_REQUEST 1
#!trydef KZ_NAT_FIX_SDP_REPLY 1
#!trydef KZ_NAT_SDP_TEST 8
#!trydef KZ_NAT_SDP_FIX 10
kazoo.nat_fix_sdp_request = KZ_NAT_FIX_SDP_REQUEST descr "performs request sdp replacement of private addresses"
kazoo.nat_fix_sdp_reply = KZ_NAT_FIX_SDP_REPLY descr "performs reply sdp replacement of private addresses"
####### NAT Traversal Logic ########
route[NAT_SDP]
{
if( has_body("application/sdp")) {
if( nat_uac_test(KZ_NAT_SDP_TEST)) {
xlog("L_DEBUG", "$ci|log|applying sdp nat fix\n");
$var(ret) = fix_nated_sdp(KZ_NAT_SDP_FIX);
xlog("L_DEBUG", "$ci|log|result of applying sdp nat fix is $var(ret)\n");
} else if( is_method("INVITE") && !isflagset(FLAG_INTERNALLY_SOURCED) && is_audio_on_hold()) {
xlog("L_DEBUG", "$ci|log|applying sdp nat fix for held channel\n");
$var(ret) = fix_nated_sdp(KZ_NAT_SDP_FIX);
xlog("L_DEBUG", "$ci|log|result of applying sdp nat fix for held channel is $var(ret)\n");
}
}
}
route[NAT_DETECT]
{
if($sel(cfg_get.kazoo.nat_fix_sdp_request) == 1) {
route(NAT_SDP);
}
if ($Rp == "5080") {
setflag(FLAG_SKIP_NAT_CORRECTION);
xlog("L_DEBUG", "$ci|log|skipping nat correction on PORT 5080\n");
} else {
if (is_present_hf("Record-Route")) {
$var(i) = 0;
$var(rr_count) = $rr_count;
while($var(i) < $var(rr_count)) {
$var(rr_base) = $(hdr(Record-Route)[$var(i)]);
$var(rr_idx) = 0;
$var(rr) = $(var(rr_base){s.select,$var(rr_idx),,});
while($var(rr) != $null && $var(rr) != "") {
$var(i) = $var(i) + 1;
if (!is_myself("$(var(rr){nameaddr.uri})")) {
setflag(FLAG_SKIP_NAT_CORRECTION);
xlog("L_DEBUG", "$ci|log|skipping nat correction on record-route $(var(rr){nameaddr.uri})\n");
}
$var(rr_idx) = $var(rr_idx) + 1;
$var(rr) = $(var(rr_base){s.select,$var(rr_idx),,});
}
}
}
}
if (isflagset(FLAG_SKIP_NAT_CORRECTION)) {
xlog("L_DEBUG", "$ci|log|skipping nat detection\n");
return;
}
force_rport();
if(nat_uac_test(KZ_NAT_DETECT)) {
xlog("L_DEBUG", "$ci|log|detected nat request\n");
setflag(FLT_NATS);
if (!is_method("REGISTER")) {
if(is_first_hop()) set_contact_alias();
}
}
}
route[NAT_MANAGE]
{
if( is_reply() && $sel(cfg_get.kazoo.nat_fix_sdp_reply) == 1) {
route(NAT_SDP);
}
if ( is_request() && isflagset(FLAG_INTERNALLY_SOURCED)) {
setbflag(FLB_NATB);
}
if ( is_request() && has_totag() ) {
setbflag(FLB_NATB);
}
if (!(isflagset(FLT_NATS) || isbflagset(FLB_NATB))) {
return;
}
if (is_reply()) {
if(isflagset(FLT_NATS) || isbflagset(FLB_NATB)) {
if(is_first_hop()) {
set_contact_alias();
}
}
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

kamailio/nodes-role.cfg → kamailio-proxy-blf/nodes-role.cfg View File


kamailio/fast-pickup-role.cfg → kamailio-proxy-blf/presence-fast-pickup.cfg View File


+ 213
- 0
kamailio-proxy-blf/presence-notify.cfg View File

@ -0,0 +1,213 @@
#!trydef KZ_PRESENCE_REMOVE_WATCHER_ON_EXPIRED_REGISTRATION 0
#!trydef KZ_PRESENCE_MAX_NOTIFY_ERROR 3
#!trydef KZ_PRESENCE_NOTIFY_LOG_LEVEL 4
kazoo.presence_notify = 1 descr "enable/disable sending notify callback to omnipresence"
kazoo.presence_notify_timeout = 5000 descr "timeout in ms waiting for notify reply"
kazoo.presence_notify_log_body = 0 descr "logs the body sent in the notification"
kazoo.presence_notify_log_resp_body = 0 descr "logs the body received from notification"
kazoo.presence_notify_log_to_table = 1 descr "logs notify/reply to active_watchers_log table"
kazoo.presence_notify_log_to_amqp = 0 descr "logs notify/reply to amqp"
kazoo.presence_notify_record_route = 1 descr "add record route header to notify msg sent"
kazoo.presence_notify_log_init_body = 0 descr "logs the body before its sent"
kazoo.presence_notify_force_send_socket = 1 descr "forces the send socket to the contact"
kazoo.presence_remove_watcher_on_expired_registration = KZ_PRESENCE_REMOVE_WATCHER_ON_EXPIRED_REGISTRATION descr "removes watcher on expired registration"
kazoo.presence_max_notify_error = KZ_PRESENCE_MAX_NOTIFY_ERROR descr "number of consecutive fails allowed before removing the subscription"
kazoo.presence_notify_log_level = KZ_PRESENCE_NOTIFY_LOG_LEVEL descr "loglevel for informational log messages"
######## Generic Hash Table container in shared memory ########
modparam("htable", "htable", "notify=>size=16;autoexpire=3600;updateexpire=1;initval=0")
route[PRESENCE_LOCAL_REQ_NOTIFY]
{
if($rm != "NOTIFY") {
return;
}
t_set_fr($sel(cfg_get.kazoo.presence_notify_timeout), $sel(cfg_get.kazoo.presence_notify_timeout));
xlog("L_DEBUG", "$ci|log|init preparing $subs(event) notify to $subs(watcher_username)@$subs(watcher_domain) on behalf of $subs(pres_uri) : $du\n");
if($sel(cfg_get.kazoo.presence_notify_log_init_body) == 1) {
xlog("L_INFO", "$ci|log|init|body $(mb{s.escape.common}{s.replace,\','}{s.replace,$$,})\n");
}
if($sel(cfg_get.kazoo.presence_notify_force_send_socket) == 1) {
$fs = $_s($(pr{s.tolower}):$(hdr(Contact){nameaddr.uri}{uri.host}):$(hdr(Contact){nameaddr.uri}{uri.port}));
xlog("L_DEBUG", "$ci|log|init|forcing socket to $fs, $(pr{s.tolower}):$(hdr(Contact){nameaddr.uri}{uri.host}):$(hdr(Contact){nameaddr.uri}{uri.port}) , $ct\n");
}
if($sel(cfg_get.kazoo.presence_notify_record_route) == 1) {
record_route();
}
#!ifdef NAT_TRAVERSAL_ROLE
if(!isdsturiset()) {
handle_ruri_alias();
}
#!endif
}
modparam("mqueue","mqueue", "name=presence_last_notity")
modparam("rtimer", "timer", "name=notifytimer;interval=1;mode=1;")
modparam("rtimer", "exec", "timer=notifytimer;route=PRESENCE_LOG_TIMER_ROUTE")
modparam("rtimer", "timer", "name=pres_cleanup;interval=10;mode=1;")
modparam("rtimer", "exec", "timer=pres_cleanup;route=PRESENCE_CLEANUP")
modparam("rtimer", "timer", "name=pres_publisher_cleanup;interval=5;mode=1;")
modparam("rtimer", "exec", "timer=pres_publisher_cleanup;route=PRESENCE_PUBLISHER_CLEANUP")
event_route[presence:notify-reply]
{
if($sel(cfg_get.kazoo.presence_notify) != 1)
return;
$xavp(pres=>delete_subscription) = 0;
if($notify_reply($rs) == 200) {
$sht(notify=>$ci) = $null;
$sht(notify=>$ci::count) = 0;
xlog("$(sel(cfg_get.kazoo.presence_notify_log_level){s.int})", "$ci|end|notified $subs(watcher_username)@$subs(watcher_domain) on behalf of $subs(pres_uri)\n");
} else if($subs(reason) == "timeout") {
$xavp(pres=>delete_subscription) = 1;
xlog("L_DEBUG", "$ci|end|deleting subscription $subs(pres_uri) for $subs(watcher_username)@$subs(watcher_domain) due to timeout\n");
} else if($notify_reply($rs) == 481 && $subs(reason) == "timeout") {
xlog("L_DEBUG","$ci|end|sent subscription $hdr(Subscription-State)\n");
} else if($notify_reply($rs) == 408) {
if($rP != "UDP") {
$xavp(pres=>delete_subscription) = 1;
xlog("L_ERROR", "$ci|warning|removing $rP watcher $subs(watcher_username)@$subs(watcher_domain) for $subs(pres_uri) with reply $notify_reply($rs)\n");
} else {
$var(shtinc) = $shtinc(notify=>$ci::count);
if($var(shtinc) > $sel(cfg_get.kazoo.presence_max_notify_error)) {
$xavp(pres=>delete_subscription) = 1;
xlog("L_WARNING", "$ci|error|removing $rP watcher $subs(watcher_username)@$subs(watcher_domain) for $subs(pres_uri) with reply $notify_reply($rs)\n");
} else {
$var(level) = 6 - $var(shtinc);
xlog("$var(level)", "$ci|error|received $notify_reply($rs) ($var(shtinc)/$sel(cfg_get.kazoo.presence_max_notify_error)) when notifying $subs(watcher_username)@$subs(watcher_domain) on behalf of $subs(pres_uri) with reply $notify_reply($rs)\n");
}
}
} else {
$xavp(pres=>delete_subscription) = 1;
xlog("L_WARNING", "$ci|end|deleting subscription $subs(pres_uri) as $subs(watcher_username)@$subs(watcher_domain) replied with $notify_reply($rs)\n");
}
if($sel(cfg_get.kazoo.presence_notify_log_body) == 1)
xlog("L_INFO", "$ci|log|sent|body $(mb{s.escape.common}{s.replace,\','}{s.replace,$$,})\n");
if($sel(cfg_get.kazoo.presence_notify_log_resp_body) == 1)
xlog("L_INFO", "$ci|log|resp|body $(notify_reply($mb){s.escape.common}{s.replace,\','}{s.replace,$$,})\n");
if($sel(cfg_get.kazoo.presence_notify_log_to_amqp) == 1) {
route(PRESENCE_NOTIFY_AMQP);
}
if($sel(cfg_get.kazoo.presence_notify_log_to_table) == 1) {
if($xavp(pres=>delete_subscription) != 1 && $subs(reason) != "timeout") {
$var(Query) = $_s(KZQ_REPLACE_WATCHERS_LOG);
mq_add("presence_last_notity", "$subs(callid)", "$var(Query)");
}
}
}
route[PRESENCE_LOG_TIMER_ROUTE]
{
$var(runloop) = 1;
while(mq_fetch("presence_last_notity") == 1 && $var(runloop) < MAX_WHILE_LOOPS) {
$var(ci) = $mqk(presence_last_notity);
xlog("L_DEBUG", "Query : $mqv(presence_last_notity)\n");
$var(sqlres) = sql_query("cb", "$mqv(presence_last_notity)");
xlog("L_DEBUG", "Query result : $var(sqlres)\n");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$var(ci)|log|error running query : $mqv(presence_last_notity)\n");
} else {
$var(nrows) = $sqlrows(cb);
xlog("L_DEBUG", "$var(ci)|log|end UPDATED $var(nrows)\n");
if($var(nrows) == 0) {
xlog("L_DEBUG", "$var(ci)|log|error no rows affected when running query\n");
}
}
$var(runloop) = $var(runloop) + 1;
}
}
route[PRESENCE_NOTIFY_AMQP]
{
$var(amqp_payload_request) = $_s({"Event-Category" : "presence", "Event-Name" : "notify", "Event-Package" : "$subs(event)", "Timestamp" : $TS, "Call-ID" : "$subs(callid)", "From" : "$fu", "To" : "$subs(to_user)@$subs(to_domain)", "Sent" : "$(TS{s.ftime,%Y-%m-%d %H:%M:%S})", "Body" : "Hostname : MY_HOSTNAME\r\nTimestamp : $(TS{s.ftime,%Y-%m-%d %H:%M:%S})\r\n$(mb{s.escape.common}{s.replace,\','}{s.replace,$$,})\r\nResponse\r\n$(notify_reply($mb){s.escape.common}{s.replace,\','}{s.replace,$$,})","Remote-CSeq" : $subs(remote_cseq), "Local-CSeq" : $subs(local_cseq), "Sequence" : $cs, "Version" : $subs(version), "Reply" : $notify_reply($rs) });
$var(rk) = "notify." + $(subs(to_domain){kz.encode}) + "." + $(subs(to_user){kz.encode});
kazoo_publish("omnipresence", "$var(rk)", $var(amqp_payload_request));
xlog("L_INFO", "$ci|log|sent notify callback for event $subs(event) : $tu\n");
}
route[PRESENCE_CLEANUP]
{
$var(Query) = $_s(KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_EXPIRES;);
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
$var(Query) = $_s(KZQ_DELETE_FROM_PRESENTITY_WHERE_EXPIRES;);
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
$var(Query) = $_s(KZQ_DELETE_FROM_PRESENTITY_WHERE_DIALOG_TERMINATED;);
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
$var(Query) = $_s(DELETE FROM ACTIVE_WATCHERS_LOG WHERE ID IN(select id from active_watchers_log a where not exists(select callid from active_watchers b where b.callid = a.callid and b.watcher_username = a.watcher_username and b.watcher_domain = a.watcher_domain)););
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
}
route[PRESENCE_PUBLISHER_CLEANUP]
{
xlog("L_DEBUG", "processing presence publisher cleanup\n");
$var(sqlres) = sql_query("cb", "update tmp_probe set action = 1 where action = 0");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$var(ci)|log|error cleaning tmp_probe\n");
return;
} else {
$var(nrows) = $sqlrows(cb);
if($var(nrows) > 0) {
if (sql_xquery("cb", "select * from tmp_probe where action = 1", "cleanup_pres") == 1)
{
while($xavp(cleanup_pres) != $null) {
xlog("L_DEBUG", "processing $xavp(cleanup_pres=>event) notifies for $xavp(cleanup_pres=>presentity_uri)\n");
pres_refresh_watchers("$xavp(cleanup_pres=>presentity_uri)", "$xavp(cleanup_pres=>event)", 1);
pv_unset("$xavp(cleanup_pres)");
}
}
$var(sqlres) = sql_query("cb", "delete from tmp_probe where action = 1");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$var(ci)|log|error cleaning tmp_probe\n");
} else {
$var(nrows) = $sqlrows(cb);
if($var(nrows) > 0) {
xlog("L_DEBUG", "presence publisher cleanup processed $var(nrows) rows\n");
}
}
}
}
}
route[PRESENCE_DEFERRED_INIT]
{
xlog("L_INFO", "processing presence deferred init\n");
$var(sqlres) = sql_query("cb", "update tmp_probe set action = 0 where action = 2");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$var(ci)|log|error cleaning tmp_probe\n");
return;
} else {
$var(nrows) = $sqlrows(cb);
if($var(nrows) > 0) {
xlog("L_NOTICE", "scheduled update for $var(nrows) watched presentities/event\n");
}
}
}
route[PRESENCE_EXPIRED_REGISTRATION]
{
if($sel(cfg_get.kazoo.presence_remove_watcher_on_expired_registration) == 1) {
$var(watcher) = $_s(sip:$ulc(exp=>aor));
$var(watcher_username) = $(var(watcher){uri.user});
$var(watcher_domain) = $(var(watcher){uri.host});
$var(Query) = $_s(DELETE FROM active_watchers WHERE watcher_username = "$var(watcher_username)" and watcher_domain = "$var(watcher_domain)";);
mq_add("presence_last_notity", "$uuid(g)", "$var(Query)");
}
}

kamailio/presence_query-role.cfg → kamailio-proxy-blf/presence-query.cfg View File


kamailio/presence-reset.cfg → kamailio-proxy-blf/presence-reset.cfg View File


+ 585
- 0
kamailio-proxy-blf/presence-role.cfg View File

@ -0,0 +1,585 @@
######## Presence server module ########
#!trydef PRESENCE_MIN_EXPIRES 300
#!trydef PRESENCE_MIN_EXPIRES_ACTION 1
#!trydef PRESENCE_MAX_EXPIRES 3600
#!trydef KZ_PRESENCE_IGNORE_STATUS_PROBE_RESP 1
#!trydef KZ_PRESENCE_CSEQ_OFFSET 2
#!trydef KZ_PRESENCE_MAX_CALL_PER_PRESENTITY 20
#!trydef BLF_USE_SINGLE_DIALOG 1
#!trydef KZ_PRESENCE_AMQP_PUBLISH 0
#!trydef KZ_PRESENCE_REQUEST_RESUBSCRIBE_PROBE 0
#!trydef KZ_PRESENCE_REQUEST_PROBE 1
#!trydef KZ_PRESENCE_NO_TARGETS_LOG_LEVEL L_DBG
#!trydef KZ_PRESENCE_WITH_TARGETS_LOG_LEVEL L_INFO
#!trydef KZ_PRESENCE_REQUIRE_AUTHN 0
#!trydef KZ_PRESENCE_KEEPALIVE_NAT_ONLY 1
#!trydef KZ_PRESENCE_KEEPALIVE_UDP_ONLY 1
#!ifdef NAT_TRAVERSAL_ROLE
#!ifndef KEEPALIVE_ROLE
#!ifndef NAT_TRAVERSAL_LOADED
#!trydef NAT_TRAVERSAL_LOADED
loadmodule "nat_traversal.so"
#!endif
modparam("nat_traversal", "keepalive_method", "OPTIONS")
modparam("nat_traversal", "keepalive_from", "sip:sipcheck@MY_HOSTNAME")
modparam("nat_traversal", "keepalive_state_file", "KAZOO_DATA_DIR/keep_alive_state")
modparam("nat_traversal", "keepalive_interval", 45)
#!endif
#!endif
modparam("htable", "htable", "first=>size=32;autoexpire=3600;initval=0;")
loadmodule "presence.so"
loadmodule "presence_dialoginfo.so"
loadmodule "presence_mwi.so"
loadmodule "presence_xml.so"
modparam("presence_dialoginfo", "force_dummy_dialog", 1)
modparam("presence_dialoginfo", "force_single_dialog", BLF_USE_SINGLE_DIALOG)
modparam("presence_xml", "force_dummy_presence", 1)
modparam("presence_xml", "force_active", 1)
modparam("presence_xml", "disable_winfo", 1)
modparam("presence_xml", "disable_bla", 1)
modparam("presence", "subs_db_mode", 3)
modparam("presence", "expires_offset", 0)
modparam("presence", "send_fast_notify", 0)
modparam("presence", "clean_period", 0)
modparam("presence", "db_update_period", 0)
modparam("presence", "publ_cache", 0)
modparam("presence", "min_expires_action", PRESENCE_MIN_EXPIRES_ACTION)
modparam("presence", "min_expires", PRESENCE_MIN_EXPIRES)
modparam("presence", "max_expires", PRESENCE_MAX_EXPIRES)
modparam("presence", "sip_uri_match", 1)
modparam("presence", "waitn_time", 1)
modparam("presence", "notifier_processes", 1)
modparam("presence", "db_url", "KAZOO_DB_URL")
modparam("presence", "xavp_cfg", "pres")
modparam("presence", "local_log_level", 6)
modparam("presence", "startup_mode", 0)
modparam("presence", "force_delete", 1)
modparam("presence", "timeout_rm_subs", 0)
modparam("presence", "cseq_offset", KZ_PRESENCE_CSEQ_OFFSET)
modparam("kazoo", "db_url", "KAZOO_DB_URL")
modparam("kazoo", "pua_mode", 1)
kazoo.presence_sync_amqp = KZ_PRESENCE_AMQP_PUBLISH descr "sync subscriptions to amqp"
kazoo.presence_request_probe = KZ_PRESENCE_REQUEST_PROBE descr "request probe for new subscriptions"
kazoo.presence_request_resubscribe_probe = KZ_PRESENCE_REQUEST_RESUBSCRIBE_PROBE descr "request probe for resubscriptions"
kazoo.presence_ignore_status_probe_resp = KZ_PRESENCE_IGNORE_STATUS_PROBE_RESP descr "ignore online/offline probe replies"
kazoo.presence_max_call_per_presentity = KZ_PRESENCE_MAX_CALL_PER_PRESENTITY descr "max number of calls per presentity"
kazoo.presence_no_targets_log_level = KZ_PRESENCE_NO_TARGETS_LOG_LEVEL descr "when a presence event is received and there no targets we can log at another level"
kazoo.presence_with_targets_log_level = KZ_PRESENCE_WITH_TARGETS_LOG_LEVEL descr "when a presence event is received and there are targets we can log at another level"
kazoo.presence_require_authn = KZ_PRESENCE_REQUIRE_AUTHN descr "require authenticated devices for presence"
kazoo.presence_keepalive_udp_only = KZ_PRESENCE_KEEPALIVE_UDP_ONLY descr "should we send keepalive for udp only"
kazoo.presence_keepalive_nat_only = KZ_PRESENCE_KEEPALIVE_NAT_ONLY descr "should we send keepalive for nat phones only"
#!include_file "presence-query.cfg"
#!include_file "presence-notify.cfg"
#!include_file "presence-reset.cfg"
#!include_file "presence-fast-pickup.cfg"
####### Presence Logic ########
route[PRESENCE_NAT]
{
if(!( ($sel(cfg_get.kazoo.presence_keepalive_udp_only) == 1 && $proto != "udp")
|| (!isflagset(FLT_NATS) && $sel(cfg_get.kazoo.presence_keepalive_nat_only) == 1)
|| ($proto == "ws" || $proto == "wss")
)) {
#!ifdef KEEPALIVE_ROLE
route(KEEPALIVE_ON_SUBSCRIBE);
#!else
nat_keepalive();
#!endif
}
}
route[HANDLE_SUBSCRIBE]
{
if (!is_method("SUBSCRIBE")) {
return;
}
if ($hdr(Event) != "dialog"
&& $hdr(Event) != "presence"
&& $hdr(Event) != "message-summary") {
xlog("L_INFO", "$ci|presence|subscribe event $hdr(Event) not supported\n");
send_reply(489, "Bad Event");
exit();
}
route(PRESENCE_AUTHN);
if (!t_newtran()) {
sl_reply_error();
exit;
}
if(has_totag()) {
loose_route();
}
record_route();
if(has_totag()) {
route(HANDLE_RESUBSCRIBE);
} else {
route(HANDLE_NEW_SUBSCRIBE);
}
t_release();
exit;
}
route[DELETE_DUPLICATED_SUBSCRIPTIONS]
{
sql_query("exec", 'KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_PRESENTITY');
}
route[HANDLE_RESUBSCRIBE]
{
if(handle_subscribe()) {
if($subs(remote_cseq) < 5) {
$sht(first=>$subs(callid)) = $null;
$sht(first=>$subs(from_user)::$subs(pres_uri)::$subs(from_domain)::$subs(event)) = $null;
}
route(DELETE_DUPLICATED_SUBSCRIPTIONS);
route(SUBSCRIBE_AMQP);
route(REQUEST_PROBE);
};
}
route[HANDLE_NEW_SUBSCRIBE]
{
if ($hdr(Event) == "dialog"
|| $hdr(Event) == "presence"
|| $hdr(Event) == "message-summary") {
if ($tU == $null) {
xlog("L_INFO", "$ci|stop|ignoring subscribe with empty TO username from a $ua\n");
send_reply(400, "Missing TO username");
return;
}
if ($fU == $null) {
xlog("L_INFO", "$ci|stop|ignoring subscribe with empty FROM username from a $ua\n");
send_reply(400, "Missing FROM username");
return;
}
if($shtinc(first=>$ci) > 1) {
sql_query("exec", 'KZQ_HANDLE_NEW_SUBSCRIBE_DELETE1');
xlog("L_INFO", "$ci|subscribe|resetting $hdr(Event) subscription from $fU to $tU in realm $fd : $sqlrows(exec)\n");
} else {
$var(presentity_uri) = $ru;
if($(var(presentity_uri){uri.user}) == "") {
$var(presentity_uri) = $tu;
}
if($shtinc(first=>$fU::$var(presentity_uri)::$fd::$hdr(Event)) > 1) {
sql_query("exec", 'KZQ_HANDLE_NEW_SUBSCRIBE_DELETE2');
xlog("L_INFO", "$ci|subscribe|resetting $hdr(Event) subscription from $fU to $var(presentity_uri) in realm $fd : $sqlrows(exec)\n");
}
}
if (handle_subscribe()) {
xlog("L_INFO","$ci|end|new $hdr(Event) subscription from $fU to $tU in realm $fd : $sht(first=>$ci) : $sht(first=>$fU::$tU::$fd::$hdr(Event))\n");
route(DELETE_DUPLICATED_SUBSCRIPTIONS);
route(SUBSCRIBE_AMQP);
route(REQUEST_PROBE);
#!ifdef NAT_TRAVERSAL_ROLE
route(PRESENCE_NAT);
#!endif
} else {
xlog("L_INFO", "$ci|stop|error $T_reply_code for new $hdr(Event) subscription from $fU to $tU in realm $fd\n");
}
} else {
xlog("L_INFO", "$ci|stop|unsupported subscription package $hdr(Event) from $fU to $tU in realm $fd\n");
send_reply(489, "Bad Event");
}
}
route[SUBSCRIBE_AMQP]
{
if($sel(cfg_get.kazoo.presence_sync_amqp) == 1) {
$var(rk) = "subscribe." + $(subs(to_domain){kz.encode}) + "." + $(subs(to_user){kz.encode});
$var(amqp_payload_request) = $_s({"Event-Category" : "presence", "Event-Name" : "subscription", "Event-Package" : "$hdr(event)", "Expires" : $subs(expires), "Queue" : "BLF-MY_HOSTNAME", "Server-ID" : "BLF-MY_HOSTNAME" , "Contact" : "$(ct{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Call-ID" : "$ci", "From" : "$fu", "User" : "$subs(uri)", "User-Agent" : "$(ua{s.escape.common}{s.replace,\','}{s.replace,$$,})" });
kazoo_publish("omnipresence", "$var(rk)", $var(amqp_payload_request));
}
}
route[REQUEST_PROBE]
{
if( ($sel(cfg_get.kazoo.presence_request_probe) == 1 && (!has_totag()))
|| ($sel(cfg_get.kazoo.presence_request_resubscribe_probe) == 1 && has_totag()) ) {
if( route(HAS_PRESENTITY) == 0) {
if($hdr(event) == "message-summary") {
$var(mwi) = $tU;
route(REQUEST_MWI);
} else {
if($tU =~ "\*98") {
$var(mwi) = $(tU{s.substr,3,0});
route(REQUEST_MWI);
} else {
xlog("L_INFO", "$ci|sub|requesting $hdr(Event) probe for $subs(to_user) in realm $subs(to_domain)\n");
$var(rk) = "probes." + $hdr(Event);
$var(amqp_payload_request) = $_s({"Event-Category" : "presence", "Event-Name" : "probe", "Event-Package" : "$hdr(event)", "Username" : "$tU", "Realm" : "$fd", "Call-ID" : "$ci"});
kazoo_publish("presence", "$var(rk)", $var(amqp_payload_request));
}
}
}
}
}
route[REQUEST_MWI]
{
xlog("L_INFO", "$ci|sub|requesting mwi probe for $var(mwi) in realm $subs(to_domain)\n");
$var(rk) = "mwi_queries." + $(subs(to_domain){kz.encode});
$var(amqp_payload_request) = $_s({"Event-Category" : "presence", "Event-Name" : "mwi_query", "Username" : "$var(mwi)", "Realm" : "$fd", "Call-ID" : "$ci"});
kazoo_publish("presence", "$var(rk)", $var(amqp_payload_request));
}
route[HANDLE_PUBLISH]
{
if(!is_method("PUBLISH")) {
return;
}
if ($hdr(Event) != "dialog"
&& $hdr(Event) != "presence"
&& $hdr(Event) != "message-summary") {
xlog("L_INFO", "$ci|presence|publish event $hdr(Event) not supported\n");
send_reply(489, "Bad Event");
exit();
}
route(PRESENCE_AUTHN);
if (!t_newtran()) {
sl_reply_error();
exit;
}
if($hdr(Sender)!= $null) {
handle_publish("$hdr(Sender)");
} else {
handle_publish();
}
t_release();
exit;
}
route[HAS_PRESENTITY]
{
$var(Query) = $_s(KZQ_HAS_PRESENTITY);
$var(res) = 0;
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
{
if($xavp(subs) != $null) {
$var(res) = $xavp(subs=>count);
pv_unset("$xavp(subs)");
}
}
return $var(res);
}
route[COUNT_PRESENTITIES]
{
$var(Query) = $_s(KZQ_COUNT_PRESENTITIES);
$var(p) = $_s(presence_id='$var(presentity)');
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
{
while($xavp(subs) != $null) {
$var(p) = $var(p) + ";" + $xavp(subs=>event) + "=" + $xavp(subs=>count);
pv_unset("$xavp(subs)");
}
}
xavp_params_explode($var(p), "watchers");
}
route[COUNT_ALL_PRESENTITIES]
{
$var(Query) = $_s(select event, (select count(*) from presentity b where b.event = a.event) count from event_list a);
$var(p) = "presence_id=none";
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
{
while($xavp(subs) != $null) {
$var(p) = $var(p) + ";" + $xavp(subs=>event) + "=" + $xavp(subs=>count);
pv_unset("$xavp(subs)");
}
}
xavp_params_explode($var(p), "watchers");
}
route[COUNT_ALL_SUBSCRIBERS]
{
$var(Query) = $_s(KZQ_COUNT_ALL_SUBSCRIBERS);
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
{
$var(sep) = "";
$var(Subscribers) = "";
$var(Subscriptions) = "";
while($xavp(subs) != $null) {
$var(Subscribers) = $var(Subscribers) + $var(sep) + $_s("$xavp(subs=>event)" : $xavp(subs=>count_unique));
$var(Subscriptions) = $var(Subscriptions) + $var(sep) + $_s("$xavp(subs=>event)" : $xavp(subs=>count));
$var(sep) = " , ";
pv_unset("$xavp(subs)");
}
}
}
route[COUNT_SUBSCRIBERS]
{
$var(Query) = $_s(KZQ_COUNT_SUBSCRIBERS);
$var(p) = $_s(presence_id='$var(presentity)');
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
{
while($xavp(subs) != $null) {
$var(p) = $var(p) + ";" + $xavp(subs=>event) + "=" + $xavp(subs=>count);
pv_unset("$xavp(subs)");
}
}
xavp_params_explode($var(p), "watchers");
}
event_route[kazoo:consumer-event-presence-dialog-update]
{
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_no_targets_log_level){s.int});
$var(StartRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_start) = $var(StartRoute) - $(kzE{kz.json,AMQP-Received});
xlog("L_DEBUG", "$(kzE{kz.json,Call-ID})|log|received $(kzE{kz.json,Event-Package}) update for $(kzE{kz.json,From}) state $(kzE{kz.json,State}) from $(kzE{kz.json,AMQP-Broker-Zone}) => $(kzE{kz.json,Switch-URI}) (Δ1 $(kzE{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs)\n");
$var(JObj) = $kzE;
route(PRESENCE_FAST_PICKUP_INIT);
$var(presentity) = $(kzE{kz.json,From});
$var(payload) = $kzE;
route(PRESENCE_UPDATE);
$var(EndRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_finish) = $var(EndRoute) - $var(StartRoute);
xlog("$var(kz_presence_log_level)", "$(kzE{kz.json,Call-ID})|log|$(kzE{kz.json,Event-Package}) update for $(kzE{kz.json,From}) state $(kzE{kz.json,State}) from $(kzE{kz.json,AMQP-Broker-Zone}) => $(kzE{kz.json,Switch-URI}) (Δ1 $(kzE{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs, Δ3 $var(delta_to_finish) μs)\n");
}
event_route[kazoo:consumer-event-presence-mwi-update]
{
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_no_targets_log_level){s.int});
$var(StartRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_start) = $var(StartRoute) - $(kzE{kz.json,AMQP-Received});
xlog("L_DBG", "$(kzE{kz.json,Call-ID})|log|received message-summary update for $(kzE{kz.json,From}) ($(kzE{kz.json,AMQP-Broker-Zone}))\n");
$var(presentity) = $(kzE{kz.json,From});
$var(payload) = $kzE;
route(COUNT_SUBSCRIBERS);
if($xavp(watchers=>message-summary) > 0) {
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_with_targets_log_level){s.int});
xlog("L_INFO", "$(kzE{kz.json,Call-ID})|log|publishing $(kzE{kz.json,From}) message-summary update for $xavp(watchers=>message-summary) watchers\n");
kazoo_pua_publish_mwi($kzE);
pres_refresh_watchers("$(kzE{kz.json,From})", "message-summary", 1);
} else {
#!ifdef PRESENCE_TRACK_ALL_PKG_MWI
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_with_targets_log_level){s.int});
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|saving $var(presentity) from mwi update => $var(payload)\n");
if(kazoo_pua_publish_mwi($kzE) != 1) {
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) mwi update => $var(payload)\n");
}
#!else
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|skip mwi update for $var(presentity)\n");
#!endif
}
route(MWI_AS_PRESENCE);
$var(mwi_state) = "ON";
if($(kzE{kz.json,Messages-Waiting}) == "no") {
$var(mwi_state) = "OFF";
}
$var(EndRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_finish) = $var(EndRoute) - $var(StartRoute);
xlog("$var(kz_presence_log_level)", "$(kzE{kz.json,Call-ID})|log|message-summary update for $(kzE{kz.json,From}) light should be $var(mwi_state) (Δ1 $(kzE{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs, Δ3 $var(delta_to_finish) μs)\n");
}
event_route[kazoo:consumer-event-presence-update]
{
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_no_targets_log_level){s.int});
$var(StartRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_start) = $var(StartRoute) - $(kzE{kz.json,AMQP-Received});
if($sel(cfg_get.kazoo.presence_ignore_status_probe_resp) == 1) {
if($(kzE{kz.json,State}) == "offline" || $(kzE{kz.json,State}) == "online") {
xlog("L_DEBUG", "$(kzE{kz.json,Call-ID})|log|ignoring $(kzE{kz.json,State}) state $(kzE{kz.json,Presence-ID})\n");
return;
}
}
xlog("L_DEBUG", "$(kzE{kz.json,Call-ID})|log|received presence update for $(kzE{kz.json,Presence-ID})");
$var(JObj) = $kzE;
$var(presentity) = $_s(sip:$(kzE{kz.json,Presence-ID}));
$var(payload) = $kzE;
route(PRESENCE_UPDATE);
$var(EndRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_finish) = $var(EndRoute) - $var(StartRoute);
xlog("$var(kz_presence_log_level)", "$(kzE{kz.json,Call-ID})|log|$(kzE{kz.json,Event-Package}) update for $(kzE{kz.json,From}) state $(kzE{kz.json,State}) from $(kzE{kz.json,AMQP-Broker-Zone}) => $(kzE{kz.json,Switch-URI}) (Δ1 $(kzE{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs, Δ3 $var(delta_to_finish) μs)\n");
}
route[PRESENCE_UPDATE]
{
$var(callid) = $(var(payload){kz.json,Call-ID});
if($(var(payload){kz.json,State}) == "terminated") {
route(COUNT_PRESENTITIES);
} else {
route(COUNT_SUBSCRIBERS);
}
if($xavp(watchers=>self) > $sel(cfg_get.kazoo.presence_max_call_per_presentity) &&
( $(var(payload){kz.json,State}) == "early" ||
($(var(payload){kz.json,State}) == "confirmed" && $(var(payload){kz.json,State}) == "initiator")
)) {
xlog("L_WARN", "$(var(payload){kz.json,Call-ID})|log|not publishing state $(var(payload){kz.json,State}) for presentity $var(presentity) with $xavp(watchers=>self) calls, policy limit of $sel(cfg_get.kazoo.presence_max_call_per_presentity) calls per presentity \n");
} else {
if($xavp(watchers=>dialog) > 0) {
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_with_targets_log_level){s.int});
if($(var(payload){kz.json,State}) == "terminated") {
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|publishing $var(presentity) dialog update for terminated dialog\n");
} else {
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|publishing $var(presentity) dialog update for $xavp(watchers=>dialog) watchers\n");
}
if(kazoo_pua_publish_dialoginfo($var(JObj)) == 1) {
pres_refresh_watchers("$var(presentity)", "dialog", 1);
} else {
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) dialog update\n");
};
} else {
#!ifdef PRESENCE_TRACK_ALL_PKG_DIALOG
if($(kzE{kz.json,Event-Package}) == "dialog") {
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_with_targets_log_level){s.int});
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|saving $var(presentity) from dialog update => $var(payload)\n");
if(kazoo_pua_publish_dialoginfo($var(JObj)) != 1) {
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) dialog update => $var(payload)\n");
}
}
#!else
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|skip dialog update for $var(presentity)\n");
#!endif
}
if($xavp(watchers=>presence) > 0) {
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_with_targets_log_level){s.int});
if($(var(payload){kz.json,State}) == "terminated") {
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|publishing $var(presentity) presence update for terminated dialog\n");
} else {
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|publishing $var(presentity) presence update for $xavp(watchers=>presence) watchers\n");
}
if(kazoo_pua_publish_presence($var(JObj)) == 1) {
pres_refresh_watchers("$var(presentity)", "presence", 1);
} else {
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) presence update\n");
};
} else {
#!ifdef PRESENCE_TRACK_ALL_PKG_PRESENCE
if($(kzE{kz.json,Event-Package}) == "presence") {
$var(kz_presence_log_level) = $(sel(cfg_get.kazoo.presence_with_targets_log_level){s.int});
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|saving $var(presentity) from presence update => $var(payload)\n");
if(kazoo_pua_publish_presence($var(JObj)) != 1) {
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) presence update => $var(payload)\n");
}
}
#!else
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|skip presence update for $var(presentity)\n");
#!endif
}
}
}
#!define MWI_PRESENCE_BODY $(kzE{re.subst,/"Messages-Waiting"\s*\:\s*"[^"]*"/"State" : "$var(State)"/} \
{re.subst,/"From"\s*\:\s*"[^"]*"/"From" : "$var(presentity)"/} \
{re.subst,/"From-User"\s*\:\s*"[^"]*"/"From-User" : "$var(user)"/} \
{re.subst,/"To"\s*\:\s*"[^"]*"/"To" : "$var(presentity)"/} \
{re.subst,/"To-User"\s*\:\s*"[^"]*"/"To-User" : "$var(user)"/} \
{re.subst,/"Messages-New"\s*\:\s*[^,]*/"Direction" : "initiator"/} \
{re.subst,/"Event-Name"\s*\:\s*"[^"]*"/"Event-Name" : "presence"/});
route[MWI_AS_PRESENCE]
{
if( $(kzE{kz.json,Extended-Presence-ID}) == "" ) {
return;
}
$var(realm) = $(kzE{kz.json,From-Realm});
$var(user) = $(kzE{kz.json,Extended-Presence-ID});
$var(presentity) = $_s(sip:$var(user)@$var(realm));
if( $(kzE{kz.json,Messages-Waiting}) == "yes" ) {
$var(State) = "confirmed";
} else {
$var(State) = "terminated";
}
$var(payload) = MWI_PRESENCE_BODY
$var(JObj) = $var(payload);
route(PRESENCE_UPDATE);
}
route[PRESENCE_BINDINGS]
{
#!import_file "presence-custom-bindings.cfg"
#!ifndef PRESENCE_CUSTOM_BINDINGS
$var(payload) = $_s({ "name" : "presence", "exchange" : "presence", "type" : "topic", "queue" : "presence-dialog-MY_HOSTNAME", "routing" : ["dialog.*.*", "update.*.*", "mwi_updates.*.*"], "exclusive" : false, "federate" : true });
kazoo_subscribe("$var(payload)");
#!endif
route(PRESENCE_API_BINDINGS);
route(PRESENCE_FAST_PICKUP_START);
}
route[PRESENCE_API_BINDINGS]
{
#!import_file "presence-api-custom-bindings.cfg"
#!ifndef PRESENCE_API_CUSTOM_BINDINGS
$var(payload) = $_s({"name": "presence-api", "exchange": "presence", "type": "topic", "queue": "presence-api-MY_HOSTNAME", "routing": ["presence.search_req.*", "presence.reset.*.*"], "exclusive": false, "federate": true });
kazoo_subscribe("$var(payload)");
#!endif
}
route[PRESENCE_LOCAL_REQUEST]
{
route(PRESENCE_LOCAL_REQ_NOTIFY);
}
route[PRESENCE_AUTHN]
{
if($sel(cfg_get.kazoo.presence_require_authn) == 1) {
$xavp(regcfg=>match_received) = $su;
if(registered("location", "$rz:$Au", 2, 1) != 1) {
xlog("L_WARNING", "$ci|stop|$rm from unregistered ($rz:$Au) user agent $ua => $su\n");
send_reply(403, "Forbidden");
exit;
}
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

kamailio/pusher-role.cfg → kamailio-proxy-blf/pusher-role.cfg View File


kamailio/rate-limiter-role.cfg → kamailio-proxy-blf/rate-limiter-role.cfg View File


+ 588
- 0
kamailio-proxy-blf/registrar-role.cfg View File

@ -0,0 +1,588 @@
#### NAT PINGING PARAMS ###
#!trydef REGISTRAR_NAT_PING_INTERVAL 30
## REGISTRAR_NAT_PING_TIMEOUT should be (REGISTRAR_NAT_PING_INTERVAL * 3 + 10) or 0 to disable
#!trydef REGISTRAR_NAT_PING_TIMEOUT 0
#!trydef REGISTRAR_NAT_PING_NAT_ONLY 1
#!trydef REGISTRAR_NAT_PING_WORKERS 5
#####
#!trydef REGISTRAR_MIN_EXPIRES 300
#!trydef REGISTRAR_MAX_EXPIRES 3600
#!trydef REGISTRAR_DEFAULT_EXPIRES 600
#!trydef REGISTRAR_ERROR_MIN_EXPIRES 1
#!trydef REGISTRAR_ERROR_MISSING_EXPIRES 1
#!trydef REGISTRAR_CONTACT_MAX_SIZE 2048
#!trydef REGISTRAR_QUERY_TIMEOUT_MS 2500
#!trydef REGISTRAR_HANDLE_LOST_TCP 1
#!trydef REGISTRAR_CLOSE_EXPIRED_TCP 1
#!trydef REGISTRAR_HANDLE_EXPIRED_TCP 1
#!trydef REGISTRAR_HANDLE_EXPIRED_UDP 0
#!trydef REGISTRAR_HANDLE_EXPIRED_TLS 1
#!trydef REGISTRAR_HANDLE_EXPIRED_WS 1
#!trydef REGISTRAR_FORCE_QUERY 0
#!trydef REGISTRAR_FORCE_FAILOVER 0
#!trydef REGISTRAR_CHECK_AMQP_AVAILABILITY 0
#!trydef KZ_REGISTRAR_KEEPALIVE_UDP_ONLY 1
#!trydef REGISTRAR_AMQP_EXCHANGE callmgr
#!trydef REGISTRAR_AMQP_FLAGS 0
#!trydef REGISTRAR_AMQP_RK_PREFIX authn.req.
#!trydef REGISTRAR_SEND_100 1
#!trydef REGISTRAR_DB_MODE 2
#!trydef REGISTRAR_DB_TIMER_CLEANUP 0
#!trydef REGISTRAR_DB_REMOVE_EXPIRED_DELAY 0
#!trydef REGISTRAR_SYNC_TIMER_INTERVAL 5
#!trydef REGISTRAR_SYNC_TIMER_PROCS 1
#!ifdef REGISTRAR_WARM_CACHE
#!substdef "!REGISTRAR_S_WARM_CACHE!dbtable=auth_cache;dbmode=1;!g"
#!else
#!substdef "!REGISTRAR_S_WARM_CACHE!!g"
#!endif
######## Generic Hash Table container in shared memory ########
modparam("htable", "htable", "auth_cache=>size=16;autoexpire=7200;REGISTRAR_S_WARM_CACHE")
####### Authentication Interface module ##########
loadmodule "auth.so"
####### User Location Implementation module ##########
loadmodule "usrloc.so"
modparam("usrloc", "db_update_as_insert", 0)
modparam("usrloc", "use_domain", 1)
modparam("usrloc", "nat_bflag", FLB_NATB)
modparam("usrloc", "db_url", "KAZOO_DB_URL")
modparam("usrloc", "db_mode", REGISTRAR_DB_MODE)
modparam("usrloc", "db_timer_clean", REGISTRAR_DB_TIMER_CLEANUP)
modparam("usrloc", "handle_lost_tcp", REGISTRAR_HANDLE_LOST_TCP)
modparam("usrloc", "rm_expired_delay", REGISTRAR_DB_REMOVE_EXPIRED_DELAY)
modparam("usrloc", "db_check_update", 1)
modparam("usrloc", "db_ops_ruid", 1)
modparam("usrloc", "xavp_contact", "ulattrs")
modparam("usrloc", "timer_interval", REGISTRAR_SYNC_TIMER_INTERVAL)
modparam("usrloc", "timer_procs", REGISTRAR_SYNC_TIMER_PROCS)
modparam("usrloc", "fetch_rows", 400)
modparam("usrloc", "handle_lost_tcp", REGISTRAR_HANDLE_LOST_TCP)
modparam("usrloc", "close_expired_tcp", REGISTRAR_CLOSE_EXPIRED_TCP)
####### SIP Registrar implementation module ##########
loadmodule "registrar.so"
modparam("registrar", "received_avp", "$avp(AVP_RECV_PARAM)")
modparam("registrar", "min_expires", REGISTRAR_MIN_EXPIRES)
modparam("registrar", "max_expires", REGISTRAR_MAX_EXPIRES)
modparam("registrar", "default_expires", REGISTRAR_DEFAULT_EXPIRES)
modparam("registrar", "xavp_cfg", "regcfg")
modparam("registrar", "gruu_enabled", 1)
modparam("registrar", "outbound_mode", 1)
modparam("registrar", "regid_mode", 1)
modparam("registrar", "path_mode", 1)
modparam("registrar", "use_path", 1)
modparam("registrar", "received_param", "")
modparam("registrar", "xavp_rcd", "ulrcd")
modparam("registrar", "contact_max_size", REGISTRAR_CONTACT_MAX_SIZE)
####### NAT ##########
#!ifdef NAT_TRAVERSAL_ROLE
#!ifndef NATHELPER_LOADED
loadmodule "nathelper.so"
#!trydef NATHELPER_LOADED
#!endif
#!ifdef KEEPALIVE_ROLE
modparam("nathelper", "natping_interval", 0)
modparam("nathelper", "natping_processes", 0)
#!else
modparam("nathelper", "natping_interval", REGISTRAR_NAT_PING_INTERVAL)
modparam("nathelper", "ping_nated_only", REGISTRAR_NAT_PING_NAT_ONLY)
modparam("nathelper", "natping_processes", REGISTRAR_NAT_PING_WORKERS)
modparam("nathelper", "sipping_bflag", FLB_NATSIPPING)
modparam("nathelper", "keepalive_timeout", REGISTRAR_NAT_PING_TIMEOUT)
#!endif
#!endif
## stats ##
modparam("statistics","variable", "registrar:force_failover")
modparam("statistics","variable", "registrar:cached")
modparam("statistics","variable", "registrar:ip_realm")
modparam("statistics","variable", "registrar:new_tran")
modparam("statistics","variable", "registrar:amqp_not_available")
modparam("statistics","variable", "registrar:challenge")
modparam("statistics","variable", "registrar:amqp_async_error")
modparam("statistics","variable", "registrar:amqp_returned")
modparam("statistics","variable", "registrar:amqp_timeout")
modparam("statistics","variable", "registrar:drops")
modparam("statistics","variable", "registrar:authn_perm_err")
modparam("statistics","variable", "registrar:authn_err")
modparam("statistics","variable", "registrar:authn_resp")
modparam("statistics","variable", "registrar:authn_unknown")
modparam("statistics","variable", "registrar:save_error")
modparam("statistics","variable", "registrar:missing_expires")
modparam("statistics","variable", "registrar:missing_expires_allowed")
modparam("statistics","variable", "registrar:min_expires")
modparam("statistics","variable", "registrar:min_expires_allowed")
##### registrar realtime params #####
kazoo.registrar_error_min_expires = REGISTRAR_ERROR_MIN_EXPIRES descr "send error when UAS sends expires < min-expires"
kazoo.registrar_error_missing_expires = REGISTRAR_ERROR_MISSING_EXPIRES descr "send error when UAS do not send expires header"
kazoo.registrar_handle_expired_tcp = REGISTRAR_HANDLE_EXPIRED_TCP descr "handles expired tcp registrations"
kazoo.registrar_handle_expired_udp = REGISTRAR_HANDLE_EXPIRED_UDP descr "handles expired udp registrations"
kazoo.registrar_handle_expired_tls = REGISTRAR_HANDLE_EXPIRED_TLS descr "handles expired tls registrations"
kazoo.registrar_handle_expired_ws = REGISTRAR_HANDLE_EXPIRED_WS descr "handles expired ws registrations"
kazoo.registrar_query_timeout_ms = REGISTRAR_QUERY_TIMEOUT_MS descr "timeout waiting for reply from registrar"
kazoo.registrar_failover = REGISTRAR_FORCE_FAILOVER descr "force failover if 1"
kazoo.registrar_force_query = REGISTRAR_FORCE_QUERY descr "force query if 1"
kazoo.registrar_check_amqp_availability = REGISTRAR_CHECK_AMQP_AVAILABILITY descr "checks if amqp connection is available before querying registrar"
kazoo.registrar_keepalive_udp_only = KZ_REGISTRAR_KEEPALIVE_UDP_ONLY descr "should we keepalive nat phones for udp only"
kazoo.registrar_send_100 = REGISTRAR_SEND_100 descr "should we send 100 reply while doing directory search"
####### Registrar Logic ########
route[REGISTRAR_NAT_FLAGS]
{
if (isflagset(FLT_NATS)) {
xlog("L_DEBUG", "$ci|log|fixing contact for nat request\n");
setbflag(FLB_NATB);
fix_nated_register();
## KAZOO-1846: Cisco SPA8000 freaks out on options pings
if (!($ua =~ "Linksys/SPA8000"
|| $ua =~ "SIPp"
|| (af==INET6)
|| ($sel(cfg_get.kazoo.registrar_keepalive_udp_only) == 1 && $proto != "udp")
|| ($proto =="ws" || $proto == "wss")
|| ($(xavp(ulattrs=>custom_channel_vars){kz.json,Keep-Alive}) == "false")
)) {
xlog("L_DEBUG", "$ci|log|set nat pinging\n");
setbflag(FLB_NATSIPPING);
}
} else {
$avp(AVP_RECV_PARAM) = $su;
}
}
route[HANDLE_REGISTER]
{
if (!is_method("REGISTER")) {
return;
}
#!ifdef PUSHER_ROLE
route(PUSHER_ATTEMPT_REGISTRATION);
#!endif
if($sel(cfg_get.kazoo.registrar_failover) == 1) {
xlog("L_INFO", "$ci|log|register|forcing failover\n");
update_stat("registrar:force_failover", "+1");
drop;
}
if($sel(cfg_get.kazoo.registrar_force_query) == 0) {
if($sht(auth_cache=>$Au) == "authn_perm_err") {
xlog("L_INFO", "$ci|end|issuing auth challenge to cached permanent failed registration attempt for $Au from IP $si:$sp\n");
update_stat("registrar:authn_perm_err", "+1");
#!ifdef ANTIFLOOD_ROLE
route(ANITFLOOD_FAILED_AUTH);
#!endif
update_stat("registrar:challenge", "+1");
auth_challenge("$fd", "4");
exit;
} else if($sht(auth_cache=>$Au) != $null) {
$xavp(regcfg=>match_received) = $su;
if(registered("location", "$rz:$Au", 2, 1) == 1) {
if($(xavp(ulattrs=>custom_channel_vars){s.len}) > 1) {
$var(password) = $sht(auth_cache=>$Au);
update_stat("registrar:cached", "+1");
route(SAVE_LOCATION);
exit;
}
}
}
}
if($td =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}" ||
$fd =~ "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}") {
xlog("L_INFO", "$ci|log|register|invalid domain\n");
update_stat("registrar:ip_realm", "+1");
drop;
}
if($sel(cfg_get.kazoo.registrar_check_amqp_availability) == 1) {
if($xavp(amqpc=>default::MY_AMQP_ZONE) == 0) {
xlog("L_WARNING", "$ci|end|register|no amqp connection available for default worker in zone MY_AMQP_ZONE\n");
update_stat("registrar:amqp_not_available", "+1");
drop;
}
}
route(REGISTRAR_BOUNDS);
$var(auth) = pv_auth_check("$fd", "$uuid(g)", "0", "0");
if($var(auth) != -2) {
xlog("L_INFO", "$ci|end|challenging $Au $si:$sp\n");
$var(auth) = auth_challenge("$fd", "4");
update_stat("registrar:challenge", "+1");
if($var(auth) != 1) {
xlog("L_ERROR", "$ci|register|error creating or sending challenge to registration attempt for $fu from $si:$sp\n");
drop;
}
exit;
}
if (!t_newtran()) {
xlog("L_ERROR", "$ci|log|failed to create transaction to query for authentication credentials for $Au $si:$sp\n");
update_stat("registrar:new_tran", "+1");
drop;
}
if($sel(cfg_get.kazoo.registrar_send_100) == 1) {
sl_send_reply("100", "checking your credentials");
}
$var(amqp_payload_request) = $_s({"Event-Category" : "directory" , "Event-Name" : "authn_req", "Method" : "REGISTER", "Auth-Nonce" : "$adn", "Auth-Realm" : "$fd", "Auth-User" : "$fU", "From" : "$fu", "To" : "$tu", "Orig-IP" : "$si", "Orig-Port" : "$sp", "User-Agent" : "$(ua{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Contact" : "$(ct{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Call-ID" : "$ci" });
$var(amqp_routing_key) = $_s($def(REGISTRAR_AMQP_RK_PREFIX)$(fd{kz.encode}));
$avp(kz_timeout) = $sel(cfg_get.kazoo.registrar_query_timeout_ms);
$xavp(deltas=>query) = $(TV(Sn){s.replace,.,});
xlog("L_DEBUG", "$ci|amqp|publishing to $def(REGISTRAR_AMQP_EXCHANGE) => $var(amqp_routing_key) : $def(REGISTRAR_AMQP_FLAGS) : $var(amqp_payload_request)\n");
if(kazoo_async_query("$def(REGISTRAR_AMQP_EXCHANGE)", $var(amqp_routing_key), $var(amqp_payload_request), "KZ_AUTHORIZATION_REPLY", "KZ_AUTHORIZATION_TIMEOUT", "$def(REGISTRAR_AMQP_FLAGS)") != 1) {
xlog("L_INFO", "$ci|log|failed to send registrar query for authentication credentials for $Au $si:$sp\n");
update_stat("registrar:amqp_async_error", "+1");
t_drop();
}
}
failure_route[KZ_AUTHORIZATION_TIMEOUT]
{
if($(kzR{kz.json,Event-Name}) == "message_returned" ) {
xlog("L_WARNING", "$ci|amqp|message was returned by broker $(kzR{kz.json,Error-Code}) $(kzR{kz.json,Error-Reason})\n");
update_stat("registrar:amqp_returned", "+1");
} else {
xlog("L_WARNING", "$ci|end|failed $T_reply_code $T_reply_reason [$T(id_index):$T(id_label)] querying directory for authentication credentials for $Au $si:$sp\n");
update_stat("registrar:amqp_timeout", "+1");
}
update_stat("registrar:drops", "+1");
t_drop();
}
onreply_route[KZ_AUTHORIZATION_REPLY]
{
$var(StartRoute) = $(TV(Sn){s.replace,.,});
$var(delta_to_start) = $var(StartRoute) - $(kzR{kz.json,AMQP-Received});
$var(delta_from_query) = $(kzR{kz.json,AMQP-Received}) - $xavp(deltas=>query);
xlog("L_INFO", "$ci|log|received $(kzR{kz.json,Event-Category}) $(kzR{kz.json,Event-Name}) reply from $(kzR{kz.json,App-Name})-$(kzR{kz.json,App-Version}) (Δ1 $(kzR{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs, Δ3 $var(delta_from_query) μs)\n");
$var(password) = $(kzR{kz.json,Auth-Password});
$var(nonce) = $adn;
if( $(kzR{kz.json,Event-Name}) == "authn_err" ) {
if($(kzR{kz.json,Permanent-Error}) == "true") {
$sht(auth_cache=>$Au) = "authn_perm_err";
}
update_stat("registrar:authn_err", "+1");
#!ifdef ANTIFLOOD_ROLE
route(ANITFLOOD_FAILED_AUTH);
#!endif
update_stat("registrar:challenge", "+1");
auth_challenge("$fd", "4");
xlog("L_INFO", "$ci|end|challenging $Au $si:$sp via $(kzR{kz.json,App-Name})-$(kzR{kz.json,App-Version}) response\n");
exit;
} else if( $(kzR{kz.json,Event-Name}) == "authn_resp" ) {
update_stat("registrar:authn_resp", "+1");
xlog("L_INFO", "$ci|log|authenticating $Au via $(kzR{kz.json,App-Name})-$(kzR{kz.json,App-Version}) response\n");
route(CHECK_AUTHORIZATION);
} else {
update_stat("registrar:authn_unknown", "+1");
update_stat("registrar:drops", "+1");
xlog("L_INFO", "$ci|log|unhandle response from directory $Au via $(kzR{kz.json,App-Name})-$(kzR{kz.json,App-Version})\n");
t_drop();
}
}
route[CHECK_AUTHORIZATION]
{
if (!pv_auth_check("$fd", "$var(password)", "0", "0")) {
#!ifdef ANTIFLOOD_ROLE
route(ANITFLOOD_FAILED_AUTH);
#!endif
xlog("L_WARNING", "$ci|end|issuing auth challenge to failed registration attempt for $Au from IP $si:$sp\n");
update_stat("registrar:challenge", "+1");
auth_challenge("$fd", "5");
exit;
}
#!ifdef ANTIFLOOD_ROLE
route(ANTIFLOOD_SUCCESSFUL_AUTH);
#!endif
# user authenticated - remove auth header
consume_credentials();
$xavp(ulattrs=>custom_channel_vars) = $(kzR{kz.json,Custom-Channel-Vars});
$xavp(ulattrs[0]=>token) = $_s($(kzR{kz.json,Custom-Channel-Vars.Authorizing-ID})@$(kzR{kz.json,Custom-Channel-Vars.Account-ID}));
route(SAVE_LOCATION);
}
route[SAVE_LOCATION]
{
if ($sht(auth_cache=>$Au) == $null && $var(password) != $null) {
xlog("L_INFO", "$ci|log|caching sip credentials for $Au\n");
};
$sht(auth_cache=>$Au) = $var(password);
route(REGISTRAR_NAT_FLAGS);
$var(save_result) = save("location", "0x04");
if($var(save_result) < 0) {
xlog("L_WARNING", "$ci|end|not expected result $var(save_result) when saving $Au registration from IP $si:$sp\n");
update_stat("registrar:save_error", "+1");
exit;
} else {
if($var(save_result) == 1) {
$var(new_reg) = "true";
} else {
$var(new_reg) = "false";
}
}
if($var(save_result) == 3) {
$var(expires) = 0;
} else {
$var(expires) = $xavp(ulrcd=>expires);
}
if($var(expires) == 0) {
xlog("L_INFO", "$ci|end|unregister request from $Au $si:$sp\n");
$var(Status) = "Unregistered";
} else {
$var(Status) = "Registered";
}
$var(ip) = $Ri;
if(af==INET6) {
$var(ip) = "[" + $Ri + "]";
}
# allow port redirection on registration
switch($proto)
{
#!ifdef KZ_WEBSOCKETS_REGISTRAR_PORT
case "ws":
case "wss":
$var(port) = KZ_WEBSOCKETS_REGISTRAR_PORT;
break;
#!endif
#!ifdef KZ_TLS_REGISTRAR_PORT
case "tls":
$var(port) = KZ_TLS_REGISTRAR_PORT;
break;
#!endif
#!ifdef KZ_UDP_REGISTRAR_PORT
case "udp":
$var(port) = KZ_UDP_REGISTRAR_PORT;
break;
#!endif
#!ifdef KZ_TCP_REGISTRAR_PORT
case "tcp":
$var(port) = KZ_TCP_REGISTRAR_PORT;
break;
#!endif
default:
$var(port) = $Rp;
}
$var(AdvIP) = $RAi;
if(af==INET6) {
$var(AdvIP) = "[" + $RAi + "]";
}
$var(amqp_payload_request) = $_s({"Event-Category" : "directory", "Event-Name" : "reg_success", "Status" : "$var(Status)", "Event-Timestamp" : $TS, "Expires" : $(var(expires){s.int}), "First-Registration" : $var(new_reg), "Contact" : "$(ct{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Call-ID" : "$ci", "Realm" : "$fd", "Username" : "$fU", "From-User" : "$fU", "From-Host" : "$fd", "To-User" : "$tU", "To-Host" : "$td", "User-Agent" : "$(ua{s.escape.common}{s.replace,\','}{s.replace,$$,})" , "Custom-Channel-Vars" : $xavp(ulattrs=>custom_channel_vars), "Proxy-Path" : "sip:MY_IP_ADDRESS:$var(port)", "Proxy-Protocol" : "$proto", "Proxy-IP" : "$var(AdvIP)", "Proxy-Port" : "$RAp", "Source-IP": "$si", "Source-Port": "$sp" });
$var(amqp_routing_key) = "registration.success." + $(fd{kz.encode}) + "." + $(fU{kz.encode});
kazoo_publish("registrar", $var(amqp_routing_key), $var(amqp_payload_request));
xlog("L_INFO", "$ci|end|successful $(var(Status){s.tolower}) with contact : $ct : $var(expires)\n");
#!ifdef PUSHER_ROLE
route(PUSHER_ON_REGISTRATION);
#!endif
#!ifdef KEEPALIVE_ROLE
route(KEEPALIVE_ON_REGISTRATION);
#!endif
exit;
}
## kazoo event route , {"directory", "reg_flush") => reg-flush by kamailio limitations
## when a Event-Category or Event-Name has a underscore (_) we need to declare it with a dash (-)
event_route[kazoo:consumer-event-directory-reg-flush]
{
$var(user) = $(kzE{kz.json,Username}) + "@" + $(kzE{kz.json,Realm});
xlog("L_INFO", "$(kzE{kz.json,Msg-ID})|log|received directory flush for $var(user)\n");
if ($sht(auth_cache=>$var(user)) != $null) {
$sht(auth_cache=>$var(user)) = $null;
}
if( $(kzE{kz.json,Cache-Only}) == "true") {
return;
}
if(reg_fetch_contacts("location", "sip:$var(user)", "caller")) {
$var(i) = 0;
while($var(i) < $(ulc(caller=>count))) {
unregister("location", "sip:$(ulc(caller=>aor))", "$(ulc(caller=>ruid)[$var(i)])");
$var(i) = $var(i) + 1;
}
reg_free_contacts("caller");
}
#!ifdef ANTIFLOOD_ROLE
route(ANTIFLOOD_RESET_AUTH);
#!endif
}
route[REGISTRAR_BINDINGS]
{
#!import_file "registrar-custom-bindings.cfg"
#!ifndef REGISTRAR_CUSTOM_BINDINGS
$var(payload) = $_s({"name": "registrar-api", "exchange": "registrar", "type": "topic", "queue": "registrar-flush-MY_HOSTNAME", "routing": "registration.flush.*", "federate": 1 });
kazoo_subscribe("$var(payload)");
#!endif
#!ifdef REGISTRAR_SYNC_ROLE
route(REGISTRAR_SYNC_BINDINGS);
#!endif
}
route[REGISTRAR_BOUNDS]
{
if((int)@contact.expires) {
$var(expires) = @contact.expires;
} else if(is_present_hf("Expires")) {
$var(expires) = $hdr(Expires);
} else if($(sel(contact){tobody.params}{param.value,expires}) != "") {
$var(expires) = $(sel(contact){tobody.params}{param.value,expires}{s.int});
} else {
if($sel(cfg_get.kazoo.registrar_error_missing_expires) == 1) {
xlog("L_WARNING", "$ci|end|missing expires registering $Au from IP $si:$sp\n");
send_reply("400", "Missing Expires");
update_stat("registrar:missing_expires", "+1");
exit;
} else {
update_stat("registrar:missing_expires_allowed", "+1");
xlog("L_WARNING", "$ci|end|allowing missing expires registering $Au from IP $si:$sp\n");
}
}
if($var(expires) != 0) {
if($var(expires) < REGISTRAR_MIN_EXPIRES) {
if($sel(cfg_get.kazoo.registrar_error_min_expires) == 1) {
xlog("L_WARNING", "$ci|end|expires $var(expires) too brief (configured $def(REGISTRAR_MIN_EXPIRES)) registering $Au from IP $si:$sp\n");
append_to_reply("Min-Expires: $def(REGISTRAR_MIN_EXPIRES)\r\n");
send_reply("423", "Interval Too Brief");
update_stat("registrar:min_expires", "+1");
exit;
} else {
update_stat("registrar:min_expires_allowed", "+1");
xlog("L_WARNING", "$ci|end|allowing expires $var(expires) too brief (configured $def(REGISTRAR_MIN_EXPIRES)) registering $Au from IP $si:$sp\n");
}
}
}
}
##
## this needs handling logic in ecallmgr
## because we will fire the unregister from this server
## after device registers in another proxy
## causing ecallmgr to delete the registration
## from the other server
##
event_route[usrloc:contact-expired]
{
#!ifdef PRESENCE_ROLE
route(PRESENCE_EXPIRED_REGISTRATION);
#!endif
#!ifdef KEEPALIVE_ROLE
route(KEEPALIVE_ON_EXPIRED_REGISTRATION);
#!endif
## return until we handle this in ecallmr
xlog("L_INFO", "$ulc(exp=>callid)|expired|removed registration for $ulc(exp=>aor) with contact : $ulc(exp=>addr)\n");
return;
$var(transport) = $(ulc(exp=>received){uri.transport});
$var(proto) = $(ulc(exp=>socket){re.subst,/^([^:]*):(.*)/\1/});
if($var(proto) == "tls" && $var(transport) == "ws") {
$var(proto) = "wss";
}
$var(handle) = 0;
switch($var(proto))
{
case "ws":
case "wss":
if($sel(cfg_get.kazoo.registrar_handle_expired_ws) == 1) {
$var(handle) = 1;
}
break;
case "tls":
if($sel(cfg_get.kazoo.registrar_handle_expired_tls) == 1) {
$var(handle) = 1;
}
break;
case "tcp":
if($sel(cfg_get.kazoo.registrar_handle_expired_tcp) == 1) {
$var(handle) = 1;
}
break;
case "udp":
if($sel(cfg_get.kazoo.registrar_handle_expired_udp) == 1) {
$var(handle) = 1;
}
break;
default:
break;
}
if($var(handle) == 1) {
$var(aor) = $_s(sip:$ulc(exp=>aor));
$var(username) = $(var(aor){uri.user});
$var(domain) = $(var(aor){uri.host});
$var(amqp_payload_request) = $_s({"Event-Category" : "directory", "Event-Name" : "reg_success", "Status" : "Unregistered", "Event-Timestamp" : $TS, "Expires" : 0, "First-Registration" : false, "Contact" : "$(ulc(exp=>addr){s.escape.common}{s.replace,\','}{s.replace,$$,})", "Call-ID" : "$ulc(exp=>callid)", "Realm" : "$var(domain)", "Username" : "$var(username)", "From-User" : "$var(username)", "From-Host" : "$var(domain)", "To-User" : "$var(username)", "To-Host" : "$var(domain)", "Proxy-Path" : "$ulc(exp=>socket)", "User-Agent" : "$(ulc(exp=>user_agent){s.escape.common}{s.replace,\','}{s.replace,$$,})"});
$var(amqp_routing_key) = "registration.success." + $(var(domain){kz.encode}) + "." + $(var(username){kz.encode});
kazoo_publish("registrar", $var(amqp_routing_key), $var(amqp_payload_request));
xlog("L_INFO", "$ulc(exp=>callid)|expired|notified registration removal with contact : $ulc(exp=>addr)\n");
}
xlog("L_INFO", "$ulc(exp=>callid)|expired|removed registration for $ulc(exp=>aor) with contact : $ulc(exp=>addr)\n");
}
#!ifdef REGISTRAR_SYNC_ROLE
#!include_file "registrar-sync-role.cfg"
#!endif
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

kamailio/registrar-sync-role.cfg → kamailio-proxy-blf/registrar-sync-role.cfg View File


kamailio/responder-role.cfg → kamailio-proxy-blf/responder-role.cfg View File


+ 67
- 0
kamailio-proxy-blf/sanity.cfg View File

@ -0,0 +1,67 @@
#!trydef SANITY_CHECK_USE_PORT 1
#!trydef SANITY_DROPS_REQUEST 1
#!trydef SANITY_DEFAULT_CHECK 17895
#!trydef SANITY_URI_CHECKS 7
#!trydef SANITY_TRACE_REQUEST 1
#!substdef "!SANITY_SUBST_CACHE_PERIOD!$def(SANITY_CACHE_PERIOD)!g"
######## SIP message formatting sanity checks [requires sl] ########
loadmodule "sanity.so"
modparam("sanity", "default_checks", SANITY_DEFAULT_CHECK)
modparam("sanity", "uri_checks", SANITY_URI_CHECKS)
modparam("sanity", "autodrop", 0)
modparam("sanity", "noreply", 1)
modparam("debugger", "mod_level", "sanity=-3")
kazoo.sanity_check_use_port = SANITY_CHECK_USE_PORT descr "should we keep track of ip and port for sanity failures"
kazoo.sanity_drops_request = SANITY_DROPS_REQUEST descr "should we drop the request or send error on sanity failure"
kazoo.sanity_trace_request = SANITY_TRACE_REQUEST descr "should we trace the request if sip trace role is enabled"
route[SANITY_CHECK]
{
## CVE-2018-14767
if($(hdr(To)[1]) != $null) {
xlog("second To header not null - dropping message");
drop;
}
$var(sanity_key) = "";
if($sel(cfg_get.kazoo.sanity_check_use_port) == 1) {
$var(sanity_key) = $_s("$si::$sp");
} else {
$var(sanity_key) = $_s("$si");
}
if (!sanity_check()) {
#!ifdef SIP_TRACE_ROLE
sip_trace();
#!endif
if($sel(cfg_get.kazoo.sanity_drops_request) == 1) {
xlog("L_WARN", "$ci|end|dropping insane message from $si:$sp\n");
drop;
} else {
xlog("L_WARN", "$ci|end|insane message from $si:$sp\n");
send_reply("400", "Bad Request");
exit;
}
}
if (!mf_process_maxfwd_header("10")) {
xlog("L_WARN", "$ci|end|too much hops, not enough barley from $si:$sp\n");
send_reply("483", "Too Many Hops");
exit;
}
if ($ua == "friendly-scanner" ||
$ua == "sundayddr" ||
$ua == "pplsip" ||
$ua =~ "NiceGuy" ||
$ua =~ "PortSIP" ||
$ua =~ "sipcli" ) {
xlog("L_WARN", "$ci|end|dropping message with user-agent $ua from $si:$sp\n");
drop;
}
}

+ 97
- 0
kamailio-proxy-blf/sip_trace-role.cfg View File

@ -0,0 +1,97 @@
#################################
## SIP_TRACE_ROLE Defs
#!trydef KZ_TRACE 0
#!trydef KZ_TRACE_INTERNAL 1
#!trydef KZ_TRACE_EXTERNAL 1
#!trydef KZ_TRACE_LOCAL 1
#!trydef KZ_TRACE_INTERNAL_INCOMING 1
#!trydef KZ_TRACE_INTERNAL_OUTGOING 1
#!trydef KZ_TRACE_EXTERNAL_INCOMING 1
#!trydef KZ_TRACE_EXTERNAL_OUTGOING 1
#!trydef SIP_TRACE_URI "sip:127.0.0.1:9060"
#!trydef HEP_CAPTURE_ID 1
##############################################################
## Kamailio siptrace settings configuration examples at runtime
## kamcmd siptrace.status on
## kamcmd cfg.seti kazoo trace_external 0
## kamcmd cfg.seti kazoo trace_internal 0
kazoo.trace_external = KZ_TRACE_EXTERNAL descr "activates tracing from external sources"
kazoo.trace_internal = KZ_TRACE_INTERNAL descr "activates tracing from internal sources"
kazoo.trace_local = KZ_TRACE_LOCAL descr "activates tracing for local requests"
kazoo.trace_internal_incoming = KZ_TRACE_INTERNAL_INCOMING descr "traces the original request as received from internal sources"
kazoo.trace_internal_outgoing = KZ_TRACE_INTERNAL_OUTGOING descr "traces the outgoing request to external sources after possible modification"
kazoo.trace_external_incoming = KZ_TRACE_EXTERNAL_INCOMING descr "traces the original request as received from external sources"
kazoo.trace_external_outgoing = KZ_TRACE_EXTERNAL_OUTGOING descr "traces the outgoing request to internal sources after possible modification"
####### Siptrace module ##########
loadmodule "siptrace.so"
modparam("siptrace", "duplicate_uri", SIP_TRACE_URI)
modparam("siptrace", "hep_mode_on", 1)
modparam("siptrace", "hep_version", 3)
modparam("siptrace", "hep_capture_id", HEP_CAPTURE_ID)
modparam("siptrace", "trace_to_database", 0)
## `trace_flag` value must be equal to FLAG_SIP_TRACE value at head of "default.cfg" file
modparam("siptrace", "trace_flag", 8)
modparam("siptrace", "trace_on", KZ_TRACE)
route[SIP_TRACE_INTERNAL]
{
if($sel(cfg_get.kazoo.trace_internal) == 0) {
return;
}
if($sel(cfg_get.kazoo.trace_internal_incoming) == 1) {
sip_trace();
}
if($sel(cfg_get.kazoo.trace_internal_outgoing) == 1) {
setflag(FLAG_SIP_TRACE);
}
}
route[SIP_TRACE_EXTERNAL]
{
if($sel(cfg_get.kazoo.trace_external) == 0) {
return;
}
if($sel(cfg_get.kazoo.trace_external_incoming) == 1) {
sip_trace();
}
if($sel(cfg_get.kazoo.trace_external_outgoing) == 1) {
setflag(FLAG_SIP_TRACE);
}
}
route[SIP_TRACE_LOCAL]
{
if($sel(cfg_get.kazoo.trace_local) == 0) {
return;
}
if($hdr(X-TM-Local) != $null) {
return;
}
sip_trace();
}
route[SIP_TRACE_LOCAL_ROUTE]
{
setflag(FLAG_SIP_TRACE);
}
route[SIP_TRACE]
{
if (isflagset(FLAG_LOCAL_ROUTE)) {
route(SIP_TRACE_LOCAL_ROUTE);
} else if (isflagset(FLAG_LOCAL_REQUEST)) {
route(SIP_TRACE_LOCAL);
} else if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(SIP_TRACE_INTERNAL);
} else {
route(SIP_TRACE_EXTERNAL);
}
}

kamailio/tls-role.cfg → kamailio-proxy-blf/tls-role.cfg View File


kamailio/tls.cfg → kamailio-proxy-blf/tls.cfg View File


kamailio/traffic-filter-role.cfg → kamailio-proxy-blf/traffic-filter-role.cfg View File


+ 147
- 0
kamailio-proxy-blf/websockets-role.cfg View File

@ -0,0 +1,147 @@
tcp_accept_no_cl=yes
listen=TCP_WS
#!ifdef TLS_ROLE
listen=TLS_WSS
#!endif
######## NAT Traversal module - signaling functions ########
#!ifndef NATHELPER_LOADED
#!trydef NATHELPER_LOADED
loadmodule "nathelper.so"
#!endif
######## Generic Hash Table container in shared memory ########
modparam("htable", "htable", "websockets=>size=16;initval=0")
######## Basic HTTP request handling ########
loadmodule "xhttp.so"
#!trydef WS_KEEPALIVE_MECHANISM 3
#!trydef WS_KEEPALIVE_TIMEOUT 30
#!trydef WS_KEEPALIVE_PROCESSES 3
#!trydef WS_KEEPALIVE_INTERVAL 1
#!trydef WS_KEEPALIVE_DATA "Kazoo encourages you to keep alive"
#!trydef WS_MAX_CONNECTIONS_PER_IP 50
#!trydef WS_MAX_CONNECTIONS_PER_PROXY 0
#!trydef WS_ALLOWED_PROXIES "0.0.0.0/0"
#!trydef WS_CONNECTIONS_FROM_PROXY_ONLY 0
######## Websocket module ########
loadmodule "websocket.so"
modparam("websocket", "keepalive_mechanism", WS_KEEPALIVE_MECHANISM)
modparam("websocket", "keepalive_timeout", WS_KEEPALIVE_TIMEOUT)
modparam("websocket", "keepalive_processes", WS_KEEPALIVE_PROCESSES)
modparam("websocket", "keepalive_interval", WS_KEEPALIVE_INTERVAL)
modparam("websocket", "ping_application_data", WS_KEEPALIVE_DATA)
modparam("websocket", "sub_protocols", 1)
####### Websocket Logic ########
kazoo.ws_allowed_proxies = WS_ALLOWED_PROXIES desc "comma separated list of allowed proxies in cidr notation"
kazoo.ws_max_connection_per_ip = WS_MAX_CONNECTIONS_PER_IP desc "max connections per ip"
kazoo.ws_max_connection_per_proxy = WS_MAX_CONNECTIONS_PER_PROXY desc "max connections per proxy"
kazoo.ws_connections_via_proxy_only = WS_CONNECTIONS_FROM_PROXY_ONLY desc "only allow connections via proxy"
event_route[xhttp:request]
{
set_reply_close();
set_reply_no_connect();
if (!($rm =~ "GET")) {
xlog("L_INFO", "websocket|log|rejecting HTTP request $rm from $si:$sp\n");
xhttp_reply("405", "Method Not Allowed", "", "");
exit;
}
if (!($hdr(Connection) =~ "Upgrade")) {
xlog("L_INFO", "websocket|log|rejecting HTTP connection $hdr(Connection) request from $si:$sp\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
if (!($hdr(Upgrade) =~ "websocket")) {
xlog("L_INFO", "websocket|log|rejecting HTTP upgrade $hdr(Upgrade) request from $si:$sp\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
if (!($hdr(Sec-WebSocket-Protocol) =~ "sip")) {
xlog("L_INFO", "websocket|log|rejecting request for websocket protocol $hdr(Sec-WebSocket-Protocol) from $si:$sp\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
#!ifdef MY_WEBSOCKET_DOMAIN
if (!($hdr(Origin) =~ "MY_WEBSOCKET_DOMAIN")) {
xlog("L_INFO", "websocket|log|rejecting HTTP request with unauthorized origin $hdr(Origin) from $si:$sp, allowed origin is MY_WEBSOCKET_DOMAIN\n");
xhttp_reply("400", "Bad Request", "", "");
exit;
}
#!endif
if ($hdr(X-Forwarded-For) == $null) {
if($sel(cfg_get.kazoo.ws_connections_via_proxy_only) == 1) {
xlog("L_INFO", "websocket|log|request from $si without X-Forwarded-For Header and only allowed connections are via proxy\n");
xhttp_reply("403", "Forbidden", "", "");
exit;
} else {
$var(ws_orig_ip) = $si;
}
} else {
xlog("L_INFO", "websocket|log|request X-Forwarded-For $hdr(X-Forwarded-For) from $si\n");
$var(ws_orig_ip) = $hdr(X-Forwarded-For);
}
if($si != $var(ws_orig_ip)) {
if(!is_in_subnet($si, $sel(cfg_get.kazoo.ws_allowed_proxies))) {
xlog("L_WARNING", "websocket|log|request X-Forwarded-For $hdr(X-Forwarded-For) from invalid ip $si - allowed $sel(cfg_get.kazoo.ws_allowed_proxies)\n");
xhttp_reply("403", "Forbidden", "", "");
exit;
}
if($sel(cfg_get.kazoo.ws_max_connection_per_proxy) > 0 && $sht(websockets=>$si::count) > $sel(cfg_get.kazoo.ws_max_connection_per_proxy)) {
xlog("L_WARN", "websocket|log|$si is at the maximum $sel(cfg_get.kazoo.ws_max_connection_per_proxy) allowable sockets per PROXY IP, rejecting request for another websocket\n");
xhttp_reply("403", "Forbidden", "", "");
exit;
}
}
if($sel(cfg_get.kazoo.ws_max_connection_per_ip) > 0 && $sht(websockets=>$var(ws_orig_ip)::count) > $sel(cfg_get.kazoo.ws_max_connection_per_ip)) {
xlog("L_WARN", "websocket|log|$var(ws_orig_ip) is at the maximum $sel(cfg_get.kazoo.ws_max_connection_per_ip) allowable sockets per IP, rejecting request for another websocket\n");
xhttp_reply("403", "Forbidden", "", "");
exit;
}
if (ws_handle_handshake()) {
$var(count) = $shtinc(websockets=>$var(ws_orig_ip)::count);
$sht(websockets=>$ws_conid::ws_orig_ip) = $var(ws_orig_ip);
if($si != $var(ws_orig_ip)) {
$var(proxy_count) = $shtinc(websockets=>$si::count);
xlog("L_INFO", "websocket|log|opened proxied websocket $ws_conid from $si for $var(ws_orig_ip):$sp\n");
} else {
xlog("L_INFO", "websocket|log|opened websocket $ws_conid from $var(ws_orig_ip):$sp\n");
}
exit;
}
xlog("L_INFO", "websocket|log|unhandled HTTP request $rm from $si:$sp\n");
xhttp_reply("404", "Not Found", "", "");
}
event_route[websocket:closed]
{
$var(ws_orig_ip) = $sht(websockets=>$ws_conid::ws_orig_ip);
$sht(websockets=>$ws_conid::ws_orig_ip) = $null;
$var(count) = $shtdec(websockets=>$si::count);
if($var(ws_orig_ip) != $null && $si != $var(ws_orig_ip)) {
$var(countip) = $shtdec(websockets=>$var(ws_orig_ip)::count);
xlog("L_INFO", "websocket|log|$si closed proxied websocket $ws_conid for $var(ws_orig_ip):$sp\n");
if ($var(countip) < 1) $sht(websockets=>$var(ws_orig_ip)::count) = $null;
} else {
xlog("L_INFO", "websocket|log|closed websocket $ws_conid from $var(ws_orig_ip):$sp\n");
}
if ($var(count) < 1) $sht(websockets=>$si::count) = $null;
}

+ 21
- 0
kamailio-proxy-call/accounting-role.cfg View File

@ -0,0 +1,21 @@
####### Flags #######
#!trydef FLAG_ACC 13
#!trydef FLAG_ACCMISSED 14
#!trydef FLAG_ACCFAILED 15
######## Accounting module ########
loadmodule "acc.so"
######## Accounting params ########
modparam("acc", "early_media", 0)
modparam("acc", "report_ack", 0)
modparam("acc", "report_cancels", 1)
modparam("acc", "detect_direction", 0)
modparam("acc", "log_flag", 7)
modparam("acc", "log_level", 2)
modparam("acc", "log_missed_flag", 8)
modparam("acc", "failed_transaction_flag", 9)
modparam("acc", "log_extra",
"src_user=$fU;src_domain=$fd;src_ip=$si;"
"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
modparam("acc", "log_facility", "LOG_LOCAL6")

+ 273
- 0
kamailio-proxy-call/acl-role.cfg View File

@ -0,0 +1,273 @@
######## DoS prevention module ########
# Default "order" is "deny,allow".
# So if there is no data from DB request will be permitted by default.
#
modparam("htable", "htable", "acl=>initval=-1;autoexpire=7200")
#!trydef ACL_MESSAGE_DENY "Rejected by ACL"
#!trydef ACL_CODE_DENY "603"
#!trydef ACL_ORDER_ALLOW_DENY "allow,deny"
#!trydef ACL_IP_ADDR_ANY "0.0.0.0/0"
#!trydef IP_REGEX "[0-9]{1,3}\.[0-9]{1,3}.[0-9]{1,3}\.[0-9]{1,3}"
## Route for ACL functionality
route[ACL_CHECK] {
# If packet came from platform or from 4 class MERA, do not check it
if (isflagset(FLAG_INTERNALLY_SOURCED) || isflagset(FLAG_TRUSTED_SOURCE) ) {
xlog("L_DEBUG", "$ci|ACL|Trusted source IP($si) ignoring\n");
return;
}
if (isflagset(FLAG_IS_REPLY)) {
$var(sip-packet) = $rs;
} else {
$var(sip-packet) = $rm;
}
# FIX for BYE method with IP instead of REALM in From, take REALM from To header
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci|ACL-realm|Fix for $var(sip-packet) with IP in from URI: use to-domain\n");
$var(realm) = $td;
} else {
$var(realm) = $fd;
}
$var(acl-realm-request) = "false";
$var(acl-device-request) = "false";
$var(realm-decision) = $sht(acl=>$var(realm)/$si);
if ($var(realm-decision) == -1) { # we do not have cached decision
$var(acl-realm-request) = "true";
} else if ($var(realm-decision) == 1 ){ # We have cached decision, let's use it
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
} else {
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
if (not_empty("$fU")) {
if ($fd =~ IP_REGEX) {
xlog("L_WARNING","$ci|ACL-device|Fix for $var(sip-packet) with IP in from URI: use to-domain\n");
$var(device) = $fU + "@" + $td;
} else {
$var(device) = $fU + "@" + $fd;
}
$var(device-decision) = $sht(acl=>$var(device)/$si);
if ($var(device-decision) == -1) { # we do not have cached decision
$var(acl-device-request) = "true";
} else if ($var(device-decision) == 1 ){ # We have cached decision, let's use it
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
} else {
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
}
if ($var(acl-realm-request) == "true" || $var(acl-device-request) == "true") {
if (not_empty("$fU"))
$var(query) = "{'Event-Category': 'acl', 'Event-Name': 'query', 'Entity': '" + $var(device) + "', 'With-Realm': " + $var(acl-realm-request) + "}";
else
$var(query) = "{'Event-Category': 'acl', 'Event-Name': 'query', 'Entity': '" + $var(realm) + "'}";
xlog("L_DBG", "$ci|ACL log|Query: $var(query)\n");
sl_send_reply("100", "Attempting K query");
if (kazoo_query("frontier", "sbc_config", $var(query), "$var(acl-response)")) {
xlog("L_DBG", "$ci|ACL log|Response: $var(acl-response)\n");
kazoo_json($var(acl-response), "Realm.Order", "$var(acl-realm-order)");
kazoo_json($var(acl-response), "Realm.CIDR", "$var(acl-realm-cidr)");
kazoo_json($var(acl-response), "Device.Order", "$var(acl-device-order)");
kazoo_json($var(acl-response), "Device.CIDR", "$var(acl-device-cidr)");
kazoo_json($var(acl-response), "Device.User-Agent", "$var(acl-device-ua)");
} else {
xlog("L_ERROR","$ci|ACL log|DB is unreachable\n");
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}
route(ACL_CHECK_REALM);
if (not_empty("$fU")) {
route(ACL_CHECK_DEVICE);
}
}
}
# Check ORDER setting for REALM
route[ACL_CHECK_REALM] {
if (not_empty("$var(acl-realm-order)")) {
if ($var(acl-realm-order) == ACL_ORDER_ALLOW_DENY) {
route(ACL_CHECK_REALM_ALLOW);
} else {
route(ACL_CHECK_REALM_DENY);
}
} else {
xlog("L_INFO","$ci|ACL-realm|undefined Order in response for $var(realm)\n");
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
}
}
route[ACL_CHECK_REALM_ALLOW] {
if (not_empty("$var(acl-realm-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-realm|checking if $si is in $var(record)\n");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
return;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-realm|undefined CIDR in response for $var(realm)\n");
}
# Remember in CACHE and DENY
$sht(acl=>$var(realm)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
route[ACL_CHECK_REALM_DENY] {
$var(size) = $(kzR{kz.json,Realm.CIDR.length});
if (not_empty("$var(acl-realm-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-realm|checking if $si is in $var(record)\n");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(realm)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(realm)\n");
exit;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Realm.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-realm|undefined CIDR in response for $var(realm)\n");
}
# Remember in CACHE and ALLOW
$sht(acl=>$var(realm)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(realm)\n");
return;
}
# Check ORDER setting for DEVICE
route[ACL_CHECK_DEVICE] {
if (not_empty("$var(acl-device-order)")) {
if ($var(acl-device-order) == ACL_ORDER_ALLOW_DENY) {
route(ACL_CHECK_DEVICE_ALLOW);
} else {
route(ACL_CHECK_DEVICE_DENY);
}
} else {
xlog("L_INFO","$ci|ACL-device|undefined Order in response for $var(device)\n");
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
}
}
route[ACL_CHECK_DEVICE_ALLOW] {
if (!not_empty("$var(acl-device-ua)") || (not_empty("$var(acl-device-ua)") && $ua =~ $var(acl-device-ua))) {
if (not_empty("$var(acl-device-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-realm|checking if $si is in $var(record)\n");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-realm|undefined CIDR in response for $var(device)\n");
}
}
# Remember in CACHE and DENY
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
route[ACL_CHECK_DEVICE_DENY] {
if (not_empty("$var(acl-device-ua)") && !($ua =~ $var(acl-device-ua))) {
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
if (not_empty("$var(acl-device-cidr)")) {
$var(i) = 0;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
while(not_empty("$var(record)")) {
xlog("L_INFO", "$ci|ACL-device|checking if $si is in $var(record)\n");
if (($var(record) == ACL_IP_ADDR_ANY) || is_in_subnet("$si", $var(record))) {
$sht(acl=>$var(device)/$si) = 0;
if (!isflagset(FLAG_IS_REPLY)) {
sl_send_reply(ACL_CODE_DENY, ACL_MESSAGE_DENY);
}
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is rejected by ACL for $var(device)\n");
exit;
}
$var(i) = $var(i) + 1;
kazoo_json($var(acl-response), "Device.CIDR[$var(i)]", "$var(record)");;
}
} else {
xlog("L_INFO", "$ci|ACL-device|undefined CIDR in response for $var(device)\n");
}
# Remember in CACHE and ALLOW
$sht(acl=>$var(device)/$si) = 1;
xlog("L_INFO", "$ci|ACL|$var(sip-packet) from $si is permitted by ACL for $var(device)\n");
return;
}
event_route[kazoo:consumer-event-acl-acl-flush]
{
if( $(kzE{kz.json,Device}) != "" ) {
$var(device_regexp) = $(kzE{kz.json,Device}) + "@" + $(kzE{kz.json,Realm}) + "/.*" ;
xlog("L_INFO","|ACL-Flush| Flush ACL for Device. Regexp: $var(device_regexp)\n");
sht_rm_name_re("acl=>$var(device_regexp)");
} else {
$var(realm_regexp) = "^" + $(kzE{kz.json,Realm}) + "/.*" ;
xlog("L_INFO","|ACL-Flush| Flush ACL for Realm. Regexp: $var(realm_regexp)\n");
sht_rm_name_re("acl=>$var(realm_regexp)");
}
}
route[ACL_BINDINGS]
{
$var(payload) = $_s({"name": "acl-role", "exchange" : "frontier_acl" , "type" : "topic", "queue" : "FRONTIERACL-FLUSH-MY_HOSTNAME", "routing" : "flush" });
kazoo_subscribe("$var(payload)");
}

+ 140
- 0
kamailio-proxy-call/antiflood-role.cfg View File

@ -0,0 +1,140 @@
#!trydef ANTIFLOOD_RATE_WINDOW 2
#!trydef ANTIFLOOD_RATE_DENSITY 50
#!trydef ANTIFLOOD_RATE_EXPIRE 4
#!trydef ANTIFLOOD_FAILED_AUTH_WINDOW 300
#!trydef ANTIFLOOD_FAILED_AUTH_DENSITY 4
#!trydef ANTIFLOOD_FAILED_AUTH_USE_PORT 1
#!trydef ANTIFLOOD_FAILED_AUTH_ACTION 2
#!trydef ANTIFLOOD_RATE_LIMIT_ENABLED 1
#!trydef ANTIFLOOD_AUTH_LIMIT_ENABLED 1
#!trydef ANTIFLOOD_RATE_DROP 1
#!trydef ANTIFLOOD_CACHE_PERIOD 300
#!substdef "!ANTIFLOOD_SUBST_CACHE_PERIOD!$def(ANTIFLOOD_CACHE_PERIOD)!g"
######## Flood Prevention Hash Tables ########
modparam("htable", "htable", "antiflood=>size=16;autoexpire=ANTIFLOOD_SUBST_CACHE_PERIOD;initval=0")
######## Flood Prevention Module ########
loadmodule "pike.so"
modparam("pike", "sampling_time_unit", ANTIFLOOD_RATE_WINDOW)
modparam("pike", "reqs_density_per_unit", ANTIFLOOD_RATE_DENSITY)
modparam("pike", "remove_latency", ANTIFLOOD_RATE_EXPIRE)
kazoo.antiflood_failed_auth_use_port = ANTIFLOOD_FAILED_AUTH_USE_PORT descr "should we keep track of ip and port for auth failures"
kazoo.antiflood_failed_auth_action = ANTIFLOOD_FAILED_AUTH_ACTION descr "0 - log, 1 - drop, 2 - reply with 403"
kazoo.antiflood_rate_limit_enabled = ANTIFLOOD_RATE_LIMIT_ENABLED descr "antiflood rate limit enabled"
kazoo.antiflood_auth_limit_enabled = ANTIFLOOD_AUTH_LIMIT_ENABLED descr "antiflood auth limit enabled"
kazoo.antiflood_rate_drop = ANTIFLOOD_RATE_DROP descr "should we drop on rate limit"
route[ANTIFLOOD_LIMIT]
{
if($sel(cfg_get.kazoo.antiflood_rate_limit_enabled) == 1) {
route(ANTIFLOOD_RATE_LIMIT);
}
if($sel(cfg_get.kazoo.antiflood_auth_limit_enabled) == 1) {
route(ANTIFLOOD_AUTH_LIMIT);
}
}
route[ANTIFLOOD_RATE_LIMIT]
{
if (has_totag()
|| isflagset(FLAG_TRUSTED_SOURCE)
|| isflagset(FLAG_INTERNALLY_SOURCED)) {
return;
}
# use pike to control the rates
if (!pike_check_req()) {
if($sel(cfg_get.kazoo.antiflood_rate_drop) == 1) {
xlog("L_WARN", "$ci|end|dropping request from $fu due to rate of requests with source $si:$sp\n");
drop();
} else {
xlog("L_WARN", "$ci|allowed|request from $fu exceeded rate of requests with source $si:$sp\n");
}
}
}
route[ANTIFLOOD_AUTH_LIMIT]
{
if (has_totag()
|| isflagset(FLAG_TRUSTED_SOURCE)
|| isflagset(FLAG_INTERNALLY_SOURCED)) {
return(1);
}
$var(auth_key) = "";
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) {
$var(auth_key) = $_s("$Au::$si::$sp");
} else {
$var(auth_key) = $_s("$Au::$si");
}
if ($Au != $null &&
$sht(antiflood=>$var(auth_key)::count) >= ANTIFLOOD_FAILED_AUTH_DENSITY
) {
$shtex(antiflood=>$var(auth_key)::count) = ANTIFLOOD_FAILED_AUTH_WINDOW;
$sht(antiflood=>$var(auth_key)::last) = $Ts;
if($sel(cfg_get.kazoo.antiflood_failed_auth_action) == 1) {
xlog("L_WARNING", "$ci|end|dropping request authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
drop();
} else if($sel(cfg_get.kazoo.antiflood_failed_auth_action) == 2) {
xlog("L_NOTICE", "$ci|end|authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
append_to_reply("Retry-After: 3600\r\n");
send_reply("403", "Forbidden");
exit;
} else {
xlog("L_NOTICE", "$ci|log|authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
}
}
}
route[ANTIFLOOD_SUCCESSFUL_AUTH]
{
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) {
sht_rm_name_re("antiflood=>$(Au{re.subst,/\\./\\\\./g})::$(si{re.subst,/\\./\\\\./g})::$sp::.*");
} else {
sht_rm_name_re("antiflood=>$(Au{re.subst,/\\./\\\\./g})::$(si{re.subst,/\\./\\\\./g})::.*");
}
}
route[ANTIFLOOD_RESET_AUTH]
{
$var(user) = $(kzE{kz.json,Username}) + "@" + $(kzE{kz.json,Realm});
sht_rm_name_re("antiflood=>$(var(user){re.subst,/\\./\\\\./g})::.*");
}
route[ANITFLOOD_FAILED_AUTH]
{
if (isflagset(FLAG_TRUSTED_SOURCE)) {
return;
}
$var(auth_key) = "";
if($sel(cfg_get.kazoo.antiflood_failed_auth_use_port) == 1) {
$var(auth_key) = $_s("$Au::$si::$sp");
} else {
$var(auth_key) = $_s("$Au::$si");
}
$var(count) = $shtinc(antiflood=>$var(auth_key)::count);
$sht(antiflood=>$var(auth_key)::last) = $Ts;
xlog("L_INFO", "$ci|log|$var(count) errounous authorization response for $Au $si:$sp\n");
if ($var(count) >= ANTIFLOOD_FAILED_AUTH_DENSITY) {
$var(exp) = $Ts - ANTIFLOOD_FAILED_AUTH_WINDOW;
if($sht(antiflood=>$var(auth_key)::last) > $var(exp)) {
xlog("L_NOTICE", "$ci|end|request at authorization failure limit $def(ANTIFLOOD_FAILED_AUTH_DENSITY) for $Au $si:$sp\n");
append_to_reply("Retry-After: 3600\r\n");
send_reply("403", "Forbidden");
exit;
}
}
}
event_route[htable:expired:antiflood]
{
xlog("L_NOTICE", "antiflood expired record $shtrecord(key) => $shtrecord(value)\n");
}

+ 130
- 0
kamailio-proxy-call/auth.cfg View File

@ -0,0 +1,130 @@
route[AUTH]
{
if (!is_method("INVITE|MESSAGE|REFER")) {
return;
}
#!ifdef DISPATCHER_ROLE
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(SETUP_AUTH_HEADERS);
}
#!endif
}
route[AUTH_HEADERS]
{
remove_hf_re("^X-");
if (!is_method("INVITE|MESSAGE|REFER")) {
return;
}
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(c) = $var(c) - 1;
}
}
route[AUTH_HEADERS_JSON]
{
xavp_params_implode("hf", "$var(outx)");
$var(out) = $(var(outx){re.subst,/^(.*);$$/\1/});
$var(c) = $(var(out){param.count});
$var(headers_json) = "";
$var(sep) = "";
xlog("L_DEBUG", "$ci|auth|headers $var(c) => $var(out) => $var(outx)\n");
while($var(c) > 0) {
$var(idx) = $var(c) - 1;
xlog("L_DEBUG", "$ci|auth|adding $(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\n");
append_hf("$(var(out){param.name,$var(idx)}): $(var(out){param.valueat,$var(idx)}{s.unescape.param})\r\n");
$var(headers_json) = $_s($var(headers_json)$var(sep)"$(var(out){param.name,$var(idx)})" : "$(var(out){param.valueat,$var(idx)}{s.unescape.param})");
$var(c) = $var(c) - 1;
$var(sep) = " , ";
}
$var(headers_json) = $_s({ $var(headers_json) });
}
route[SETUP_AUTH_HEADERS]
{
$xavp(hf=>X-AUTH-IP) = $si;
$xavp(hf[0]=>X-AUTH-PORT) = $sp;
#!ifdef REGISTRAR_ROLE
$avp(is_registered) = "false";
$xavp(regcfg=>match_received) = $su;
if (registered("location","$fu", 2, 1) != 1) return;
$avp(is_registered) = "true";
#!ifdef WITH_AUTH_TOKEN
route(AUTH_TOKEN);
#!else
route(AUTH_CCVS);
#!endif
#!endif
}
#!ifdef REGISTRAR_ROLE
route[AUTH_TOKEN]
{
if($(xavp(ulattrs=>token){s.len}) > 0) {
$xavp(hf[0]=>X-AUTH-Token) = $xavp(ulattrs=>token);
} else {
if($(xavp(ulattrs=>Authorizing-ID){s.len}) > 0 && $(xavp(ulattrs=>Account-ID){s.len})) {
$xavp(hf[0]=>X-AUTH-Token) = $_s($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID})@$(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}));
}
}
}
route[AUTH_CCVS]
{
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}{s.len}) > 0 && $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type}{s.len}) > 0)
$xavp(hf[0]=>X-AUTH-Token) = $_s($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID})@$(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}));
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Authorizing-Type) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-Type});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Authorizing-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Authorizing-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Username}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Username) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Username});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Realm}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Realm) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Realm});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-Realm) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Realm});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Account-Name) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Account-Name}{s.escape.param});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Presence-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Presence-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Owner-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Owner-ID});
if($(xavp(ulattrs=>custom_channel_vars){kz.json,Hotdesk-Current-ID}{s.len}) > 0)
$xavp(hf[0]=>X-ecallmgr_Hotdesk-Current-ID) = $(xavp(ulattrs=>custom_channel_vars){kz.json,Hotdesk-Current-ID});
}
#!endif

+ 23
- 0
kamailio-proxy-call/authorization-role.cfg View File

@ -0,0 +1,23 @@
## to be enhanced
route[AUTHORIZATION_CHECK]
{
if (!is_method("MESSAGE|NOTIFY|SUBSCRIBE|PUBLISH"))
return;
if(has_totag())
return;
if (isflagset(FLAG_INTERNALLY_SOURCED))
return;
if (isflagset(FLAG_TRUSTED_SOURCE))
return;
$xavp(regcfg=>match_received) = $su;
if(!(registered("location", "$fu", 2, 1) == 1 && $(xavp(ulattrs=>custom_channel_vars){s.len}) > 1)) {
xlog("L_INFO", "$ci|log|not authorized $fu from $si:$sp\n");
send_reply("503", "Not Registered");
exit;
}
}

+ 39
- 0
kamailio-proxy-call/blocker-role.cfg View File

@ -0,0 +1,39 @@
######## BLOCK BY IP[PORT] ########
#!trydef KZ_BLOCK_ENABLE 1
#!trydef KZ_BLOCK_LOG_LEVEL 1
#!trydef KZ_BLOCK_LOG_BUFFER 0
#!trydef KZ_BLOCK_DRY_RUN 0
#!ifdef KZ_BLOCK_COLD_CACHE
#!substdef "!BLOCK_S_WARM_CACHE!!g"
#!else
#!substdef "!BLOCK_S_WARM_CACHE!dbtable=block_cache;dbmode=1;!g"
#!endif
modparam("htable", "htable", "block=>size=8;BLOCK_S_WARM_CACHE")
modparam("statistics","variable", "block:blocked_requests")
kazoo.block_enable = KZ_BLOCK_ENABLE descr "enable block processing"
kazoo.block_log_level = KZ_BLOCK_LOG_LEVEL descr "block log level"
kazoo.block_log_buffer = KZ_BLOCK_LOG_BUFFER descr "log the received buffer"
kazoo.block_dry_run = KZ_BLOCK_DRY_RUN descr "log but keep processing"
## global param to enable route
received_route_mode=1
event_route[core:msg-received]
{
if($sel(cfg_get.kazoo.block_enable) == 1) {
if($sht(block=>$rcv(srcip)) || $sht(block=>$rcv(srcip)::$rcv(srcport))) {
if($sel(cfg_get.kazoo.block_log_buffer) == 1) {
xlog("$(sel(cfg_get.kazoo.block_log_level){s.int})", "|block|request from [$rcv(srcip):$rcv(srcport)] to [$rcv(rcvip):$rcv(rcvport)] was blocked => [$rcv(buf)]\n");
} else {
xlog("$(sel(cfg_get.kazoo.block_log_level){s.int})", "|block|request from [$rcv(srcip):$rcv(srcport)] to [$rcv(rcvip):$rcv(rcvport)] was blocked\n");
}
if($sel(cfg_get.kazoo.block_dry_run) == 0) {
drop;
}
}
}
}

+ 1
- 0
kamailio-proxy-call/certs/.placeholder View File

@ -0,0 +1 @@
ensure certs directory gets created

+ 14
- 0
kamailio-proxy-call/db_kazoo.cfg View File

@ -0,0 +1,14 @@
#### db_kazoo module ###
#!trydef KZ_DB_HOOK_TRACE 1
#!trydef KZ_DB_TRACE 0
#!trydef KZ_DB_TRACE_LOG_LEVEL 3
#!trydef KZ_DB_TRACE_FILTER 110
loadmodule "db_kazoo.so"
modparam("db_kazoo", "trace_hook", KZ_DB_HOOK_TRACE)
modparam("db_kazoo", "trace_enable", KZ_DB_TRACE)
modparam("db_kazoo", "trace_log_level", KZ_DB_TRACE_LOG_LEVEL)
modparam("db_kazoo", "trace_filter", KZ_DB_TRACE_FILTER)
include_file "db_queries_kazoo.cfg"

+ 4
- 0
kamailio-proxy-call/db_mysql.cfg View File

@ -0,0 +1,4 @@
#### db_mysql module ###
loadmodule "db_mysql.so"
include_file "db_queries_mysql.cfg"

+ 4
- 0
kamailio-proxy-call/db_postgres.cfg View File

@ -0,0 +1,4 @@
#### db_postgres module ###
loadmodule "db_postgres.so"
include_file "db_queries_postgres.cfg"

+ 33
- 0
kamailio-proxy-call/db_queries_kazoo.cfg View File

@ -0,0 +1,33 @@
####### Database queries ########
#!substdef "!KZQ_CHECK_MEDIA_SERVER_INSERT!insert into dispatcher (setid, destination, flags, attrs, description) select \$var(SetId), \"\$var(MediaUrl)\", \$var(flags), \"\$var(attrs)\", \"added by nodes role\" where not exists(select * from dispatcher where destination = \"\$var(MediaUrl)\")!g"
#!substdef "!KZQ_COUNT_ALL_SUBSCRIBERS!select a.event, count(distinct watcher_uri) count_unique, count(*) count from event_list a left outer join active_watchers b on a.event = b.event group by a.event!g"
#!substdef "!KZQ_COUNT_PRESENTITIES!select event, (select count(*) from presentity b where username = \"\$(var(payload){kz.json,From}{uri.user})\" and domain = \"\$(var(payload){kz.json,From}{uri.domain})\" and b.event = a.event) count from event_list a!g"
#!substdef "!KZQ_COUNT_SUBSCRIBERS!select event, (select count(*) from active_watchers b where presentity_uri = \"\$var(presentity)\" and b.event = a.event) count from event_list a union all select \"self\", count(distinct callid) from presentities where presentity_uri = \"\$var(presentity)\" and callid <> \"\$var(callid)\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_EVENT_PRESENCE_RESET_DELETE!delete from presentity where domain=\"\$(kzE{kz.json,Realm})\" and username = \"\$(kzE{kz.json,Username})\"!g"
#!substdef "!KZQ_HANDLE_NEW_SUBSCRIBE_DELETE1!delete from active_watchers where callid = \"\$ci\"!g"
#!substdef "!KZQ_HANDLE_NEW_SUBSCRIBE_DELETE2!delete from active_watchers where presentity_uri=\"\$var(presentity_uri)\" and event=\"\$hdr(Event)\" and watcher_username=\"\$fU\" and to_user=\"\$tU\" and watcher_domain=\"\$fd\"!g"
#!substdef "!KZQ_PRESENCE_SEARCH_SUMMARY!select * from active_watchers where to_domain = \"\$var(Domain)\"!g"
#!substdef "!KZQ_PRESENCE_SEARCH_DETAIL!select a.*, b.time, b.result, b.sent_msg, b.received_msg from active_watchers a left outer join active_watchers_log b on a.presentity_uri = b.presentity_uri and a.event = b.event and a.callid = b.callid where a.presentity_uri = \"\$var(presentity_uri)\" !g"
#!substdef "!KZQ_HAS_PRESENTITY!select count(*) as count from presentity where username = \"\$subs(to_user)\" and domain = \"\$subs(to_domain)\" and event = \"\$subs(event)\"!g"
#!substdef "!KZQ_REPLACE_WATCHERS_LOG!REPLACE INTO active_watchers_log (presentity_uri, watcher_username, watcher_domain, event, callid, to_user, to_domain, user_agent, time, result, sent_msg, received_msg) VALUES (\"\$subs(uri)\", \"\$subs(watcher_username)\", \"\$subs(watcher_domain)\", \"\$subs(event)\",\"\$subs(callid)\",\"\$subs(to_user)\",\"\$subs(to_domain)\", '\$(subs(user_agent){s.escape.common}{s.replace,\\\',''}{s.replace,\$\$,})', \$TS, \$notify_reply(\$rs), '\$(mb{s.escape.common}{s.replace,\\\',''}{s.replace,\$\$,})', '\$(notify_reply(\$mb){s.escape.common}{s.replace,\\\',''}{s.replace,\$\$,})')!g"
# # #!substdef "!KZQ_RESET_PUBLISHER_UPDATE!update active_watchers set expires = \$TS where id in (select b.id from presentity a inner join active_watchers b on a.username = b.to_user and a.domain = b.to_domain and a.event = b.event where a.sender = \"\$var(MediaUrl)\")!g"
#!substdef "!KZQ_RESET_PUBLISHER_UPDATE!INSERT INTO tmp_probe select distinct a.event, a.presentity_uri, 0 from presentities a inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where sender = \"\$var(MediaUrl)\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_PRESENCE_RESET!delete from presentity where sender = \"\$var(MediaUrl)\"!g"
# # #!substdef "!KZQ_RESET_ACCOUNT_UPDATE!update active_watchers set expires = \$TS where watcher_domain=\"\$(kzE{kz.json,Realm})\"!g"
#!substdef "!KZQ_RESET_ACCOUNT_UPDATE!INSERT INTO tmp_probe select distinct a.event, a.presentity_uri, 0 from presentities a inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where domain=\"\$(kzE{kz.json,Realm})\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_RESET_ACCOUNT_RESET!delete from presentity where domain=\"\$(kzE{kz.json,Realm})\"!g"
#!substdef "!KZQ_RESET_PUBLISHER_ZONE_UPDATE!INSERT INTO tmp_probe select distinct a.event, a.presentity_uri, 0 from presentities a inner join wdispatcher c on a.sender = c.destination inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where zone = \"\$var(Zone)\" and state in('early', 'confirmed', 'onthephone', 'busy', 'ringing')!g"
#!substdef "!KZQ_PRESENCE_ZONE_RESET!delete from presentity where id in(select a.id from presentities a join wdispatcher c on a.sender = c.destination where zone = \"\$var(Zone)\")!g"
#!substdef "!KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_EXPIRES!DELETE FROM active_watchers WHERE expires > 0 AND datetime(expires, 'unixepoch') < datetime('now', '-90 seconds')!g"
#!substdef "!KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_PRESENTITY!DELETE FROM ACTIVE_WATCHERS WHERE PRESENTITY_URI=\"\$subs(uri)\" AND EVENT=\"\$subs(event)\" AND FROM_USER = \"\$subs(from_user)\" AND FROM_DOMAIN=\"\$subs(from_domain)\" AND CALLID <> \"\$subs(callid)\"!g"
#!substdef "!KZQ_DELETE_FROM_PRESENTITY_WHERE_EXPIRES!DELETE FROM PRESENTITY WHERE expires > 0 AND datetime(expires, 'unixepoch') < datetime('now')!g"
#!substdef "!KZQ_DELETE_FROM_PRESENTITY_WHERE_DIALOG_TERMINATED!DELETE FROM PRESENTITY WHERE ID IN(select id from presentities where event = 'dialog' and state = 'terminated' and received < datetime('now', '-5 minutes'))!g"

kamailio/db_queries_kazoo.cfg → kamailio-proxy-call/db_queries_mysql.cfg View File


+ 23
- 0
kamailio-proxy-call/db_queries_postgres.cfg View File

@ -0,0 +1,23 @@
####### Database queries ########
#!substdef "!KZQ_CHECK_MEDIA_SERVER_INSERT!insert into dispatcher (setid, destination) select \$var(SetId), '\$var(MediaUrl)' where not exists(select * from dispatcher where destination = '\$var(MediaUrl)')!g"
#!substdef "!KZQ_COUNT_ALL_SUBSCRIBERS!select a.event, count(distinct watcher_username || '@' || watcher_domain) count_unique, count(*) count from event_list a, active_watchers b where b.event = a.event group by a.event!g"
#!substdef "!KZQ_COUNT_PRESENTITIES!select event, (select count(*) from presentity b where username = '\$(kzE{kz.json,From}{uri.user})' and domain = '\$(kzE{kz.json,From}{uri.domain})' and b.event = a.event) count from event_list a!g"
#!substdef "!KZQ_COUNT_SUBSCRIBERS!select event, (select count(*) from active_watchers b where presentity_uri = '\$var(presentity)' and b.event = a.event) count from event_list a!g"
#!substdef "!KZQ_EVENT_PRESENCE_RESET_DELETE!delete from presentity where domain='\$(kzE{kz.json,Realm})' and username = '\$(kzE{kz.json,Username})'!g"
#!substdef "!KZQ_HANDLE_NEW_SUBSCRIBE_DELETE1!delete from active_watchers where callid = '\$ci'!g"
#!substdef "!KZQ_HANDLE_NEW_SUBSCRIBE_DELETE2!delete from active_watchers where watcher_username='\$fU' and presentity_uri='\$var(presentity_uri)' and to_user='\$tU' and watcher_domain='\$fd' and event='\$hdr(Event)'!g"
#!substdef "!KZQ_RESET_ACCOUNT_DELETE!delete from presentity where domain='\$(kzE{kz.json,Realm})'!g"
#!substdef "!KZQ_RESET_ACCOUNT_UPDATE!update active_watchers set expires = \$TS where watcher_domain='\$(kzE{kz.json,Realm})'!g"
#!substdef "!KZQ_RESET_PUBLISHER_UPDATE!update active_watchers set expires = \$TS where id in (select b.id from presentity a inner join active_watchers b on a.username = b.to_user and a.domain = b.to_domain and a.event = b.event where a.sender = '\$var(MediaUrl)')!g"
#!substdef "!KZQ_PRESENCE_SEARCH_DETAIL!select * from active_watchers_log where presentity_uri = '\$var(presentity_uri)'!g"
#!substdef "!KZQ_PRESENCE_SEARCH_SUMMARY!select * from active_watchers where watcher_domain = '\$var(Domain)'!g"
#!substdef "!KZQ_PRESENCE_RESET!delete from presentity where sender = '\$var(MediaUrl)'!g"
#!substdef "!KZQ_REPLACE_WATCHERS_LOG!INSERT INTO active_watchers_log (presentity_uri, watcher_username, watcher_domain, event, callid, to_user, to_domain, user_agent, time, result, sent_msg, received_msg) VALUES ('\$subs(uri)', '\$subs(watcher_username)', '\$subs(watcher_domain)', '\$subs(event)','\$subs(callid)','\$subs(to_user)','\$subs(to_domain)', '\$(subs(user_agent){s.escape.common}{s.replace,\\\',''}{s.replace,\$\$,})', \$TS, \$notify_reply(\$rs), '\$(mb{s.replace,\\\',''}{s.replace,\$\$,''})', '\$(notify_reply(\$mb){s.replace,\\\',''}{s.replace,\$\$,''})') ON CONFLICT (presentity_uri, watcher_username, watcher_domain, event) DO UPDATE SET presentity_uri = excluded.presentity_uri, watcher_username = excluded.watcher_username, watcher_domain = excluded.watcher_domain, event = excluded.event!g"
#!substdef "!KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_EXPIRES!DELETE FROM active_watchers WHERE expires > 0 AND to_timestamp(expires) < now() - interval '90 seconds'!g"
#!substdef "!KZQ_DELETE_FROM_ACTIVE_WATCHERS_WHERE_PRESENTITY!DELETE FROM ACTIVE_WATCHERS WHERE PRESENTITY_URI='\$subs(uri)' AND EVENT='\$subs(event)' AND FROM_USER = '\$subs(from_user)' AND FROM_DOMAIN='\$subs(from_domain)' AND CALLID <> '\$subs(callid)'!g"
#!substdef "!KZQ_DELETE_FROM_PRESENTITY_WHERE_EXPIRES!DELETE FROM PRESENTITY WHERE expires > 0 AND to_timestamp(expires) < now()!g"
#!substdef "!KZQ_DELETE_FROM_PRESENTITY_WHERE_DIALOG_TERMINATED!DELETE FROM PRESENTITY WHERE ID IN(select id from presentities where event = 'dialog' and state = 'terminated' and received < now() - interval '5 minutes'))!g"
#!substdef "!KZQ_HAS_PRESENTITY!select count(*) as count from presentity where username = '\$subs(to_user)' and domain = '\$subs(to_domain)' and event = '\$subs(event)'!g"

+ 46
- 0
kamailio-proxy-call/db_scripts/check-kazoodb-sql.sh View File

@ -0,0 +1,46 @@
#!/bin/sh
TEMP_DB_LOCATION=/tmp/db
TEMP_DB=${TEMP_DB_LOCATION}/kazoo.db
rm -rf ${TEMP_DB_LOCATION}
. $(dirname $0)/kazoodb-sql.sh --source-only
file=$(sql_db_prepare)
sql_setup $file ${TEMP_DB_LOCATION}
DB_VERSION=`KazooDB -db ${TEMP_DB} "select sum(table_version) from version;"`
DB_CURRENT_DB=${DB_LOCATION:-/etc/kazoo/kamailio}/kazoo.db
DB_CURRENT_VERSION=`KazooDB -db ${DB_CURRENT_DB} "select sum(table_version) from version;"`
if [[ $DB_CURRENT_VERSION -ne $DB_VERSION ]]; then
echo "db required version is ${DB_VERSION}, existing version is ${DB_CURRENT_VERSION}, applying diff"
KazooDB-diff --schema ${DB_CURRENT_DB} ${TEMP_DB} | KazooDB -db ${DB_CURRENT_DB}
KazooDB-diff --primarykey --table version ${DB_CURRENT_DB} ${TEMP_DB} | KazooDB -db ${DB_CURRENT_DB}
KazooDB-diff --primarykey --table event_list ${DB_CURRENT_DB} ${TEMP_DB} | KazooDB -db ${DB_CURRENT_DB}
fi
for VIEW in `ls ${DB_SCRIPT_DIR}/vw_*.sql`; do
filename=$(basename -- "$VIEW")
filename="${filename%.*}"
viewname=${filename#*_}
v1=$(KazooDB -db ${DB_CURRENT_DB} "select sql from sqlite_master where type='view' and name='$viewname'" 2> /dev/null | tr -d ' ' | md5sum | cut -d ' ' -f1)
v2=$(cat $VIEW | tr -d ' ' | md5sum | cut -d ' ' -f1)
if [[ "$v1" != "$v2" ]]; then
echo "rebuilding view $viewname"
KazooDB -db ${DB_CURRENT_DB} "drop view if exists $viewname;"
KazooDB -db ${DB_CURRENT_DB} < $VIEW
fi
done
if [ -f ${DB_SCRIPT_DIR}/db_extra_check.sql ]; then
. ${DB_SCRIPT_DIR}/db_extra_check.sql --source-only
do_db_extra_check;
fi
for INIT in `ls ${DB_SCRIPT_DIR}/db_init_*.sql`; do
KazooDB -db ${DB_CURRENT_DB} < $INIT
done

+ 9
- 0
kamailio-proxy-call/db_scripts/create-kazoodb-sql.sh View File

@ -0,0 +1,9 @@
#!/bin/sh -e
. $(dirname $0)/kazoodb-sql.sh --source-only
file=$(sql_db_prepare)
echo "setting up kazoo db from init script $file"
sql_setup $file
exit 0

+ 34
- 0
kamailio-proxy-call/db_scripts/db_extra_check.sql View File

@ -0,0 +1,34 @@
do_db_extra_check() {
# location
if [[ $RESET_NON_UDP_ENABLED == "true" ]]; then
KazooDB -db ${DB_CURRENT_DB} "delete from location where socket not like 'udp:%';"
fi
##KazooDB -db ${DB_CURRENT_DB} "delete from location where expires > 0 and datetime(expires) < datetime('now', '-30 seconds');"
KazooDB -db ${DB_CURRENT_DB} "delete from location_attrs where not exists(select id from location where ruid = location_attrs.ruid);"
## presence
if [[ $RESET_NON_UDP_ENABLED == "true" ]]; then
KazooDB -db ${DB_CURRENT_DB} "delete from active_watchers where socket_info not like 'udp:%';"
fi
KazooDB -db ${DB_CURRENT_DB} "delete from active_watchers where expires > 0 and datetime(expires, 'unixepoch') < datetime('now', '-10 seconds');"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where expires > 0 AND datetime(expires, 'unixepoch') < datetime('now', '-10 seconds');"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where id in(select id from presentities where state in('terminated','available'));"
KazooDB -db ${DB_CURRENT_DB} "delete from active_watchers_log where id in(select id from active_watchers_log a where not exists(select callid from active_watchers b where b.callid = a.callid and b.watcher_username = a.watcher_username and b.watcher_domain = a.watcher_domain));"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where id in(select id from presentities a where not exists(select * from active_watchers where presentity_uri = a.presentity_uri));"
## notify watchers of pending calls
## 'create temp table as' because it will be dropped as soon as we ended the session
KazooDB -db ${DB_CURRENT_DB} "drop table if exists tmp_probe;"
KazooDB -db ${DB_CURRENT_DB} "create table tmp_probe as select distinct a.event, a.presentity_uri, cast(2 as integer) action from presentities a inner join active_watchers b on a.presentity_uri = b.presentity_uri and a.event = b.event where state in('early', 'confirmed', 'onthephone', 'busy');"
KazooDB -db ${DB_CURRENT_DB} "delete from presentity where id in(select id from presentities where state in('early', 'confirmed', 'onthephone', 'busy'));"
## keepalive
if [[ $RESET_NON_UDP_ENABLED == "true" ]]; then
KazooDB -db ${DB_CURRENT_DB} "delete from keepalive where sockinfo NOT LIKE 'udp%';"
fi
KazooDB -db ${DB_CURRENT_DB} "update keepalive set selected = 0, time_sent = datetime('now') where selected < 3;"
}

+ 14
- 0
kamailio-proxy-call/db_scripts/db_init_watcher_triggers.sql View File

@ -0,0 +1,14 @@
CREATE TRIGGER if not exists active_watchers_watcher_uri_insert
AFTER INSERT ON active_watchers
FOR EACH ROW
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;
CREATE TRIGGER if not exists active_watchers_watcher_uri_update
AFTER UPDATE ON active_watchers
FOR EACH ROW
WHEN OLD.watcher_username <> NEW.watcher_username OR OLD.watcher_domain <> NEW.watcher_domain
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;

+ 152
- 0
kamailio-proxy-call/db_scripts/db_kazoo-specific View File

@ -0,0 +1,152 @@
#!/bin/sh
sql_db_pre_setup() {
cat << EOF
PRAGMA foreign_keys=OFF;
PRAGMA wal=on;
PRAGMA journal_mode=WAL;
PRAGMA wal_autocheckpoint=25;
BEGIN TRANSACTION;
EOF
}
sql_setup() {
DB_KAZOO_LOCATION=${2:-${DB_KAZOO_LOCATION:-/etc/kazoo/kamailio/db}}
mkdir -p ${DB_KAZOO_LOCATION}
KazooDB -db ${DB_KAZOO_LOCATION}/kazoo.db < $1 > /dev/null
}
sql_header() {
cat << EOF
EOF
}
sql_extra_tables() {
cat << EOF
CREATE TABLE active_watchers_log (
id INTEGER PRIMARY KEY NOT NULL,
presentity_uri VARCHAR(128) NOT NULL COLLATE NOCASE,
watcher_username VARCHAR(64) NOT NULL COLLATE NOCASE,
watcher_domain VARCHAR(64) NOT NULL COLLATE NOCASE,
to_user VARCHAR(64) NOT NULL COLLATE NOCASE,
to_domain VARCHAR(64) NOT NULL COLLATE NOCASE,
event VARCHAR(64) DEFAULT 'presence' NOT NULL,
callid VARCHAR(255) NOT NULL,
time INTEGER NOT NULL,
result INTEGER NOT NULL,
sent_msg BLOB NOT NULL,
received_msg BLOB NOT NULL,
user_agent VARCHAR(255) DEFAULT '' COLLATE NOCASE,
CONSTRAINT active_watchers_active_watchers_log_idx UNIQUE (presentity_uri, watcher_username, watcher_domain, event)
);
INSERT INTO version (table_name, table_version) values ('active_watchers_log','1');
CREATE TABLE keepalive (
id INTEGER PRIMARY KEY NOT NULL,
contact VARCHAR(2048) NOT NULL COLLATE NOCASE,
received VARCHAR(32) NOT NULL COLLATE NOCASE,
sockinfo VARCHAR(128) NOT NULL COLLATE NOCASE,
time_inserted timestamp DEFAULT CURRENT_TIMESTAMP,
time_sent timestamp DEFAULT CURRENT_TIMESTAMP,
slot INTEGER NOT NULL,
selected INTEGER DEFAULT 0,
failed INTEGER DEFAULT 0,
CONSTRAINT keepalive_idx UNIQUE (contact),
CONSTRAINT keepalive_idx_2 UNIQUE (slot, failed, contact)
);
CREATE INDEX keepalive_idx_3 ON keepalive (slot, selected, time_sent);
CREATE INDEX keepalive_idx_4 ON keepalive (received, selected);
INSERT INTO version (table_name, table_version) values ('keepalive','4');
ALTER TABLE active_watchers ADD COLUMN watcher_uri varchar(64) NOT NULL DEFAULT "sip:no_watcher@no_domain";
CREATE TRIGGER active_watchers_watcher_uri_insert
AFTER INSERT ON active_watchers
FOR EACH ROW
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;
CREATE TRIGGER active_watchers_watcher_uri_update
AFTER UPDATE ON active_watchers
FOR EACH ROW
WHEN OLD.watcher_username <> NEW.watcher_username OR OLD.watcher_domain <> NEW.watcher_domain
BEGIN
UPDATE active_watchers SET watcher_uri = "sip:" || NEW.watcher_username || "@" || NEW.watcher_domain where id = NEW.id;
END;
CREATE UNIQUE INDEX active_watchers_contact ON active_watchers (contact, id);
CREATE INDEX active_watchers_event_watcher_uri ON active_watchers (event, watcher_uri);
CREATE INDEX location_attrs_ruid ON location_attrs (ruid);
CREATE UNIQUE INDEX location_ruid ON location (ruid);
create table auth_cache as select * from htable;
INSERT INTO version (table_name, table_version) select 'auth_cache', table_version from version where table_name = 'htable';
create table block_cache as select * from htable;
INSERT INTO version (table_name, table_version) select 'block_cache', table_version from version where table_name = 'htable';
create view presentities as select id, cast(printf("sip:%s@%s",username,domain) as varchar(64)) presentity_uri ,
username, domain, event, cast(substr(etag, instr(etag,"@")+1) as varchar(64)) callid,
datetime(received_time, 'unixepoch') as received,
datetime(expires, 'unixepoch') as expire_date,
expires, cast(sender as varchar(30)) sender,
lower(cast( case when event = "dialog"
then substr(body, instr(BODY,"<state>")+7, instr(body,"</state>") - instr(body,"<state>") - 7)
when event = "presence"
then case when instr(body,"<dm:note>") == 0
then replace(substr(body, instr(body,"<note>")+6, instr(body,"</note>") - instr(body,"<note>") - 6), " ", "")
else replace(substr(body, instr(body,"<dm:note>")+9, instr(body,"</dm:note>") - instr(body,"<dm:note>") - 9), " ", "")
end
when event = "message-summary"
then case when instr(body,"Messages-Waiting: yes") = 0
then "Waiting"
else "Not-Waiting"
end
end as varchar(12))) state
from presentity;
create view wdispatcher as select *,
cast(substr(attrs, instr(attrs, "zone=")+5, instr(attrs, ";profile")-instr(attrs, "zone=")-5) as varchar(20)) zone,
cast(substr(attrs, instr(attrs, "idx=")+4, instr(attrs, ";node")-instr(attrs, "idx=")-4) as integer) idx,
cast(substr(attrs, instr(attrs, "node=")+5) as varchar(50)) node
from dispatcher;
create unique index if not exists idx_dispatcher_destination on dispatcher(destination);
CREATE VIEW w_keepalive_contact as
SELECT id, slot, selected, failed, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from keepalive;
CREATE VIEW w_location_contact as
SELECT id, ruid, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from location;
CREATE VIEW w_watchers_contact as
select id, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from active_watchers;
EOF
}
sql_footer() {
cat << EOF
EOF
}

+ 5811
- 0
kamailio-proxy-call/db_scripts/kamailio_initdb_postgres.sql
File diff suppressed because it is too large
View File


+ 56
- 0
kamailio-proxy-call/db_scripts/kazoodb-sql.sh View File

@ -0,0 +1,56 @@
#!/bin/sh -e
KAMAILIO_SHARE_DIR=${KAMAILIO_SHARE_DIR:-/usr/share/kamailio}
DB_ENGINE=${DB_ENGINE:-db_kazoo}
RESULTED_SQL=${RESULTED_SQL:-/tmp/kamailio_initdb.sql}
. $(dirname $0)/$DB_ENGINE-specific --source-only
sql_filelist() {
echo `ls -A1 ${KAMAILIO_SHARE_DIR}/${DB_ENGINE}/*.sql | grep -v standard | tr '\n' '\0' | xargs -0 -n 1 basename | sort`
}
sql_all_header() {
cat << EOF
CREATE TABLE version (
table_name VARCHAR(32) NOT NULL,
table_version INTEGER DEFAULT 0 NOT NULL,
PRIMARY KEY(table_name)
);
INSERT INTO version VALUES('version',1);
EOF
}
sql_all_extra_tables() {
cat << EOF
CREATE TABLE event_list ( event varchar(25) PRIMARY KEY NOT NULL);
INSERT INTO event_list VALUES('dialog');
INSERT INTO event_list VALUES('presence');
INSERT INTO event_list VALUES('message-summary');
INSERT INTO version VALUES('event_list',1);
EOF
}
sql_all_footer() {
cat << EOF
COMMIT;
EOF
}
sql_db_prepare() {
sql_db_pre_setup > $RESULTED_SQL
sql_all_header >> $RESULTED_SQL
sql_header >> $RESULTED_SQL
for i in $(sql_filelist); do
cat $KAMAILIO_SHARE_DIR/$DB_ENGINE/$i >> $RESULTED_SQL
done
sql_all_extra_tables >> $RESULTED_SQL
sql_extra_tables >> $RESULTED_SQL
sql_footer >> $RESULTED_SQL
sql_all_footer >> $RESULTED_SQL
echo "$RESULTED_SQL"
}

+ 44
- 0
kamailio-proxy-call/db_scripts/mysql-specific View File

@ -0,0 +1,44 @@
#!/bin/sh
sql_db_pre_setup() {
cat << EOF
START TRANSACTION;
EOF
}
sql_setup() {
cat << EOF
EOF
}
sql_header() {
cat << EOF
EOF
}
sql_extra_tables() {
cat << EOF
CREATE TABLE active_watchers_log (
id SERIAL PRIMARY KEY NOT NULL,
presentity_uri VARCHAR(128) NOT NULL,
watcher_username VARCHAR(64) NOT NULL,
watcher_domain VARCHAR(64) NOT NULL,
to_user VARCHAR(64) NOT NULL,
to_domain VARCHAR(64) NOT NULL,
event VARCHAR(64) DEFAULT 'presence' NOT NULL,
callid VARCHAR(255) NOT NULL,
time INTEGER NOT NULL,
result INTEGER NOT NULL,
sent_msg BLOB NOT NULL,
received_msg BLOB NOT NULL,
user_agent VARCHAR(255) DEFAULT '' NOT NULL,
CONSTRAINT active_watchers_active_watchers_log_idx UNIQUE (presentity_uri, watcher_username, watcher_domain, event)
);
EOF
}
sql_footer() {
cat << EOF
ALTER TABLE location_attrs MODIFY avalue varchar(512);
EOF
}

+ 44
- 0
kamailio-proxy-call/db_scripts/postgres-specific View File

@ -0,0 +1,44 @@
#!/bin/sh
sql_db_pre_setup() {
cat << EOF
BEGIN TRANSACTION;
EOF
}
sql_setup() {
cat << EOF
EOF
}
sql_header() {
cat << EOF
EOF
}
sql_extra_tables() {
cat << EOF
CREATE TABLE active_watchers_log (
id SERIAL PRIMARY KEY NOT NULL,
presentity_uri VARCHAR(128) NOT NULL,
watcher_username VARCHAR(64) NOT NULL,
watcher_domain VARCHAR(64) NOT NULL,
to_user VARCHAR(64) NOT NULL,
to_domain VARCHAR(64) NOT NULL,
event VARCHAR(64) DEFAULT 'presence' NOT NULL,
callid VARCHAR(255) NOT NULL,
time INTEGER NOT NULL,
result INTEGER NOT NULL,
sent_msg BYTEA NOT NULL,
received_msg BYTEA NOT NULL,
user_agent VARCHAR(255) DEFAULT '' NOT NULL,
CONSTRAINT active_watchers_active_watchers_log_idx UNIQUE (presentity_uri, watcher_username, watcher_domain, event)
);
EOF
}
sql_footer() {
cat << EOF
ALTER TABLE location_attrs ALTER COLUMN avalue TYPE varchar(512);
EOF
}

+ 20
- 0
kamailio-proxy-call/db_scripts/vw_presentities.sql View File

@ -0,0 +1,20 @@
CREATE VIEW presentities as
select id, cast(printf("sip:%s@%s",username,domain) as varchar(64)) presentity_uri ,
username, domain, event, cast(substr(etag, instr(etag,"@")+1) as varchar(64)) callid,
datetime(received_time, 'unixepoch') as received,
datetime(expires, 'unixepoch') as expire_date,
expires, cast(sender as varchar(30)) sender,
lower(cast( case when event = "dialog"
then substr(body, instr(BODY,"<state>")+7, instr(body,"</state>") - instr(body,"<state>") - 7)
when event = "presence"
then case when instr(body,"<dm:note>") == 0
then replace(substr(body, instr(body,"<note>")+6, instr(body,"</note>") - instr(body,"<note>") - 6), " ", "")
else replace(substr(body, instr(body,"<dm:note>")+9, instr(body,"</dm:note>") - instr(body,"<dm:note>") - 9), " ", "")
end
when event = "message-summary"
then case when instr(body,"Messages-Waiting: yes") = 0
then "Waiting"
else "Not-Waiting"
end
end as varchar(12))) state
from presentity

+ 6
- 0
kamailio-proxy-call/db_scripts/vw_w_keepalive_contact.sql View File

@ -0,0 +1,6 @@
CREATE VIEW w_keepalive_contact as
select id, slot, selected, failed, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from keepalive

+ 6
- 0
kamailio-proxy-call/db_scripts/vw_w_location_contact.sql View File

@ -0,0 +1,6 @@
CREATE VIEW w_location_contact as
select id, ruid, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from location

+ 6
- 0
kamailio-proxy-call/db_scripts/vw_w_watchers_contact.sql View File

@ -0,0 +1,6 @@
CREATE VIEW w_watchers_contact as
select id, case when instr(contact,";") > 0
then substr(contact, 1, instr(contact,";")-1)
else contact
end as contact
from active_watchers

+ 6
- 0
kamailio-proxy-call/db_scripts/vw_wdispatcher.sql View File

@ -0,0 +1,6 @@
CREATE VIEW wdispatcher as
select *,
cast(substr(attrs, instr(attrs, "zone=")+5, instr(attrs, ";profile")-instr(attrs, "zone=")-5) as varchar(20)) zone,
cast(substr(attrs, instr(attrs, "duid=")+5, instr(attrs, ";node")-instr(attrs, "duid=")-5) as integer) idx,
cast(substr(attrs, instr(attrs, "node=")+5) as varchar(50)) node
from dispatcher

+ 970
- 0
kamailio-proxy-call/default.cfg View File

@ -0,0 +1,970 @@
## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
####### Flags #######
#!trydef FLAG_INTERNALLY_SOURCED 1
#!trydef FLAG_ASSOCIATE_SERVER 2
#!trydef FLAG_SKIP_NAT_CORRECTION 3
#!trydef FLAG_ASSOCIATE_USER 4
#!trydef FLAG_TRUSTED_SOURCE 5
#!trydef FLAG_SESSION_PROGRESS 6
#!trydef FLAG_IS_REPLY 7
#!trydef FLAG_SIP_TRACE 8
#!trydef FLT_AOR 9
#!trydef FLT_T38 10
#!trydef FLT_NATS 11
#!trydef FLAG_LOCAL_REQUEST 12
#!trydef FLAG_LOCAL_ROUTE 17
#!trydef FLAG_NETWORK_CLASSIFIED 18
####### Global Parameters #########
fork = yes
children = CHILDREN
server_signature = no
server_header = "Server: Kazoo"
user_agent_header = "User-Agent: Kazoo"
shm_force_alloc = yes
mlock_pages = yes
phone2tel = 1
max_while_loops = MAX_WHILE_LOOPS
pv_buffer_size = PV_BUFFER_SIZE
pv_buffer_slots = PV_BUFFER_SLOTS
mem_join=1
####### Logging Parameters #########
debug = KAZOO_LOG_LEVEL
memdbg = 10
memlog = L_BUG
corelog = L_ERR
mem_summary = KZ_MEM_SUMMARY
log_stderror = no
log_facility = LOG_LOCAL0
log_name="kamailio"
####### Alias Parameters #########
auto_aliases = yes
####### Binding Parameters #########
tos = IPTOS_LOWDELAY
####### TCP Parameters #########
tcp_children = TCP_CHILDREN
disable_tcp = no
tcp_max_connections = TCP_MAX_CONNECTIONS
tcp_connection_lifetime = TCP_CONNECTION_LIFETIME
tcp_accept_aliases = no
tcp_async = yes
tcp_connect_timeout = TCP_CONNECTION_TIMEOUT
tcp_conn_wq_max = 65536
tcp_crlf_ping = yes
tcp_delayed_ack = yes
tcp_fd_cache = yes
tcp_keepalive = TCP_KEEP_ALIVE
tcp_keepcnt = TCP_KEEP_COUNT
tcp_keepidle = TCP_KEEP_IDLE
tcp_keepintvl = TCP_KEEP_INTERVAL
tcp_linger2 = 30
tcp_rd_buf_size = 80000
tcp_send_timeout = TCP_SEND_TIMEOUT
tcp_wq_blk_size = 2100
tcp_wq_max = 10485760
####### UDP Parameters #########
udp4_raw = 0
#udp4_raw_mtu = 800
# # pmtu_discovery = no
#udp_mtu = 800
# #udp_mtu_try_proto = TCP
####### DNS Parameters #########
dns = no
rev_dns = no
dns_try_ipv6 = no
use_dns_cache = on
dns_cache_del_nonexp = yes
dns_cache_flags = 1
dns_cache_gc_interval = 120
dns_cache_init = 0
dns_cache_mem = 1000
dns_cache_negative_ttl = 60
dns_try_naptr = no
use_dns_failover = off
dns_srv_lb = off
####### SCTP Parameters #########
disable_sctp = yes
####### multi homed #########
mhomed=KZ_MULTI_HOMED
######## Kamailio mqueue module ########
loadmodule "mqueue.so"
######## Kamailio outbound module ########
loadmodule "outbound.so"
######## Kamailio stun module ########
loadmodule "stun.so"
######## Kamailio path module ########
loadmodule "path.so"
######## Kamailio control connector module ########
loadmodule "ctl.so"
modparam("ctl", "binrpc_buffer_size", 4096)
loadmodule "cfg_rpc.so"
######## Kamailio config utils module ########
loadmodule "cfgutils.so"
modparam("cfgutils", "lock_set_size", 4)
######## Kamailio corex module ########
loadmodule "corex.so"
######## Kamailio uuid module ########
loadmodule "uuid.so"
######## Kamailio core extensions module ########
loadmodule "kex.so"
######## Transaction (stateful) module ########
loadmodule "tm.so"
loadmodule "tmx.so"
modparam("tm", "auto_inv_100", 1)
modparam("tm", "auto_inv_100_reason", "Attempting to connect your call")
modparam("tm", "cancel_b_method", 2)
modparam("tm", "ruri_matching", 0)
modparam("tm", "failure_reply_mode", 3)
modparam("tm", "failure_exec_mode", 1)
modparam("tm", "reparse_on_dns_failover", 0)
# modparam("tm", "fr_timer", 30000)
# modparam("tm", "fr_inv_timer", 120000)
######## Stateless replier module ########
loadmodule "sl.so"
######## Record-Route and Route module ########
loadmodule "rr.so"
modparam("rr", "enable_full_lr", RR_FULL_LR)
modparam("rr", "enable_double_rr", RR_DOUBLE_RR)
modparam("rr", "force_send_socket", RR_FORCE_SOCKET)
######## Max-Forward processor module ########
loadmodule "maxfwd.so"
modparam("maxfwd", "max_limit", 50)
######## SIP utilities [requires sl] ########
loadmodule "siputils.so"
######## Text operations module ########
loadmodule "textopsx.so"
######## sdp operations module ########
loadmodule "sdpops.so"
######## Generic Hash Table container in shared memory ########
loadmodule "htable.so"
modparam("htable", "htable", "associations=>size=16;autoexpire=7200")
modparam("htable", "htable", "redirects=>size=16;autoexpire=5")
modparam("htable", "db_url", "KAZOO_DB_URL")
####### RTIMER module ##########
loadmodule "rtimer.so"
####### evrexec module ##########
loadmodule "evrexec.so"
modparam("evrexec", "exec", "name=evrexec:DEFERRED_INIT;wait=20000000;workers=1;")
######## Advanced logger module ########
loadmodule "xlog.so"
######## UAC ########
loadmodule "uac.so"
######## AVP's ########
loadmodule "avp.so"
loadmodule "avpops.so"
######## UAC Redirection module ########
loadmodule "uac_redirect.so"
#### json rpc ####
loadmodule "jsonrpcs.so"
####### SQL OPS module ##########
loadmodule "sqlops.so"
modparam("sqlops","sqlcon", "cb=>KAZOO_DB_URL")
modparam("sqlops","sqlcon", "exec=>KAZOO_DB_URL")
####### DEBUG ######
loadmodule "debugger.so"
modparam("debugger", "mod_hash_size", 5)
modparam("debugger", "mod_level_mode", 1)
modparam("debugger", "mod_level", "core=1")
####### STATISTICS ######
loadmodule "statistics.so"
####### DATABASE module ##########
include_file "db_KAMAILIO_DBMS.cfg"
###### kazoo bindings ######
include_file "kazoo-bindings.cfg"
####### Role Configurations ##########
#!ifdef AUTHORIZATION_ROLE
include_file "authorization-role.cfg"
#!endif
#!ifdef DISPATCHER_ROLE
include_file "dispatcher-role-MAJOR.cfg"
#!endif
#!ifdef REGISTRAR_ROLE
include_file "registrar-role.cfg"
#!endif
#!ifdef PRESENCE_ROLE
include_file "presence-role.cfg"
#!endif
#!ifdef DMQ_ROLE
include_file "dmq-role.cfg"
#!endif
#!ifdef MESSAGE_ROLE
include_file "message-role.cfg"
#!endif
#!ifdef NAT_TRAVERSAL_ROLE
include_file "nat-traversal-role.cfg"
#!endif
#!ifdef WEBSOCKETS_ROLE
include_file "websockets-role.cfg"
#!endif
#!ifdef TLS_ROLE
include_file "tls-role.cfg"
#!endif
#!ifdef ACCOUNTING_ROLE
include_file "accounting-role.cfg"
#!endif
#!ifdef ANTIFLOOD_ROLE
include_file "antiflood-role.cfg"
#!endif
#!ifdef TRAFFIC_FILTER_ROLE
include_file "traffic-filter-role.cfg"
#!endif
#!ifdef ACL_ROLE
include_file "acl-role.cfg"
#!endif
#!ifdef RATE_LIMITER_ROLE
include_file "rate-limiter-role.cfg"
#!endif
#!ifdef PUSHER_ROLE
include_file "pusher-role.cfg"
#!endif
#!ifdef RESPONDER_ROLE
include_file "responder-role.cfg"
#!endif
#!ifdef NODES_ROLE
include_file "nodes-role.cfg"
#!endif
#!ifdef SIP_TRACE_ROLE
include_file "sip_trace-role.cfg"
#!endif
#!ifdef KEEPALIVE_ROLE
include_file "keepalive-role.cfg"
#!endif
#!ifdef BLOCKER_ROLE
include_file "blocker-role.cfg"
#!endif
## sanity ##
include_file "sanity.cfg"
## auth ##
include_file "auth.cfg"
####### Permissions module ##########
loadmodule "permissions.so"
modparam("permissions", "db_url", "KAZOO_DB_URL")
modparam("permissions", "db_mode", 1)
###### local route ######
socket_workers=5
listen=tcp:127.0.0.1:5090
####### Routing Logic ########
route
{
route(LOCAL_REQUEST);
route(SANITY_CHECK);
route(CHECK_RETRANS);
#!ifdef ANTIFLOOD_ROLE
route(ANTIFLOOD_LIMIT);
#!endif
#!ifdef TRAFFIC_FILTER_ROLE
route(FILTER_REQUEST);
#!endif
#!ifdef ACL_ROLE
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER_ROLE
route(DOS_PREVENTION);
#!endif
route(LOG_REQUEST);
route(CLASSIFY_SOURCE);
#!ifdef NAT_TRAVERSAL_ROLE
route(NAT_DETECT);
#!endif
route(HANDLE_OPTIONS);
#!ifdef SIP_TRACE_ROLE
route(SIP_TRACE);
#!endif
route_if_exists("CUSTOM_START_ROUTES");
route(HANDLE_NOTIFY);
#!ifdef AUTHORIZATION_ROLE
route(AUTHORIZATION_CHECK);
#!endif
#!ifdef MESSAGE_ROLE
route(HANDLE_MESSAGE);
#!else
if (is_method("MESSAGE")) {
sl_send_reply("405", "Method Not Allowed");
exit;
}
#!endif
#!ifdef PRESENCE_ROLE
route(HANDLE_SUBSCRIBE);
route(HANDLE_PUBLISH);
#!endif
#!ifdef REGISTRAR_ROLE
route(HANDLE_REGISTER);
#!endif
#!ifdef DMQ_ROLE
route(HANDLE_DMQ);
#!endif
route(HANDLE_REFER);
route(HANDLE_IN_DIALOG_REQUESTS);
route(PREPARE_INITIAL_REQUESTS);
#!ifdef PUSHER_ROLE
route(PUSHER_ROUTE);
#!endif
#!ifdef RESPONDER_ROLE
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(HANDLE_RESPOND);
}
#!endif
route(AUTH);
route(SETUP);
}
#!trydef KZ_LOG_REQUEST_OPTIONS 0
kazoo.log_request_options = KZ_LOG_REQUEST_OPTIONS descr "log OPTIONS requests, default is 0 for preserving log size"
route[LOG_REQUEST]
{
if($sel(cfg_get.kazoo.log_request_options) == 0 && is_method("OPTIONS")) {
$var(log_request_level) = L_DBG;
} else {
$var(log_request_level) = L_INFO;
}
# log the basic info regarding this call
xlog("$var(log_request_level)", "$ci|start|received $pr request $rm $ou\n");
xlog("$var(log_request_level)", "$ci|log|source $si:$sp -> $RAi:$RAp\n");
xlog("$var(log_request_level)", "$ci|log|from $fu\n");
xlog("$var(log_request_level)", "$ci|log|to $tu\n");
}
route[CHECK_RETRANS]
{
# handle retransmissions
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}
}
route[CLASSIFY_SOURCE]
{
#!ifdef DISPATCHER_ROLE
route(DISPATCHER_CLASSIFY_SOURCE);
#!endif
if (allow_source_address(TRUSTED_ADR_GROUP)) {
xlog("$var(log_request_level)", "$ci|log|request from trusted IP\n");
setflag(FLAG_TRUSTED_SOURCE);
}
if (isflagset(FLAG_INTERNALLY_SOURCED) || is_myself($si)) {
setflag(FLAG_TRUSTED_SOURCE);
}
}
route[HANDLE_OPTIONS]
{
if (!is_method("OPTIONS")) {
return;
}
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC_FILTER_ROLE
if (!isflagset(FLAG_TRUSTED_SOURCE)) {
route(FILTER_REQUEST_DOMAIN);
}
#!endif
sl_send_reply("200", "Rawr!!");
#!ifdef KEEPALIVE_ROLE
route(KEEPALIVE_ON_OPTIONS);
#!endif
}
exit;
}
route[HANDLE_NOTIFY]
{
if (!is_method("NOTIFY")) return;
if (has_totag()) return;
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
if (loose_route()) {
xlog("L_INFO", "$ci|log|Able to loose-route. Cool beans!\n");
}
#!ifdef REGISTRAR_ROLE
if (registered("location")) {
lookup("location");
xlog("L_INFO", "$ci|log|routing to $ruid\n");
}
#!endif
## verify we're not routing to ourselves
if(is_myself($du)) {
xlog("L_INFO", "$ci|log|notify from internal to invalid destination $ruid\n");
sl_send_reply("200", "Rawr!!");
exit;
}
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
#!ifdef TRAFFIC_FILTER_ROLE
if (!isflagset(FLAG_TRUSTED_SOURCE)) {
route(FILTER_REQUEST_DOMAIN);
}
#!endif
if($hdr(Event) == "keep-alive") {
xlog("L_INFO", "$ci|stop|replying to keep alive\n");
sl_send_reply("405", "Stay Alive / Method Not Allowed");
} else {
xlog("L_INFO", "$ci|stop|consuming event $hdr(Event)\n");
sl_send_reply("200", "Rawr!!");
}
#!ifdef KEEPALIVE_ROLE
route(KEEPALIVE_ON_NOTIFY);
#!endif
}
exit;
}
route[HANDLE_REFER]
{
if (!is_method("REFER")) {
return;
}
if(is_present_hf("Referred-By")) {
$var(referred_by) = $hdr(Referred-By);
} else {
$var(referred_by) = $_s(<sip:$Au>;created=true);
}
route(AUTH);
if($avp(is_registered) = "true") {
$var(referred_by) = $_s($var(referred_by);endpoint_id=$(xavp(ulattrs=>token){re.subst,/(.*)@(.*)/\1/});account_id=$(xavp(ulattrs=>token){re.subst,/(.*)@(.*)/\2/}));
}
remove_hf_re("^Referred-By");
append_hf("Referred-By: $var(referred_by)\r\n");
}
route[HANDLE_IN_DIALOG_REQUESTS]
{
if (!has_totag()) return;
if (is_method("INVITE")) {
setflag(FLAG_SESSION_PROGRESS);
record_route();
}
if (loose_route()) {
#!ifdef NAT_TRAVERSAL_ROLE
if(!isdsturiset()) {
handle_ruri_alias();
}
if ( is_method("ACK") ) {
# ACK is forwarded statelessly
route(NAT_MANAGE);
}
#!endif
#!ifdef ACCOUNTING_ROLE
if (is_method("BYE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
xlog("L_INFO", "$ci|log|loose_route in-dialog message\n");
# Called on in-dialog requests
# If the request in an Invite for on hold from external to internal,
# associate the contact with the media server
# if Invite for on hold, we need to associate the contact URI with the next hop
if (is_method("INVITE") && !isflagset(FLAG_INTERNALLY_SOURCED) && is_audio_on_hold()) {
setflag(FLAG_ASSOCIATE_USER);
}
# If the request in an Invite for t38 from internal,
# mark the request with FLT_T38
if (is_method("INVITE") && isflagset(FLAG_INTERNALLY_SOURCED) && sdp_with_media("image")) {
xlog("L_DEBUG", "$ci|log|T38 RE-INVITE\n");
setflag(FLT_T38);
}
if ( is_method("NOTIFY") ) {
# Add Record-Route for in-dialog NOTIFY as per RFC 6665.
record_route();
}
route(RELAY);
} else if (isflagset(FLAG_INTERNALLY_SOURCED)) {
xlog("L_INFO", "$ci|log|relay internally sourced in-dialog message without loose_route\n");
route(RELAY);
} else if (t_check_trans()) {
xlog("L_INFO", "$ci|log|allow message for a known transaction\n");
route(RELAY);
} else {
xlog("L_INFO", "$ci|log|message had a to-tag but can't be loose routed\n");
sl_send_reply("481", "Call Leg/Transaction Does Not Exist");
}
exit();
}
route[PREPARE_INITIAL_REQUESTS]
{
if (is_method("CANCEL")) {
if (t_check_trans()) {
route(RELAY);
} else {
sl_send_reply("481", "Call leg/transaction does not exist");
}
exit();
} else if (is_method("ACK")) {
if (t_check_trans()) {
route(RELAY);
}
exit();
}
if (is_method("UPDATE")) {
xlog("L_WARN", "$ci|end|update outside dialog not allowed\n");
send_reply("403", "Dialog does not exist");
break;
}
if (is_method("BYE|PRACK")) {
xlog("L_WARN", "$ci|end|originating subsequent requests outside dialog not allowed\n");
send_reply("403", "Dialog does not exist");
break;
}
## if (loose_route()) {
## #!ifdef REGISTRAR_ROLE
## $xavp(regcfg=>match_received) = $su;
## if(registered("location", "$rz:$Au", 2) == 1) {
## xlog("L_INFO", "$ci|log|allowing initial route-set for $Au\n");
## } else {
## #!endif
## xlog("L_WARN", "$ci|end|dropping initial request with route-set\n");
## sl_send_reply("403", "No pre-loaded routes");
## exit();
## #!ifdef REGISTRAR_ROLE
## }
## #!endif
## }
record_route();
}
route[SETUP]
{
#!ifdef DISPATCHER_ROLE
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(DISPATCHER_FIND_ROUTES);
}
#!endif
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(ROUTE_TO_AOR);
forward();
}
route(RELAY);
}
route[BRANCH_HEADERS]
{
if (!isflagset(FLAG_INTERNALLY_SOURCED)) {
route(AUTH_HEADERS);
} else {
remove_hf_re("^X-");
}
}
# Manage outgoing branches
branch_route[MANAGE_BRANCH] {
xlog("L_INFO", "$ci|branch|new branch [$T_branch_idx] to $ru => $du\n");
#!ifdef NAT_TRAVERSAL_ROLE
route(NAT_MANAGE);
#!endif
### route(BRANCH_HEADERS);
route_if_exists("CUSTOM_BRANCH_HEADERS");
}
route[RELAY]
{
if (is_method("INVITE|BYE|SUBSCRIBE|UPDATE|NOTIFY|REFER")) {
if(!t_is_set("branch_route")) t_on_branch("MANAGE_BRANCH");
}
if (isflagset(FLAG_INTERNALLY_SOURCED)) {
route(INTERNAL_TO_EXTERNAL_RELAY);
} else {
route(EXTERNAL_TO_INTERNAL_RELAY);
}
exit();
}
route[INTERNAL_TO_EXTERNAL_RELAY]
{
#!ifdef ACCOUNTING_ROLE
if (is_method("INVITE")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
t_on_reply("EXTERNAL_REPLY");
t_set_fr(0, $sel(cfg_get.kazoo.to_external_no_response_timer));
t_relay();
}
route[EXTERNAL_TO_INTERNAL_RELAY]
{
#!ifdef ACCOUNTING_ROLE
if (is_method("INVITE") && is_present_hf("Proxy-Authorization")) {
setflag(FLAG_ACC);
setflag(FLAG_ACCFAILED);
}
#!endif
t_on_reply("INTERNAL_REPLY");
t_on_failure("INTERNAL_FAULT");
t_set_fr(0, $sel(cfg_get.kazoo.to_internal_no_response_timer));
t_relay();
}
onreply_route[EXTERNAL_REPLY]
{
xlog("L_INFO", "$ci|log|external reply $T_reply_code $T_reply_reason\n");
#!ifdef NAT_TRAVERSAL_ROLE
if(status=~"[12][0-9][0-9]") {
route(NAT_MANAGE);
}
#!endif
#!ifdef ACL_ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER_ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);
#!endif
}
onreply_route[INTERNAL_REPLY]
{
# this route handles replies that are comming from our media server
if ($rs < 300) {
xlog("L_INFO", "$ci|log|internal reply $T_reply_code $T_reply_reason\n");
xlog("L_DEBUG", "$ci|log|source $si:$sp\n");
}
#!ifdef NAT_TRAVERSAL_ROLE
if(status=~"[12][0-9][0-9]") {
route(NAT_MANAGE);
}
#!endif
#!ifdef ACL_ROLE
setflag(FLAG_IS_REPLY);
route(ACL_CHECK);
#!endif
#!ifdef RATE_LIMITER_ROLE
setflag(FLAG_IS_REPLY);
route(DOS_PREVENTION);
#!endif
if (is_method("INVITE") &&
!isflagset(FLAG_SESSION_PROGRESS) &&
t_check_status("(180)|(183)|(200)")
) {
xlog("L_INFO", "$ci|log|call setup, now ignoring abnormal termination\n");
setflag(FLAG_SESSION_PROGRESS);
# clear the redirect
if ($avp(AVP_REDIRECT_KEY) != $null && $sht(redirects=>$avp(AVP_REDIRECT_KEY)) != $null) {
xlog("L_INFO", "$ci|log|removing redirect mapping $avp(AVP_REDIRECT_KEY)\n");
$sht(redirects=>$avp(AVP_REDIRECT_KEY)) = $null;
}
}
if ($rs < 300) {
xlog("L_INFO", "$ci|pass|$T_req($si):$T_req($sp)\n");
}
}
failure_route[INTERNAL_FAULT]
{
# this branch handles failures (>=300) to our media servers,
# which we can sometimes overcome by routing to another server
# if the failure cause was due to the transaction being
# cancelled then we are complete
if (t_is_canceled()) {
xlog("L_INFO", "$ci|log|transaction was cancelled\n");
exit;
}
if (!is_method("INVITE") || has_totag()) {
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
xlog("L_INFO", "$ci|pass|$si:$sp\n");
return;
}
# Handle redirects
if (t_check_status("302") && $T_rpl($hdr(X-Redirect-Server)) != $null) {
route(INTERNAL_REDIRECT);
}
remove_hf_re("^X-.*");
# handle challenges replies from media server, we want to route to same media server
if (t_check_status("407")) {
xlog("L_INFO", "$ci|log|media $xavp(ds_dst=>uri) challenged the invite, creating redirect\n");
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->" + @ruri.user + "@" + @ruri.host;
$sht(redirects=>$var(redirect)) = $xavp(ds_dst=>uri);
# change 6xx to 4xx
} else if (t_check_status("6[0-9][0-9]") && !t_check_status("600|603|604|606")) {
$var(new_code) = "4" + $(T_reply_code{s.substr,1,0});
xlog("L_INFO", "$ci|failure|sending $T_reply_code reply as $var(new_code) $T_reply_reason\n");
t_reply("$(var(new_code){s.int})", "$T_reply_reason");
# if the failure case was something that we should recover
# from then try to find a new media server
} else if ($T_reply_reason =~ "call barred") {
xlog("L_INFO", "$ci|failure|ignoring call barred\n");
} else if (isflagset(FLAG_SESSION_PROGRESS)) {
xlog("L_INFO", "$ci|failure|ignoring failure after session progress\n");
if (t_check_status("480")) {
xlog("L_INFO", "$ci|failure|overriding reply code 480 with $sel(cfg_get.kazoo.override_media_reply_480)\n");
send_reply("$(sel(cfg_get.kazoo.override_media_reply_480){s.int})", "Endpoint Not Available");
}
} else if (t_check_status("403") && $T_reply_reason=="Forbidden") {
xlog("L_WARNING", "$ci|failure|Failed auth from IP $si\n");
} else if (t_check_status("(401)|(486)")) {
xlog("L_INFO", "$ci|failure|auth reply $T_reply_code $T_reply_reason\n");
} else if (t_check_status("402")) {
xlog("L_INFO", "$ci|failure|overriding reply code 402 with 486\n");
send_reply("486", "Insufficient Funds");
} else if (t_check_status("(4[0-9][0-9])|(5[0-9][0-9])")) {
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
#!ifdef DISPATCHER_ROLE
route(DISPATCHER_NEXT_ROUTE);
#!endif
send_reply("486", "Unable to Comply");
} else {
xlog("L_INFO", "$ci|failure|internal reply $T_reply_code $T_reply_reason\n");
send_reply("$T_reply_code", "$T_reply_reason");
}
xlog("L_INFO", "$ci|pass|$si:$sp\n");
}
route[INTERNAL_REDIRECT]
{
xlog("L_INFO", "$ci|log|redirect to $T_rpl($hdr(X-Redirect-Server))\n");
$du = $T_rpl($hdr(X-Redirect-Server));
$xavp(ds_dst=>uri) = $du;
t_on_branch("MANAGE_BRANCH");
t_on_reply("INTERNAL_REPLY");
t_on_failure("INTERNAL_FAULT");
t_set_fr(0, 1000);
t_relay();
exit();
}
onsend_route {
if (isflagset(FLAG_ASSOCIATE_USER)) {
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
xlog("L_INFO", "$ci|log|associate traffic from $var(user_source) with media server sip:$sndto(ip):$sndto(port)\n");
$sht(associations=>$var(user_source))= "sip:" + $sndto(ip) + ":" + $sndto(port);
}
#!ifdef SIP_TRACE_ROLE
if (is_method("ACK") && isflagset(FLAG_SIP_TRACE)) {
sip_trace();
}
#!endif
if(!isflagset(FLAG_LOCAL_ROUTE)) {
xlog("L_INFO", "$ci|pass|$sndfrom(ip):$sndfrom(port) -> $sndto(ip):$sndto(port)\n");
}
}
route[ROUTE_TO_AOR]
{
if ($hdr(X-KAZOO-AOR) == $null) {
return;
}
xlog("L_INFO", "$ci|log|using AOR $hdr(X-KAZOO-AOR)\n");
if ($hdr(X-KAZOO-INVITE-FORMAT) == "contact") {
if(lookup("location", "$hdr(X-KAZOO-AOR)") > 0){
## handle_ruri_alias();
reg_fetch_contacts("location", "$hdr(X-KAZOO-AOR)", "callee");
$du = $(ulc(callee=>received));
xlog("L_INFO", "$ci|end|routing to contact $ru via $du\n");
} else {
xlog("L_INFO", "$ci|end|lookup for AOR $hdr(X-KAZOO-AOR) failed\n");
sl_send_reply("410", "Not registered");
exit;
}
} else if (reg_fetch_contacts("location", "$hdr(X-KAZOO-AOR)", "callee")) {
$du = $(ulc(callee=>received));
$fs = $(ulc(callee=>socket));
$bf = $bf | $(ulc(callee=>cflags));
xlog("L_INFO", "$ci|log|routing $hdr(X-KAZOO-AOR) to $du via $fs\n");
} else {
xlog("L_INFO", "$ci|end|user is not registered\n");
sl_send_reply("410", "Not registered");
exit;
}
}
event_route[tm:local-request]
{
setflag(FLAG_LOCAL_REQUEST);
xlog("L_DEBUG", "$ci|local|start $pr request $rm $ou\n");
xlog("L_DEBUG", "$ci|local|source $si:$sp -> $dd:$dp\n");
xlog("L_DEBUG", "$ci|local|from $fu\n");
xlog("L_DEBUG", "$ci|local|to $tu\n");
#!ifdef SIP_TRACE_ROLE
route(SIP_TRACE);
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_LOCAL_REQUEST);
#!endif
}
event_route[evrexec:DEFERRED_INIT]
{
xlog("L_INFO", "processing deferred init\n");
#!ifdef PRESENCE_ROLE
route(PRESENCE_DEFERRED_INIT);
#!endif
#!import_file "custom-init.cfg"
}
route[LOCAL_REQUEST]
{
if(src_ip != myself || $hdr(X-TM-Local) == $null) {
return;
}
xlog("L_DEBUG", "internal route $hdr(X-TM-Local)\n");
setflag(FLAG_LOCAL_ROUTE);
#!ifdef SIP_TRACE_ROLE
route(SIP_TRACE);
#!endif
$var(LocalRoute) = $hdr(X-TM-Local);
remove_hf_re("^X-TM-Local");
route_if_exists("$var(LocalRoute)");
exit;
}
#!import_file "custom-routes.cfg"
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 88
- 0
kamailio-proxy-call/defs-amqp.cfg View File

@ -0,0 +1,88 @@
## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
####### amqp defs ########
#!ifndef AMQP_DEFAULTS_INCLUDED
#!define AMQP_DEFAULTS_INCLUDED
#!trydef MY_AMQP_MAX_CHANNELS 25
#!trydef MY_AMQP_CONSUMER_PROCESSES 4
#!trydef MY_AMQP_CONSUMER_WORKERS 16
#!trydef MY_AMQP_HEARTBEATS 5
#!ifndef MY_AMQP_ZONE
#!substdef "!MY_AMQP_ZONE!local!g"
#!endif
#!ifdef PRESENCE_ROLE
#!trydef MY_AMQP_PUA_MODE 1
#!else
#!trydef MY_AMQP_PUA_MODE 0
#!endif
#!ifndef MY_AMQP_URL
#!ifdef AMQP_URL1
#!substdef "!MY_AMQP_URL!$def(AMQP_URL1)!g"
#!else
#!substdef "!MY_AMQP_URL!amqp://guest:guest@127.0.0.1:5672!g"
#!endif
#!endif
#!ifndef MY_AMQP_SECONDARY_URL
#!ifdef AMQP_URL2
#!substdef "!MY_AMQP_SECONDARY_URL!$def(AMQP_URL2)!g"
#!endif
#!endif
#!ifndef MY_AMQP_TERTIARY_URL
#!ifdef AMQP_URL3
#!substdef "!MY_AMQP_TERTIARY_URL!$def(AMQP_URL3)!g"
#!endif
#!endif
#!ifndef MY_AMQP_QUATERNARY_URL
#!ifdef AMQP_URL4
#!substdef "!MY_AMQP_QUATERNARY_URL!$def(AMQP_URL4)!g"
#!endif
#!endif
#!ifndef MY_AMQP_QUINARY_URL
#!ifdef AMQP_URL5
#!substdef "!MY_AMQP_QUINARY_URL!$def(AMQP_URL5)!g"
#!endif
#!endif
#!ifndef MY_AMQP_SENARY_URL
#!ifdef AMQP_URL6
#!substdef "!MY_AMQP_SENARY_URL!$def(AMQP_URL6)!g"
#!endif
#!endif
#!ifndef MY_AMQP_SEPTENARY_URL
#!ifdef AMQP_URL7
#!substdef "!MY_AMQP_SEPTENARY_URL!$def(AMQP_URL7)!g"
#!endif
#!endif
#!ifndef MY_AMQP_OCTONARY_URL
#!ifdef AMQP_URL8
#!substdef "!MY_AMQP_OCTONARY_URL!$def(AMQP_URL8)!g"
#!endif
#!endif
#!ifndef MY_AMQP_NONARY_URL
#!ifdef AMQP_URL9
#!substdef "!MY_AMQP_NONARY_URL!$def(AMQP_URL9)!g"
#!endif
#!endif
#!ifndef MY_AMQP_DENARY_URL
#!ifdef AMQP_URL10
#!substdef "!MY_AMQP_DENARY_URL!$def(AMQP_URL10)!g"
#!endif
#!endif
#!endif
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 95
- 0
kamailio-proxy-call/defs.cfg View File

@ -0,0 +1,95 @@
## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
####### defs ########
#!ifndef DEFAULTS_INCLUDED
#!define DEFAULTS_INCLUDED
#!substdef "!MAJOR!$(version(num){re.subst,/^(([^\.])*\.([^\.])*)\..*/\1/})!g"
#!trydef EXTERNAL_TO_INTERNAL_NO_RESPONSE_TIMER 3500
#!trydef INTERNAL_TO_EXTERNAL_NO_RESPONSE_TIMER 3500
#!trydef OVERRIDE_MEDIA_REPLY_480 603
kazoo.to_internal_no_response_timer = EXTERNAL_TO_INTERNAL_NO_RESPONSE_TIMER descr "external to internal no response timer"
kazoo.to_external_no_response_timer = INTERNAL_TO_EXTERNAL_NO_RESPONSE_TIMER descr "internal to external no response timer"
kazoo.override_media_reply_480 = OVERRIDE_MEDIA_REPLY_480 descr "sip code to send upstream when media returns 480 with session in progress"
#!ifndef MY_HOSTNAME
#!substdef "!MY_HOSTNAME!$HN(f)!g"
#!endif
#!ifndef MY_IP_ADDRESS
#!ifdef MY_LOCAL_IP
#!substdef "!MY_IP_ADDRESS!$def(MY_LOCAL_IP)!g"
#!else
#!substdef "!MY_IP_ADDRESS!$HN(i)!g"
#!endif
#!endif
#!ifndef WEBSOCKET_NO_ORIGIN_RESTRICTION
#!ifndef MY_WEBSOCKET_DOMAIN
#!substdef "!MY_WEBSOCKET_DOMAIN!$HN(d)!g"
#!endif
#!endif
#!trydef KAZOO_LOG_LEVEL L_INFO
#!trydef PV_BUFFER_SIZE 16384
#!trydef PV_BUFFER_SLOTS 30
#!trydef KZ_MEM_SUMMARY 0
#!trydef KZ_DB_MODULE kazoo
#!substdef "!KAMAILIO_DBMS!$def(KZ_DB_MODULE)!g"
#!ifndef KAZOO_DATA_DIR
#!substdef "!KAZOO_DATA_DIR!/etc/kazoo/kamailio/db!g"
#!endif
#!ifndef KAZOO_DB_URL
#!substdef "!KAZOO_DB_URL!kazoo:///KAZOO_DATA_DIR/kazoo.db!g"
#!endif
#!ifndef MAX_WHILE_LOOPS
#!substdef "!MAX_WHILE_LOOPS!500!g"
#!endif
#### tcp parameters ##
#!trydef CHILDREN 25
#!trydef TCP_CHILDREN 25
#!trydef TCP_MAX_CONNECTIONS 4096
#!trydef TCP_CONNECTION_LIFETIME 3605
#!trydef TCP_CONNECTION_TIMEOUT 5
#!trydef TCP_KEEP_ALIVE yes
#!trydef TCP_KEEP_COUNT 3
#!trydef TCP_KEEP_IDLE 30
#!trydef TCP_KEEP_INTERVAL 30
#!trydef TCP_SEND_TIMEOUT 3
#!include_file "defs-amqp.cfg"
#!ifndef MEDIA_SERVERS_HASH_SIZE
#!substdef "!MEDIA_SERVERS_HASH_SIZE!256!g"
#!endif
#!trydef RR_FULL_LR 1
#!trydef RR_DOUBLE_RR 1
#!trydef RR_FORCE_SOCKET 1
#!ifndef KZ_DISABLE_WEBSOCKETS_REGISTRAR_PORT
#!trydef KZ_WEBSOCKETS_REGISTRAR_PORT 7000
#!endif
#!ifndef KZ_DISABLE_TLS_REGISTRAR_PORT
#!trydef KZ_TLS_REGISTRAR_PORT 7000
#!endif
#!trydef KZ_MULTI_HOMED 0
#!endif
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 306
- 0
kamailio-proxy-call/dispatcher-role-5.1.cfg View File

@ -0,0 +1,306 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "dst_avp", "$avp(ds_dst)")
modparam("dispatcher", "attrs_avp", "$avp(ds_attrs)")
modparam("dispatcher", "grp_avp", "$avp(ds_grp)")
modparam("dispatcher", "cnt_avp", "$avp(ds_cnt)")
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
#!import_file "dispatcher-network-params.cfg"
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
#!import_file "dispatcher-network-classify.cfg"
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $sel(cfg_get.kazoo.dispatcher_primary_group);
$var(ds_backup_group) = $sel(cfg_get.kazoo.dispatcher_secondary_group);
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
add_path();
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
add_path();
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
#!import_file "dispatcher-network-find.cfg"
$var(ds_group) = $var(ds_primary_group);
if (!ds_select_dst("$var(ds_primary_group)", "$sel(cfg_get.kazoo.dispatcher_algorithm)") || $(avp(ds_dst)[0]) == $null) {
# we selected from primary group, try again in backup group
if (!ds_select_dst("$var(ds_backup_group)", "$sel(cfg_get.kazoo.dispatcher_algorithm)") || $(avp(ds_dst)[0]) == $null) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
} else {
$var(ds_group) = $var(ds_backup_group);
}
}
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_retries) = 0;
}
route[DISPATCHER_PREFERRED_ROUTE]
{
######
# check if the preferred route is active
######
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $avp(ds_dst)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
######
# filters current list from prefered route
# * saves the current list to temp avp removing the preferred route if it exists
# * resets current list
# * copies the temp back to list
# sets the prefered at top
# sets $du (destination) to prefered
######
$var(i) = 0;
while($(avp(ds_dst)[$var(i)]) != $null) {
if($(avp(ds_dst)[$var(i)]) != $var(prefered_route)) {
$avp(tmp_ds_dst) = $(avp(ds_dst)[$var(i)]);
}
$var(i) = $var(i) + 1;
}
$(avp(ds_dst)[*]) = $null;
$var(i) = 0;
while($(avp(tmp_ds_dst)[$var(i)]) != $null) {
$avp(ds_dst) = $(avp(tmp_ds_dst)[$var(i)]);
$var(i) = $var(i) + 1;
}
$avp(ds_dst) = $var(prefered_route);
$du = $var(prefered_route);
$(avp(tmp_ds_dst)[*]) = $null;
return 1;
}
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
$var(remaining) = $(sel(cfg_get.kazoo.dispatcher_max_retries){s.int}) - $avp(ds_retries);
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|remaining failed retry attempts: $var(remaining)\n");
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# reset the final reply timer
$avp(final_reply_timer) = 3;
# relay the request to the new media server
route(RELAY);
exit();
}
}
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_NOTICE", "Destination up: $ru\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
#!import_file "dispatcher-custom-media-check.cfg"
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_NOTICE", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 309
- 0
kamailio-proxy-call/dispatcher-role-5.2.cfg View File

@ -0,0 +1,309 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
#!trydef KZ_DISPATCHER_PRINT_ROUTES 1
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
kazoo.dispatcher_print_routes = KZ_DISPATCHER_PRINT_ROUTES descr "should we log the selected routes"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
modparam("dispatcher", "xavp_dst", "ds_dst")
modparam("dispatcher", "xavp_ctx", "ds_ctx")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
route_if_exists("DISPATCHER_CUSTOM_NETWORK_CLASSIFY");
if (!isflagset(FLAG_NETWORK_CLASSIFIED)) {
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $(sel(cfg_get.kazoo.dispatcher_primary_group){s.int});
$var(ds_backup_group) = $(sel(cfg_get.kazoo.dispatcher_secondary_group){s.int});
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
route_if_exists("DISPATCHER_CUSTOM_SET_GROUPS");
$var(ds_group) = $var(ds_primary_group);
$var(ds_alg) = $sel(cfg_get.kazoo.dispatcher_algorithm);
if(ds_list_exists("$var(ds_backup_group)")) {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg);$var(ds_backup_group)=$var(ds_alg));
} else {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg));
}
ds_select_routes("$var(ds_rule)", "2");
if ($xavp(ds_ctx=>cnt) == 0) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
}
route(PRINT_ROUTES);
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->"
+ @ruri.user + "@" + @ruri.host;
if ($sht(redirects=>$var(redirect)) != $null) {
$var(prefered_route) = $sht(redirects=>$var(redirect));
xlog("L_INFO", "$ci|route|found redirect for $var(redirect) to $var(prefered_route)\n");
$avp(AVP_REDIRECT_KEY) = $var(redirect);
route(DISPATCHER_PREFERRED_ROUTE);
} else if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_group) = $xavp(ds_dst=>grp);
$avp(ds_retries) = 0;
ds_set_dst();
}
route[DISPATCHER_PREFERRED_ROUTE]
{
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $xavp(ds_dst=>uri)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
$var(i) = $xavp(ds_ctx=>cnt) - 1;
while($var(i) >= 0) {
if($xavp(ds_dst[$var(i)]=>uri) == $var(prefered_route)) {
$xavp(ds_dst[$var(i)]) = $null;
}
$var(i) = $var(i) - 1;
}
$xavp(ds_dst=>uri) = $var(prefered_route);
$xavp(ds_dst[0]=>grp) = $var(setid);
$xavp(ds_dst[0]=>attrs) = $var(attrs);
return 1;
}
route[PRINT_ROUTES]
{
if($sel(cfg_get.kazoo.dispatcher_print_routes) == 0) return;
$var(i) = 0;
while($xavp(ds_dst[$var(i)]=>uri) != $null) {
xlog("L_INFO", "$ci|route|group $xavp(ds_dst[$var(i)]=>grp) => $xavp(ds_dst[$var(i)]=>uri) => zone $(xavp(ds_dst[$var(i)]=>attrs){param.value,zone})\n");
$var(i) = $var(i) + 1;
}
}
#!import_file "dispatcher-next-route.cfg"
#!ifndef CUSTOM_DISPATCHER_NEXT_ROUTE
# Try next destinations in failure route
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# relay the request to the new media server
route(RELAY);
exit;
}
}
#!endif
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_WARNING", "Destination up: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_WARNING", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 309
- 0
kamailio-proxy-call/dispatcher-role-5.4.cfg View File

@ -0,0 +1,309 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
#!trydef KZ_DISPATCHER_PRINT_ROUTES 1
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
kazoo.dispatcher_print_routes = KZ_DISPATCHER_PRINT_ROUTES descr "should we log the selected routes"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
modparam("dispatcher", "xavp_dst", "ds_dst")
modparam("dispatcher", "xavp_ctx", "ds_ctx")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
route_if_exists("DISPATCHER_CUSTOM_NETWORK_CLASSIFY");
if (!isflagset(FLAG_NETWORK_CLASSIFIED)) {
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $(sel(cfg_get.kazoo.dispatcher_primary_group){s.int});
$var(ds_backup_group) = $(sel(cfg_get.kazoo.dispatcher_secondary_group){s.int});
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
route_if_exists("DISPATCHER_CUSTOM_SET_GROUPS");
$var(ds_group) = $var(ds_primary_group);
$var(ds_alg) = $sel(cfg_get.kazoo.dispatcher_algorithm);
if(ds_list_exists("$var(ds_backup_group)")) {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg);$var(ds_backup_group)=$var(ds_alg));
} else {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg));
}
ds_select_routes("$var(ds_rule)", "2");
if ($xavp(ds_ctx=>cnt) == 0) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
}
route(PRINT_ROUTES);
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->"
+ @ruri.user + "@" + @ruri.host;
if ($sht(redirects=>$var(redirect)) != $null) {
$var(prefered_route) = $sht(redirects=>$var(redirect));
xlog("L_INFO", "$ci|route|found redirect for $var(redirect) to $var(prefered_route)\n");
$avp(AVP_REDIRECT_KEY) = $var(redirect);
route(DISPATCHER_PREFERRED_ROUTE);
} else if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_group) = $xavp(ds_dst=>grp);
$avp(ds_retries) = 0;
ds_set_dst();
}
route[DISPATCHER_PREFERRED_ROUTE]
{
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $xavp(ds_dst=>uri)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
$var(i) = $xavp(ds_ctx=>cnt) - 1;
while($var(i) >= 0) {
if($xavp(ds_dst[$var(i)]=>uri) == $var(prefered_route)) {
$xavp(ds_dst[$var(i)]) = $null;
}
$var(i) = $var(i) - 1;
}
$xavp(ds_dst=>uri) = $var(prefered_route);
$xavp(ds_dst[0]=>grp) = $var(setid);
$xavp(ds_dst[0]=>attrs) = $var(attrs);
return 1;
}
route[PRINT_ROUTES]
{
if($sel(cfg_get.kazoo.dispatcher_print_routes) == 0) return;
$var(i) = 0;
while($xavp(ds_dst[$var(i)]=>uri) != $null) {
xlog("L_INFO", "$ci|route|group $xavp(ds_dst[$var(i)]=>grp) => $xavp(ds_dst[$var(i)]=>uri) => zone $(xavp(ds_dst[$var(i)]=>attrs){param.value,zone})\n");
$var(i) = $var(i) + 1;
}
}
#!import_file "dispatcher-next-route.cfg"
#!ifndef CUSTOM_DISPATCHER_NEXT_ROUTE
# Try next destinations in failure route
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# relay the request to the new media server
route(RELAY);
exit;
}
}
#!endif
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_WARNING", "Destination up: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_WARNING", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 309
- 0
kamailio-proxy-call/dispatcher-role-5.5.cfg View File

@ -0,0 +1,309 @@
### DISPATCHER ROLE ####
#!trydef KZ_DISPATCHER_PROBE_MODE 1
#!trydef DISPATCHER_ADD_SERVERS 1
#!trydef DISPATCHER_ADD_SECONDARY_IP 1
#!trydef DISPATCHER_SECONDARY_IP_GROUP 3
#!trydef DISPATCHER_ALG 0
#!trydef KZ_DISPATCHER_HASH_SIZE 8
#!trydef KZ_DISPATCHER_ADD_FLAGS 9
#!trydef KZ_DISPATCHER_PRIMARY_GROUP 1
#!trydef KZ_DISPATCHER_SECONDARY_GROUP 2
#!trydef KZ_DISPATCHER_CLASSIFY_GROUP 3
#!trydef KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP 51
#!trydef KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP 52
#!trydef KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP 53
#!trydef KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP 54
#!trydef KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP 10
#!trydef KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP 11
#!trydef KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP 20
#!trydef KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP 21
#!trydef KZ_DISPATCHER_MAX_RETRIES 2
#!trydef KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA 1
#!trydef KZ_DISPATCHER_CLASSIFY_FLAGS 2
#!trydef KZ_DISPATCHER_PRINT_ROUTES 1
kazoo.dispatcher_auto_add = DISPATCHER_ADD_SERVERS descr "adds media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip = DISPATCHER_ADD_SECONDARY_IP descr "adds internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_add_secondary_ip_group = DISPATCHER_SECONDARY_IP_GROUP descr "sets the group where to add internal ip from media servers reported by ecallmgr"
kazoo.dispatcher_algorithm = DISPATCHER_ALG descr "dispatcher algorithm to use"
kazoo.dispatcher_primary_group = KZ_DISPATCHER_PRIMARY_GROUP descr "dispatcher primary group"
kazoo.dispatcher_secondary_group = KZ_DISPATCHER_SECONDARY_GROUP descr "dispatcher secondary group"
kazoo.dispatcher_max_retries = KZ_DISPATCHER_MAX_RETRIES descr "max number of retries for media servers"
kazoo.dispatcher_route_to_associated_media = KZ_DISPATCHER_ROUTE_ASSOCIATED_MEDIA descr "routes to associated media for atxfer"
kazoo.dispatcher_classify_flags = KZ_DISPATCHER_CLASSIFY_FLAGS descr "dispatch classifier flags"
kazoo.dispatcher_print_routes = KZ_DISPATCHER_PRINT_ROUTES descr "should we log the selected routes"
####### Dispatcher module ########
loadmodule "dispatcher.so"
modparam("dispatcher", "db_url", "KAZOO_DB_URL")
modparam("dispatcher", "flags", 2)
modparam("dispatcher", "use_default", 0)
modparam("dispatcher", "force_dst", 1)
modparam("dispatcher", "hash_pvar", "$avp(ds_grp)")
modparam("dispatcher", "setid_pvname", "$var(setid)")
modparam("dispatcher", "attrs_pvname", "$var(attrs)")
modparam("dispatcher", "ds_ping_method", "OPTIONS")
modparam("dispatcher", "ds_ping_interval", 10)
modparam("dispatcher", "ds_probing_threshold", 3)
modparam("dispatcher", "ds_probing_mode", KZ_DISPATCHER_PROBE_MODE)
modparam("dispatcher", "ds_ping_reply_codes", "501,403,404,400,200")
modparam("dispatcher", "ds_ping_from", "sip:sipcheck@MY_HOSTNAME")
modparam("dispatcher", "xavp_dst", "ds_dst")
modparam("dispatcher", "xavp_ctx", "ds_ctx")
modparam("dispatcher", "ds_hash_size", KZ_DISPATCHER_HASH_SIZE)
## Dispatcher Groups:
## 1 - Primary media servers
## 2 - Backup media servers
## 3 - Alternate media server IPs (used only for classification)
## 10 - Presence servers (if not locally handled)
## 20 - Registrar servers (if not locally handled)
modparam("rtimer", "timer", "name=dispatcher_reload;interval=20;mode=1;")
modparam("rtimer", "exec", "timer=dispatcher_reload;route=DISPATCHER_RELOAD")
####### Dispatcher Logic ########
route[DISPATCHER_CLASSIFY_SOURCE]
{
route_if_exists("DISPATCHER_CUSTOM_NETWORK_CLASSIFY");
if (!isflagset(FLAG_NETWORK_CLASSIFIED)) {
if (is_myself("$ou")) {
xlog("$var(log_request_level)", "$ci|log|original R-URI ($ou) is this proxy, treating as external sources\n");
} else {
$var(classify_dispatcher_flag) = $(sel(cfg_get.kazoo.dispatcher_classify_flags){s.int});
if (ds_is_from_list(KZ_DISPATCHER_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_CLASSIFY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET1_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_ALTNET2_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP, "$var(classify_dispatcher_flag)") ||
ds_is_from_list(KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP, "$var(classify_dispatcher_flag)")) {
xlog("$var(log_request_level)", "$ci|log|originated from internal sources\n");
setflag(FLAG_INTERNALLY_SOURCED);
} else {
xlog("$var(log_request_level)", "$ci|log|originated from external sources\n");
}
}
}
}
# Take the routes from dispatcher - hash over callid
# If prefered route defined, reorder the destionations
route[DISPATCHER_FIND_ROUTES]
{
$var(ds_primary_group) = $(sel(cfg_get.kazoo.dispatcher_primary_group){s.int});
$var(ds_backup_group) = $(sel(cfg_get.kazoo.dispatcher_secondary_group){s.int});
#!ifndef PRESENCE_ROLE
if (is_method("SUBSCRIBE")) {
$var(ds_primary_group) = KZ_DISPATCHER_PRESENCE_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_PRESENCE_SECONDARY_GROUP;
}
#!endif
#!ifndef REGISTRAR_ROLE
if (is_method("REGISTER")) {
$var(ds_primary_group) = KZ_DISPATCHER_REGISTRAR_PRIMARY_GROUP;
$var(ds_backup_group) = KZ_DISPATCHER_REGISTRAR_SECONDARY_GROUP;
}
#!endif
#!ifdef PRESENCE_ROLE
route(PRESENCE_FAST_PICKUP_ATTEMPT);
#!endif
route_if_exists("DISPATCHER_CUSTOM_SET_GROUPS");
$var(ds_group) = $var(ds_primary_group);
$var(ds_alg) = $sel(cfg_get.kazoo.dispatcher_algorithm);
if(ds_list_exists("$var(ds_backup_group)")) {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg);$var(ds_backup_group)=$var(ds_alg));
} else {
$var(ds_rule) = $_s($var(ds_primary_group)=$var(ds_alg));
}
ds_select_routes("$var(ds_rule)", "2");
if ($xavp(ds_ctx=>cnt) == 0) {
xlog("L_WARN", "$ci|end|no servers available in primary or backup group\n");
sl_send_reply("480", "All servers busy");
exit;
}
route(PRINT_ROUTES);
$var(user_source) = $(ct{tobody.user}) + "@" + $si + ":" + $sp;
$var(redirect) = @from.uri.user + "@" + @from.uri.host + "->"
+ @ruri.user + "@" + @ruri.host;
if ($sht(redirects=>$var(redirect)) != $null) {
$var(prefered_route) = $sht(redirects=>$var(redirect));
xlog("L_INFO", "$ci|route|found redirect for $var(redirect) to $var(prefered_route)\n");
$avp(AVP_REDIRECT_KEY) = $var(redirect);
route(DISPATCHER_PREFERRED_ROUTE);
} else if ($sht(associations=>$var(user_source)) != $null) {
if($sel(cfg_get.kazoo.dispatcher_route_to_associated_media) == 1) {
$var(prefered_route) = $sht(associations=>$var(user_source));
xlog("L_INFO", "$ci|route|found association for contact uri $var(user_source)\n");
route(DISPATCHER_PREFERRED_ROUTE);
}
$sht(associations=>$var(user_source)) = $null;
}
$avp(ds_group) = $xavp(ds_dst=>grp);
$avp(ds_retries) = 0;
ds_set_dst();
}
route[DISPATCHER_PREFERRED_ROUTE]
{
if(!ds_is_from_list(-1, 6, "$var(prefered_route)")) {
xlog("L_INFO", "$ci|log|associated media server $var(prefered_route) is inactive, moving to $xavp(ds_dst=>uri)\n");
return -1;
}
xlog("L_INFO", "$ci|log|re-ordering the dispatcher list to maintain association with $var(prefered_route)\n");
$var(i) = $xavp(ds_ctx=>cnt) - 1;
while($var(i) >= 0) {
if($xavp(ds_dst[$var(i)]=>uri) == $var(prefered_route)) {
$xavp(ds_dst[$var(i)]) = $null;
}
$var(i) = $var(i) - 1;
}
$xavp(ds_dst=>uri) = $var(prefered_route);
$xavp(ds_dst[0]=>grp) = $var(setid);
$xavp(ds_dst[0]=>attrs) = $var(attrs);
return 1;
}
route[PRINT_ROUTES]
{
if($sel(cfg_get.kazoo.dispatcher_print_routes) == 0) return;
$var(i) = 0;
while($xavp(ds_dst[$var(i)]=>uri) != $null) {
xlog("L_INFO", "$ci|route|group $xavp(ds_dst[$var(i)]=>grp) => $xavp(ds_dst[$var(i)]=>uri) => zone $(xavp(ds_dst[$var(i)]=>attrs){param.value,zone})\n");
$var(i) = $var(i) + 1;
}
}
#!import_file "dispatcher-next-route.cfg"
#!ifndef CUSTOM_DISPATCHER_NEXT_ROUTE
# Try next destinations in failure route
route[DISPATCHER_NEXT_ROUTE]
{
if($avp(ds_retries) >= $sel(cfg_get.kazoo.dispatcher_max_retries)) return;
$avp(ds_retries) = $avp(ds_retries) + 1;
if(ds_next_dst()) {
xlog("L_INFO", "$ci|log|routing call to next media server $du\n");
setflag(FLAG_SKIP_NAT_CORRECTION);
# relay the request to the new media server
route(RELAY);
exit;
}
}
#!endif
event_route[dispatcher:dst-down]
{
xlog("L_WARNING", "Destination down: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
event_route[dispatcher:dst-up]
{
xlog("L_WARNING", "Destination up: $ru , $xavp(ds_dst=>uri), $xavp(ds_dst=>grp), $xavp(ds_dst=>attrs)\n");
}
route[DISPATCHER_CHECK_MEDIA_SERVER]
{
$var(check_media_server_ret) = 0;
if($sel(cfg_get.kazoo.dispatcher_auto_add) == 1) {
$var(SetId) = 1;
if($var(Zone) != "MY_AMQP_ZONE") {
$var(SetId) = 2;
}
$var(flags) = KZ_DISPATCHER_ADD_FLAGS;
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
if($sel(cfg_get.kazoo.dispatcher_add_secondary_ip) == 1) {
if($var(MediaIP) != "" && $var(MediaIP) != $(var(MediaUrl){uri.host})) {
$var(MediaUrlBack) = $var(MediaUrl);
$var(MediaUrl) = $_s($(var(MediaUrlBack){uri.scheme}):$var(MediaIP):$(var(MediaUrlBack){uri.port}));
$var(attrs) = $_s(zone=$var(Zone);profile=$var(MediaProfile);duid=$(var(MediaUrl){s.corehash, MEDIA_SERVERS_HASH_SIZE});node=$var(MediaName));
$var(SetId) = $sel(cfg_get.kazoo.dispatcher_add_secondary_ip_group);
route_if_exists("DISPATCHER_CUSTOM_MEDIA_CHECK");
sql_query("exec", "KZQ_CHECK_MEDIA_SERVER_INSERT");
if($sqlrows(exec) > 0) {
$shv(dispatcher_reload) = 1;
$var(check_media_server_ret) = 1;
}
$var(MediaUrl) = $var(MediaUrlBack);
}
}
}
return $var(check_media_server_ret);
}
route[DISPATCHER_RELOAD]
{
if($shv(dispatcher_reload) == 1) {
xlog("L_WARNING", "reloading dispatcher table\n");
ds_reload();
};
$shv(dispatcher_reload) = 0;
}
route[DISPATCHER_STATUS]
{
jsonrpc_exec('{"jsonrpc": "2.0", "method": "dispatcher.list", "id": 1}');
$var(Sets) = $(jsonrpl(body){kz.json, result.NRSETS});
$var(i) = 0;
$var(ds_groups_json)="";
$var(Sep1) = "";
while($var(i) < $var(Sets)) {
$var(Set) = $(jsonrpl(body){kz.json, result.RECORDS[$var(i)].SET});
$var(SetCount) = $(var(Set){kz.json.count,TARGETS});
$var(Sep2)="";
$var(ds_group_json)="";
$var(c) = 0;
while($var(c) < $var(SetCount)) {
$var(Dest) = $(var(Set){kz.json,TARGETS[$var(c)].DEST});
$var(record) = $_s("$(var(Dest){kz.json,URI})" : {"destination" : "$(var(Dest){kz.json,URI})", "flags" : "$(var(Dest){kz.json,FLAGS})", "priority" : $(var(Dest){kz.json,PRIORITY}), "attrs" : "$(var(Dest){kz.json,ATTRS.BODY})"});
$var(ds_group_json) = $var(ds_group_json) + $var(Sep2) + $var(record);
$var(Sep2) = ",";
$var(c) = $var(c) + 1;
}
$var(ds_groups_json) = $var(ds_groups_json) + $var(Sep1) + $_s("$(var(Set){kz.json,ID})" : { $var(ds_group_json) });
$var(Sep1)=", ";
$var(i) = $var(i) + 1;
}
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 17
- 0
kamailio-proxy-call/dmq-role.cfg View File

@ -0,0 +1,17 @@
loadmodule "dmq.so"
loadmodule "dmq_usrloc.so"
# ---- dmq params ----
modparam("dmq", "server_address", "sip:MY_IP_ADDRESS:5090")
modparam("dmq", "multi_notify", 0)
modparam("dmq_usrloc", "enable", 1)
route[HANDLE_DMQ]
{
if (is_method("KDMQ") && $Rp == 5090)
{
dmq_handle_message();
}
}

+ 52
- 0
kamailio-proxy-call/kamailio.cfg View File

@ -0,0 +1,52 @@
## NOTE: DO NOT CHANGE THIS FILE, EDIT local.cfg ##
#### Preprocessor Directives #########
#!define L_ALERT -5
#!define L_BUG -4
#!define L_CRIT2 -3
#!define L_CRIT -2
#!define L_ERR -1
#!define L_WARN 0
#!define L_NOTICE 1
#!define L_INFO 2
#!define L_DBG 3
#!define L_DEBUG 4
#!define AVP_RECV_PARAM "recv_param"
#!define AVP_LOG_LEVEL "log_level"
#!define AVP_ROUTE_CNT "route_cnt"
#!define AVP_ASSOCIATED_SERVER "associated_server"
#!define AVP_ASSOCIATE_CONTACT "associate_contact"
#!define AVP_REDIRECT_KEY "redirect_key"
#!define FLB_NATB 1
#!define FLB_NATSIPPING 2
#!define FLB_UAC_REDIRECT 3
#!define TRUSTED_ADR_GROUP 1
################
# Kamailio modules to help substdef setup
# these need to go before local.cfg
# so they can be used
#
# ipops - ip , domain, hostname
# pv - $def(existing definition)
# textops - apply regexp
#
#
################
loadmodule "ipops.so"
loadmodule "pv.so"
loadmodule "textops.so"
####### Local Configuration ########
include_file "local.cfg"
####### defaults not configured in local ########
include_file "defs.cfg"
####### Default Configuration ######
include_file "default.cfg"
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 156
- 0
kamailio-proxy-call/kazoo-bindings.cfg View File

@ -0,0 +1,156 @@
######## kazoo bindings ########
###
###
#!trydef KZ_PUA_PRESENCE_USE_FULL_ENTITY 1
####### Kazoo Integration module ##########
loadmodule "kazoo.so"
modparam("kazoo", "pua_mode", MY_AMQP_PUA_MODE)
modparam("kazoo", "amqp_primary_zone", "MY_AMQP_ZONE")
modparam("kazoo", "amqp_query_timeout_avp", "$avp(kz_timeout)")
modparam("kazoo", "node_hostname", "MY_HOSTNAME")
modparam("kazoo", "amqp_heartbeats", MY_AMQP_HEARTBEATS)
modparam("kazoo", "amqp_max_channels", MY_AMQP_MAX_CHANNELS)
modparam("kazoo", "amqp_consumer_processes", MY_AMQP_CONSUMER_PROCESSES)
modparam("kazoo", "amqp_consumer_workers", MY_AMQP_CONSUMER_WORKERS)
modparam("kazoo", "presence_use_full_entity", KZ_PUA_PRESENCE_USE_FULL_ENTITY)
## amqp connections
#!ifdef MY_AMQP_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_URL")
#!endif
#!ifdef MY_AMQP_SECONDARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_SECONDARY_URL")
#!endif
#!ifdef MY_AMQP_TERTIARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_TERTIARY_URL")
#!endif
#!ifdef MY_AMQP_QUATERNARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_QUATERNARY_URL")
#!endif
#!ifdef MY_AMQP_QUINARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_QUINARY_URL")
#!endif
#!ifdef MY_AMQP_SENARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_SENARY_URL")
#!endif
#!ifdef MY_AMQP_SEPTENARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_SEPTENARY_URL")
#!endif
#!ifdef MY_AMQP_OCTONARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_OCTONARY_URL")
#!endif
#!ifdef MY_AMQP_NONARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_NONARY_URL")
#!endif
#!ifdef MY_AMQP_DENARY_URL
modparam("kazoo", "amqp_connection", "MY_AMQP_DENARY_URL")
#!endif
event_route[kazoo:mod-init]
{
#!ifdef PRESENCE_ROLE
route(PRESENCE_BINDINGS);
#!endif
#!ifdef MESSAGE_ROLE
route(MESSAGE_BINDINGS);
#!endif
#!ifdef REGISTRAR_ROLE
route(REGISTRAR_BINDINGS);
#!endif
#!ifdef NODES_ROLE
route(NODES_BINDINGS);
#!endif
#!ifdef ACL_ROLE
route(ACL_BINDINGS);
#!endif
#!import_file "kazoo-custom-bindings.cfg"
}
event_route[kazoo:consumer-event]
{
xlog("L_DEBUG","unhandled AMQP event, payload: $kzE\n");
}
event_route[kazoo:consumer-event-connection-open]
{
xlog("L_DEBUG","connection to $(kzE{kz.json,host}) opened\n");
}
event_route[kazoo:consumer-event-connection-error]
{
xlog("L_ERR","amqp|error|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|$(kzE{kz.json,message})\n");
}
event_route[kazoo:consumer-event-connection-message]
{
xlog("L_DEBUG","amqp|msg|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|$(kzE{kz.json,message})\n");
}
event_route[kazoo:consumer-event-connection-closed]
{
xlog("L_DEBUG","amqp|closed|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|connection to $(kzE{kz.json,host}) closed\n");
}
event_route[kazoo:consumer-event-connection-zone-available]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is available\n");
}
event_route[kazoo:consumer-event-connection-zone-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
event_route[kazoo:consumer-event-connection-available]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is available\n");
}
event_route[kazoo:consumer-event-connection-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
event_route[kazoo:consumer-event-connection-zone-listener-available]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is available\n");
}
event_route[kazoo:consumer-event-connection-zone-listener-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
event_route[kazoo:consumer-event-connection-listener-zone-available]
{
xlog("L_NOTICE","amqp|connection|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|listener available\n");
}
event_route[kazoo:consumer-event-connection-listener-zone-unavailable]
{
xlog("L_WARN","amqp|connection|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|listener unavailable\n");
#!ifdef PRESENCE_ROLE
route(PRESENCE_ZONE_UNAVAILABLE);
#!endif
}
event_route[kazoo:consumer-event-connection-listener-available]
{
xlog("L_DEBUG","amqp|connection|$(kzE{kz.json,zone})|$(kzE{kz.json,name})|listener available\n");
}
event_route[kazoo:consumer-event-connection-listener-unavailable]
{
xlog("L_DEBUG","amqp zone $(kzE{kz.json,zone}) is unavailable\n");
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

+ 343
- 0
kamailio-proxy-call/keepalive-role.cfg View File

@ -0,0 +1,343 @@
######## KEEPALIVE PINGING ########
#!trydef KEEPALIVE_ENABLED 1
#!trydef KEEPALIVE_NAT_ONLY 0
#!trydef KEEPALIVE_UDP_ONLY 0
#!trydef KEEPALIVE_TIMERS 4
#!trydef KEEPALIVE_INTERVAL 60
#!trydef KEEPALIVE_TIMEOUT 5000
#!trydef KEEPALIVE_FAILED_THRESHOLD 2
#!trydef KEEPALIVE_EXPIRE_SUBSCRIPTIONS 1
#!trydef KEEPALIVE_EXPIRE_REGISTRATIONS 1
#!trydef KEEPALIVE_FAILED_ACTION 1
#!trydef KEEPALIVE_FAILED_LOG_LEVEL 0
#!trydef KEEPALIVE_EXPIRED_SUBSCRIPTION_ACTION 1
#!trydef KEEPALIVE_EXPIRED_REGISTRATION_ACTION 1
#!trydef KEEPALIVE_ON_SUBSCRIPTION_ACTION 1
#!trydef KEEPALIVE_ON_REGISTRATION_ACTION 1
#!substdef "!KEEPALIVE_S_FROM_URI!sip:keepalive@MY_HOSTNAME!g"
#!substdef "!KEEPALIVE_S_TIMERS!$def(KEEPALIVE_TIMERS)!g"
kazoo.keepalive_udp_only = KEEPALIVE_UDP_ONLY descr "should we send keepalive for udp only"
kazoo.keepalive_nat_only = KEEPALIVE_NAT_ONLY descr "should we send keepalive for nat phones only"
kazoo.keepalive_timeout = KEEPALIVE_TIMEOUT descr "timeout in ms for keepalive transaction"
kazoo.keepalive_failed_threshold = KEEPALIVE_FAILED_THRESHOLD descr "how many times can a device fail to respond to OPTIONS"
kazoo.keepalive_expire_subscriptions = KEEPALIVE_EXPIRE_SUBSCRIPTIONS descr "expires subscriptions that do not respond to OPTIONS"
kazoo.keepalive_expire_registrations = KEEPALIVE_EXPIRE_REGISTRATIONS descr "expires registrations that do not respond to OPTIONS"
kazoo.keepalive_failed_log_level = KEEPALIVE_FAILED_LOG_LEVEL descr "loglevel for keepalive failed reply"
kazoo.keepalive_failed_action = KEEPALIVE_FAILED_ACTION descr "action for devices that exceed the threshold. 1 = disable, 2 = delete"
kazoo.keepalive_interval = KEEPALIVE_INTERVAL descr "interval in seconds between attempts to send OPTIONS to device"
kazoo.keepalive_expired_registration_action = KEEPALIVE_EXPIRED_REGISTRATION_ACTION descr "action when registrar expires a registration, 1 = delete , 2 = disable, 0 = none"
kazoo.keepalive_expired_subscription_action = KEEPALIVE_EXPIRED_SUBSCRIPTION_ACTION descr "action when presence expires a subscription, 1 = delete , 2 = disable, 0 = none"
kazoo.keepalive_on_registration_action = KEEPALIVE_ON_REGISTRATION_ACTION descr "action on registration, 1 = insert in keepalive , 0 = none"
kazoo.keepalive_on_subscription_action = KEEPALIVE_ON_SUBSCRIPTION_ACTION descr "action on subscription, 1 = insert in keepalive , 0 = none"
kazoo.keepalive_enable = KEEPALIVE_ENABLED descr "enable keepalive, 1 = on , 0 = off"
modparam("rtimer", "timer", "name=keepalive_timer;interval=1;mode=KEEPALIVE_S_TIMERS;")
modparam("rtimer", "exec", "timer=keepalive_timer;route=KEEPALIVE_TIMER")
modparam("rtimer", "timer", "name=keepalive_db_timer;interval=1;mode=1;")
modparam("rtimer", "exec", "timer=keepalive_db_timer;route=KEEPALIVE_DB_TIMER")
##modparam("rtimer", "timer", "name=keepalive_cleanup;interval=5;mode=1;")
##modparam("rtimer", "exec", "timer=keepalive_cleanup;route=KEEPALIVE_CLEANUP")
modparam("mqueue","mqueue", "name=keepalive_db_queue")
modparam("statistics","variable", "keepalive:success")
modparam("statistics","variable", "keepalive:failure")
modparam("statistics","variable", "keepalive:db:success")
modparam("statistics","variable", "keepalive:db:failure")
modparam("statistics","variable", "keepalive:client_options")
modparam("statistics","variable", "keepalive:client_notify")
modparam("statistics","variable", "keepalive:disabled")
modparam("statistics","variable", "keepalive:removed")
modparam("statistics","variable", "keepalive:expired_registrations")
modparam("statistics","variable", "keepalive:expired_subscriptions")
modparam("statistics","variable", "keepalive:from_registration")
modparam("statistics","variable", "keepalive:from_subscription")
modparam("statistics","variable", "keepalive:removed_from_registration")
modparam("statistics","variable", "keepalive:removed_from_subscription")
modparam("statistics","variable", "keepalive:disabled_from_expired_registration")
modparam("statistics","variable", "keepalive:removed_from_expired_registration")
modparam("statistics","variable", "keepalive:disabled_from_expired_subscription")
modparam("statistics","variable", "keepalive:removed_from_expired_subscription")
modparam("htable", "htable", "keepalive=>size=32;")
route[KEEPALIVE_DB_TIMER]
{
$var(runloop) = 1;
while(mq_fetch("keepalive_db_queue") == 1 && $var(runloop) < MAX_WHILE_LOOPS) {
$var(ci) = $mqk(keepalive_db_queue);
xlog("L_DEBUG", "Query : $var(ci) => $mqv(keepalive_db_queue)\n");
$var(sqlres) = sql_query("cb", "$mqv(keepalive_db_queue)");
xlog("L_DEBUG", "Query result : $var(sqlres)\n");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$var(ci)|log|error running query : $mqv(keepalive_db_queue)\n");
} else {
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("$var(ci)", "$var(stat_update)");
$var(nrows) = $sqlrows(cb);
xlog("L_DEBUG", "$var(ci)|log|end UPDATED $var(nrows) => $var(stat_update)\n");
if($var(nrows) == 0) {
xlog("L_DEBUG", "$var(ci)|log|error no rows affected when running query\n");
}
}
$var(runloop) = $var(runloop) + 1;
}
}
route[KEEPALIVE_CLEANUP]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
$var(Query) = $_s(UPDATE keepalive SET SELECTED = 9 WHERE slot = $var(slot) AND selected = 0 and failed > $sel(cfg_get.kazoo.keepalive_failed_threshold));
# $var(Query) = $_s(UPDATE keepalive SET SELECTED = 9 where selected < 3 and failed > $sel(cfg_get.kazoo.keepalive_failed_threshold));
sql_query("cb", "$var(Query)");
if($sqlrows(cb) > 0) {
if($sel(cfg_get.kazoo.keepalive_expire_registrations) == 1) {
if($def(REGISTRAR_DB_MODE) == 3) {
$var(Query) = $_s(update location set expires = last_modified where id in(select b.id from w_keepalive_contact a inner join w_location_contact b on a.contact = b.contact where selected = 9));
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("keepalive:expired_registrations", "$var(stat_update)");
} else {
$var(Query) = $_s(update location set expires = last_modified where id in(select b.id from w_keepalive_contact a inner join w_location_contact b on a.contact = b.contact where selected = 9));
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("keepalive:expired_registrations", "$var(stat_update)");
}
}
if($sel(cfg_get.kazoo.keepalive_expire_subscriptions) == 1) {
$var(Query) = $_s(DELETE FROM active_watchers where id in(select b.id from w_keepalive_contact a inner join w_watchers_contact b on a.contact = b.contact where selected = 9));
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("keepalive:expired_subscriptions", "$var(stat_update)");
}
if($sel(cfg_get.kazoo.keepalive_failed_action) == 2) {
## disable
$var(Query) = $_s(UPDATE keepalive SET SELECTED = 10 where selected = 9);
$var(stat) = "keepalive:disabled";
} else if($sel(cfg_get.kazoo.keepalive_failed_action) == 1) {
## delete - will be recreated on registration/subscription with same contact
$var(Query) = $_s(DELETE FROM keepalive where selected = 9);
$var(stat) = "keepalive:removed";
}
sql_query("cb", "$var(Query)");
$var(stat_update) = $_s(+$sqlrows(cb));
update_stat("$var(stat)", "$var(stat_update)");
}
}
route[KEEPALIVE_TIMER]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
$var(base_slot) = $rtimer_worker * $sel(cfg_get.kazoo.keepalive_interval);
$var(slot) = $var(base_slot) + $var(tick);
$var(Query) = $_s(UPDATE keepalive SET selected = 1 WHERE slot = $var(slot) AND selected = 0 AND time_sent < datetime('now', '-$sel(cfg_get.kazoo.keepalive_interval) seconds'));
## xlog("L_NOTICE", "SQLTIMER ($var(base_slot) + $var(tick))> $var(Query)\n");
$var(sqlres) = sql_query("cb", "$var(Query)");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$rtimer_worker|$var(tick)|log|error running query : $var(Query)\n");
} else {
$var(nrows) = $sqlrows(cb);
xlog("L_DEBUG", "$rtimer_worker|$var(tick)|log|selected $var(nrows) endpoints to ping\n");
}
route(KEEPALIVE_CLEANUP);
$var(Query) = $_s(SELECT id, contact, sockinfo from keepalive WHERE slot = $var(slot) AND selected = 1);
xlog("L_DEBUG", "$rtimer_worker|$var(tick)|timer|SQL => $var(Query)\n");
$var(result) =sql_xquery("cb", "$var(Query)", "ra");
if($var(result) == 1) {
while($xavp(ra) != $null) {
$var(loop) = 0;
while($xavp(ra) != $null && $var(loop) < MAX_WHILE_LOOPS) {
route(KEEPALIVE_SEND_PING);
pv_unset("$xavp(ra)");
$var(loop) = $var(loop) + 1;
}
}
}
$var(Query) = $_s(UPDATE keepalive SET selected = 2 WHERE slot = $var(slot) AND selected = 1);
$var(sqlres) = sql_query("cb", "$var(Query)");
if($var(sqlres) < 0) {
xlog("L_ERROR", "$rtimer_worker|$var(tick)|log|error running query : $var(Query)\n");
}
$var(tick) = $var(tick) + 1;
if($var(tick) > $sel(cfg_get.kazoo.keepalive_interval)) {
$var(tick) = 0;
}
}
route[KEEPALIVE_SEND_PING]
{
$var(CallId) = $uuid(g);
xlog("L_DEBUG", "$var(CallId)|$rtimer_worker|timer|SENDING PING FROM $xavp(ra=>local_contact) TO => $xavp(ra=>contact)\n");
$uac_req(method)="OPTIONS";
$uac_req(hdrs) = "X-TM-Local: KEEPALIVE_PING\r\nX-TM-SockInfo: " + $xavp(ra=>sockinfo) + "\r\n";
$uac_req(turi) = $xavp(ra=>contact);
$uac_req(ruri) = $xavp(ra=>contact);
$uac_req(furi) = $_s(KEEPALIVE_S_FROM_URI;nat_id=$xavp(ra=>id));
$uac_req(ouri) = "sip:127.0.0.1:5090;transport=tcp";
$uac_req(callid) = $var(CallId);
uac_req_send();
}
onreply_route[KEEPALIVE_REPLY]
{
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE REPLY $(tu{nameaddr.uri})\n");
$var(Query) = $_s(UPDATE keepalive SET selected = 0, failed = 0, time_sent = datetime('now') WHERE id = $(fu{uri.param,nat_id}) AND SELECTED = 2);
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE UPDATE SQL => '$var(Query)'\n");
mq_add("keepalive_db_queue", "keepalive:db:success", "$var(Query)");
update_stat("keepalive:success", "+1");
resetflag(FLAG_SIP_TRACE);
}
failure_route[KEEPALIVE_FAULT]
{
xlog("$(sel(cfg_get.kazoo.keepalive_failed_log_level){s.int})", "$ci|keepalive|received error $T_reply_code $T_reply_reason from $(tu{nameaddr.uri})\n");
$var(Query) = $_s(UPDATE keepalive SET selected = 0, failed = failed + 1, time_sent = datetime('now') WHERE id = $(fu{uri.param,nat_id}) AND SELECTED = 2);
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE REMOVE SQL => '$var(Query)'\n");
mq_add("keepalive_db_queue", "keepalive:db:failure", "$var(Query)");
update_stat("keepalive:failure", "+1");
resetflag(FLAG_SIP_TRACE);
}
route[KEEPALIVE_PING]
{
$fs = $hdr(X-TM-SockInfo);
remove_hf_re("^X-TM-SockInfo");
force_rport();
handle_ruri_alias();
record_route();
xlog("L_DEBUG", "$ci|local|sending $proto keepalive using $fs to $ru => $du => $tu\n");
t_on_reply("KEEPALIVE_REPLY");
t_on_failure("KEEPALIVE_FAULT");
t_set_fr(0, $sel(cfg_get.kazoo.keepalive_timeout));
t_relay();
}
route[KEEPALIVE_ON_REGISTRATION]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($sel(cfg_get.kazoo.keepalive_on_registration_action) == 0) {
return;
}
if($proto == "ws" || $proto == "wss") {
return;
}
if($sht(keepalive=>$si~$sp~$prid) != $null) {
return;
}
if (isbflagset(FLB_NATB)) {
if(!isbflagset(FLB_NATSIPPING)) {
return;
}
} else {
if($sel(cfg_get.kazoo.keepalive_nat_only) == 1) {
return;
}
}
$var(alias) = $(avp(AVP_RECV_PARAM){uri.host}) + "~" + $(avp(AVP_RECV_PARAM){uri.port}) + "~" + $prid;
$var(contact) = $(ct{nameaddr.uri}) + ";alias=" + $var(alias);
$var(local_contact) = "sip:" + $Ri + ":" + $Rp + ";transport=" + $proto;
xlog("L_DEBUG", "$ci|keepalive|KEEPALIVE ON REG $var(save_result) $proto $RAut $var(contact) $var(alias) $(ct{nameaddr.uri}) $ct $avp(AVP_RECV_PARAM) $tu $xavp(ulrcd=>ruid) , $xavp(ulrcd=>contact) , $xavp(ulrcd=>expires)\n");
if($var(save_result) == 3) {
$var(sql) = $_s(DELETE FROM keepalive WHERE contact = "$var(contact)");
$var(stat) = "keepalive:removed_from_registration";
} else {
$var(max_slots) = $sel(cfg_get.kazoo.keepalive_interval) * KEEPALIVE_S_TIMERS;
$var(slot) = $(var(contact){s.corehash, $var(max_slots)});
$var(sql) = $_s(INSERT OR IGNORE INTO keepalive (contact, received, sockinfo, slot) values("$var(contact)", "$var(alias)", "$(RAut{uri.tosocket})", $var(slot)));
$var(stat) = "keepalive:from_registration";
}
mq_add("keepalive_db_queue", "$var(stat)", "$var(sql)");
return;
}
route[KEEPALIVE_ON_SUBSCRIBE]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($sel(cfg_get.kazoo.keepalive_on_subscription_action) == 0) {
return;
}
if($sht(keepalive=>$si~$sp~$prid) != $null) {
return;
}
$var(max_slots) = $sel(cfg_get.kazoo.keepalive_interval) * KEEPALIVE_S_TIMERS;
$var(slot) = $(subs(contact){s.corehash, $var(max_slots)});
$var(alias) = $(subs(contact){uri.param,alias});
$var(sql) = $_s(INSERT OR IGNORE INTO keepalive (contact, received, sockinfo, slot) values("$subs(contact)", "$var(alias)", "$subs(sockinfo)", $var(slot)));
mq_add("keepalive_db_queue", "keepalive:from_subscription", "$var(sql)");
}
route[KEEPALIVE_ON_EXPIRED_REGISTRATION]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($sel(cfg_get.kazoo.keepalive_expired_registration_action) == 2) {
## disable
$var(Query) = $_s(UPDATE keepalive SET SELECTED = 10 where selected < 3 and contact like "$ulc(exp=>addr)%");
mq_add("keepalive_db_queue", "keepalive:disabled_from_expired_registration", "$var(Query)");
} else if($sel(cfg_get.kazoo.keepalive_expired_registration_action) == 1) {
## delete - will be recreated on registration with same contact
$var(Query) = $_s(DELETE FROM keepalive where selected < 3 and contact like "$ulc(exp=>addr)%");
mq_add("keepalive_db_queue", "keepalive:removed_from_expired_registration", "$var(Query)");
}
}
route[KEEPALIVE_ON_OPTIONS]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($shtinc(keepalive=>$si~$sp~$prid) == 1) {
$var(Query) = $_s(UPDATE keepalive set selected = 3 where received = "$si~$sp~$prid" and selected <> 3 );
mq_add("keepalive_db_queue", "keepalive:client_options", "$var(Query)");
}
}
route[KEEPALIVE_ON_NOTIFY]
{
if($sel(cfg_get.kazoo.keepalive_enable) == 0) return;
if($shtinc(keepalive=>$si~$sp~$prid) == 1) {
$var(Query) = $_s(UPDATE keepalive set selected = 4 where received = "$si~$sp~$prid" and selected <> 4 );
mq_add("keepalive_db_queue", "keepalive:client_notify", "$var(Query)");
}
}

+ 159
- 0
kamailio-proxy-call/local.cfg View File

@ -0,0 +1,159 @@
################################################################################
## ROLES
################################################################################
## Enabled Roles
#!trydef DISPATCHER_ROLE
#!trydef NAT_TRAVERSAL_ROLE
#!trydef REGISTRAR_ROLE
# # #!trydef PRESENCE_ROLE
#!trydef RESPONDER_ROLE
#!trydef NODES_ROLE
## Disabled Roles - remove all but the last '#' to enable
# # #!trydef TRAFFIC_FILTER_ROLE
# # #!trydef WEBSOCKETS_ROLE
# # #!trydef TLS_ROLE
# # #!trydef ANTIFLOOD_ROLE
# # #!trydef RATE_LIMITER_ROLE
# # #!trydef ACL_ROLE
# # #!trydef MESSAGE_ROLE
# # #!trydef PUSHER_ROLE
# # #!trydef REGISTRAR_SYNC_ROLE
# # #!trydef PRESENCE_NOTIFY_SYNC_ROLE
# # #!trydef SIP_TRACE_ROLE
################################################################################
## SERVER INFORMATION
################################################################################
## UNCOMMENT & CHANGE "kamailio.2600hz.com" TO YOUR SERVERS HOSTNAME
# # #!substdef "!MY_HOSTNAME!kamailio.2600hz.com!g"
## UNCOMMENT & CHANGE "127.0.0.1" TO YOUR SERVERS IP ADDRESS
## Usually your public IP. If you need
## to listen on addtional ports or IPs
## add them in "BINDINGS" at the bottom.
# # #!substdef "!MY_IP_ADDRESS!127.0.0.1!g"
## CHANGE "kazoo://guest:guest@127.0.0.1:5672" TO THE AMQP URL
## This should be the primary RabbitMQ server
## in the zone that this server will service.
# # #!substdef "!MY_AMQP_URL!amqp://guest:guest@127.0.0.1:5672!g"
################################################################################
## WEBSOCKETS
################################################################################
##
## These parameters are only required if you are using websockets
##
## MY_WEBSOCKET_DOMAIN
## This value must be present in the HTTP
## Origin header on a new websocket request
## or it will be rejected. default value is
## domain of this server.
## #!substdef "!MY_WEBSOCKET_DOMAIN!2600hz.com!g"
##
## WEBSOCKET_NO_ORIGIN_RESTRICTION
## if defined, it will disable the origin validation.
##
## #!trydef WEBSOCKET_NO_ORIGIN_RESTRICTION
##
################################################################################
## DATABASE
################################################################################
## This parameter is OPTIONAL
## If you would like to use an external database
## remove all but the last '#' and configure the connector
## accordingly. The example shows how to use postgres.
## See the kamailio documentation for more details.
#!trydef KZ_DB_MODULE postgres
#!substdef "!KAMAILIO_DBMS!postgres!g"
#!substdef "!KAZOO_DB_URL!postgres://kamailio:kamailio@127.0.0.1/kamailio!g"
################################################################################
## UDP PARAMETERS
################################################################################
## This parameter is OPTIONAL
## If large UDP packets are dropped by the
## interface try uncommenting this option.
## However, you MUST match this to your
## network adapter! If they do not match,
## all UDP packets over this limit WILL FAIL!
## E.g.: Add MTU=1472 to the /etc/sysconfig/network-scripts/XXX
# udp4_raw_mtu = 1472
################################################################################
## BINDINGS
################################################################################
## This parameter is OPTIONAL.
## when set to 1,
## It will try to locate outbound interface
## on multihomed host. By default forward
## requests use the incoming socket disregarding
## the destination location. When enabled Kamailio
## will select a socket that can reach the
## destination. This reduces performance.
##!define KZ_MULTI_HOMED 1
################################################################################
## KZ_DISABLE_REGISTRAR_PORTS
################################################################################
## This parameter is OPTIONAL.
## It will disable publishing single proxy port on registrar success messages
## By default single port proxy is send on registrar success messages
## for websockets/tls protocols. the default port is 7000
## which enables config less in freeswitch for handling webrtc/tls
## ie, no certs in freeswitch, no webrtc/tls listeners on freeswitch
## by disabling single port proxy, ecallmgr needs to be started with
## 'use_transport_for_fs_path' set to true in its environment configuration
##
###!define KZ_DISABLE_WEBSOCKETS_REGISTRAR_PORT 1
###!define KZ_DISABLE_TLS_REGISTRAR_PORT 1
##
## you can also change the ports used for single port redirect
##!define KZ_WEBSOCKETS_REGISTRAR_PORT 5060
##!define KZ_TLS_REGISTRAR_PORT 5060
##
## also available for udp/tcp if it works for you
##!define KZ_UDP_REGISTRAR_PORT 7000
##!define KZ_TCP_REGISTRAR_PORT 7000
################################################################################
## SIP traffic mirroring to SIP_TRACE server
################################################################################
## This parameter is OPTIONAL.
## If you have installed SIP_TRACE server (Homer as example),
## then you can mirror INVITE and MESSAGE here
# # #!define SIP_TRACE_URI "sip:127.0.0.1:9060"
# # #!define HEP_CAPTURE_ID 1
## YOU SHOULD NOT HAVE TO CHANGE THESE!
## By setting MY_IP_ADDRESS above these will resolve
## to the proper bindings. These are here
## for those with complex layouts who know
## what they are doing :)
#!substdef "!UDP_SIP!udp:MY_IP_ADDRESS:5060!g"
#!substdef "!TCP_SIP!tcp:MY_IP_ADDRESS:5060!g"
#!substdef "!TLS_SIP!tls:MY_IP_ADDRESS:5061!g"
#!substdef "!UDP_ALG_SIP!udp:MY_IP_ADDRESS:7000!g"
#!substdef "!TCP_ALG_SIP!tcp:MY_IP_ADDRESS:7000!g"
#!substdef "!TLS_ALG_SIP!tls:MY_IP_ADDRESS:7001!g"
#!substdef "!TCP_WS!tcp:MY_IP_ADDRESS:5064!g"
#!substdef "!UDP_WS_SIP!udp:MY_IP_ADDRESS:5064!g"
#!substdef "!TLS_WSS!tls:MY_IP_ADDRESS:5065!g"
#!substdef "!UDP_WSS_SIP!udp:MY_IP_ADDRESS:5065!g"
## YOU SHOULD NOT HAVE TO CHANGE THESE!
## This will bind the default SIP listeners
## as determined above. The tls-role and
## websocket-role will use the appropriate
## definitions if enabled. These are here
## for those with complex layouts who know
## what they are doing :)
listen=UDP_SIP
listen=TCP_SIP
listen=UDP_ALG_SIP
listen=TCP_ALG_SIP
#!ifdef DMQ_ROLE
listen=udp:MY_IP_ADDRESS:5090
#!endif

+ 102
- 0
kamailio-proxy-call/message-role.cfg View File

@ -0,0 +1,102 @@
route[HANDLE_MESSAGE]
{
if (!is_method("MESSAGE")) return;
if (isflagset(FLAG_INTERNALLY_SOURCED) || src_ip == myself) return;
xlog("L_INFO", "$ci|log|MESSAGE from $fu to $tu\n");
route(AUTH);
$xavp(regcfg=>match_received) = $su;
if($avp(is_registered) != "true") {
sl_send_reply("403", "Forbidden");
exit;
} else {
if($hdr(Content-Type) =~ "text/plain" ||
$hdr(Content-Type) =~ "text/html") {
route(MESSAGE_INBOUND);
} else {
xlog("L_WARN", "$ci|end|dropping MESSAGE $hdr(Content-Type)\n");
sl_send_reply("200", "OK");
exit;
}
}
}
route[MESSAGE_INBOUND]
{
$var(key) = "kamailio@MY_HOSTNAME";
route(AUTH_HEADERS_JSON);
$var(Payload) = $_s({"Event-Category" : "sms", "Event-Name" : "inbound", "Call-ID" : "$ci", "Message-ID" : "$ci", "Route-Type" : "onnet", "Route-ID" : "$(var(key){kz.encode})", "From" : "$fU", "To" : "$tU", "Body" : "$rb", "Custom-SIP-Headers" : $var(headers_json), "Msg-ID" : "$uuid(g)"});
$var(exchange) = "im";
$var(RoutingKey) = $_s(sms.inbound.onnet.$(ci{kz.encode}));
xlog("L_INFO", "$ci|msg|sending inbound message $var(RoutingKey) => $var(Payload)\n");
kazoo_publish($var(exchange), $var(RoutingKey), $var(Payload));
sl_send_reply("200", "OK");
exit;
}
event_route[kazoo:consumer-event-sms-outbound]
{
xlog("L_INFO", "$(kzE{kz.json,Message-ID})|log|received message outbound for $(kzE{kz.json,Endpoints[0].To-DID})\n");
$var(from_uri) = $_s(sip:$(kzE{kz.json,From})@$(kzE{kz.json,Custom-Vars.Realm}));
$var(to_uri) = $_s(sip:$(kzE{kz.json,Endpoints[0].To-Username})@$(kzE{kz.json,Endpoints[0].To-Realm}));
$uac_req(method)="MESSAGE";
$uac_req(body)= $kzE;
$uac_req(hdrs)="X-TM-Local: MESSAGE_ROUTE\r\nX-KAZOO-AOR: " + $var(to_uri)+ "\r\nContent-Type: text/plain\r\n";
$uac_req(turi) = $var(to_uri);
$uac_req(ruri) = $var(to_uri);
$uac_req(furi) = $var(from_uri);
$uac_req(ouri) = "sip:127.0.0.1:5090;transport=tcp";
$uac_req(callid) = $(kzE{kz.json,Message-ID});
xlog("L_INFO", "$(kzE{kz.json,Message-ID})|log|sending message from $var(from_uri) to $var(to_uri) \n");
uac_req_send();
}
route[MESSAGE_ROUTE]
{
remove_hf_re("^X-");
route(ROUTE_TO_AOR);
$var(JObj) = $rb;
set_body("$(var(JObj){kz.json,Body})", "text/plain");
$avp(message_id) = $(var(JObj){kz.json,Message-ID});
$avp(msg_id) = $(var(JObj){kz.json,Msg-ID});
$avp(server_id) = $(var(JObj){kz.json,Server-ID});
t_on_reply("MESSAGE_REPLY");
t_on_failure("MESSAGE_FAULT");
t_relay();
}
onreply_route[MESSAGE_REPLY]
{
if($T_reply_code < 300) {
xlog("L_INFO", "$ci|log|sending success delivery message to $avp(server_id)\n");
$var(Payload) = $_s({"Event-Category" : "message", "Event-Name" : "delivery", "Call-ID" : "$ci", "Message-ID" : "$avp(message_id)" , "Delivery-Result-Code" : "sip:$T_reply_code", "Msg-ID" : "$avp(msg_id)" , "Status" : "delivered"});
$var(exchange) = "targeted";
$var(RK) = $avp(server_id);
kazoo_publish($var(exchange), $var(RK), $var(Payload));
}
}
failure_route[MESSAGE_FAULT]
{
xlog("L_INFO", "$ci|log|sending failure delivery message to $avp(server_id)\n");
$var(Payload) = $_s({"Event-Category" : "message", "Event-Name" : "delivery", "Call-ID" : "$ci", "Message-ID" : "$avp(message_id)" , "Delivery-Result-Code" : "sip:$T_reply_code", "Msg-ID" : "$avp(msg_id)" , "Status" : "failure"});
$var(exchange) = "targeted";
$var(RK) = $avp(server_id);
kazoo_publish($var(exchange), $var(RK), $var(Payload));
}
route[MESSAGE_BINDINGS]
{
$var(key) = "kamailio@MY_HOSTNAME";
$var(payload) = $_s({"name": "sms", "exchange": "im", "type": "topic", "queue": "MSG-QUEUE-MY_HOSTNAME", "routing": "sms.outbound.$(var(key){kz.encode}).*", "no_ack": false, "federate": true });
kazoo_subscribe("$var(payload)");
}
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save