├── dispatcher.list ├── README.md └── kamailio.cfg /dispatcher.list: -------------------------------------------------------------------------------- 1 | 1 sip:10.10.10.10;transport=udp 0 0 2 | 1 sip:10.10.10.11;transport=udp 0 0 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dispatcher 2 | Simple config file of Kamailio as Loadblancer for calls and registrations 3 | 4 | This is simple config for somebody who need to use Kamailio as Loadbalancer in front of Freeswitch or Asterisk. This particular configuration will Loadbalance not only INVITEs, but registrations too. 5 | 6 | Following configuration I took as template: 7 | http://kamailio.org/docs/modules/5.3.x/modules/dispatcher.html#dispatcher.ex.config 8 | 9 | On freeswitch side I added following lines to sip profile config: 10 | 11 | \ 12 | 13 | \ 14 | 15 | Additionnally you need to configure domain in vars.xml: 16 | 17 | \ 18 | 19 | To make this configuration work you will need to add freeswitch/asterisk to list file(dispather.list as example) or to mysql db. 20 | 21 | To make DB work you will need to uncomment lines related to DB and make sure that DB url is set properly and don't forget to remove line where list file is set). 22 | 23 | And off cause you will need to insert related data: 24 | 25 | `INSERT INTO dispatcher(setid, destination, flags, priority) values (1, 'sip:freeswitchip1:5060', 0, 0);` 26 | 27 | `INSERT INTO dispatcher(setid, destination, flags, priority) values (1, 'sip:freeswitchip2:5060', 0, 0);` 28 | 29 | Please make sure that setid is `1` for both servers. 30 | -------------------------------------------------------------------------------- /kamailio.cfg: -------------------------------------------------------------------------------- 1 | #!KAMAILIO 2 | # 3 | # sample config file for dispatcher module 4 | # - load balancing of VoIP calls with round robin 5 | # - no TPC listening 6 | # - don't dispatch REGISTER and presence requests 7 | # 8 | # Kamailio SIP Server 9 | # - web: http://www.kamailio.org 10 | # - git: http://github.com/kamailio/ 11 | # 12 | # Direct your questions about this file to: sr-users@lists.kamailio.org 13 | # 14 | # Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php 15 | # for an explanation of possible statements, functions and parameters. 16 | # 17 | # Several features can be enabled using '#!define WITH_FEATURE' directives: 18 | # 19 | # *** To run in debug mode: 20 | # - define WITH_DEBUG 21 | # 22 | 23 | #-!ifndef DBURL 24 | #-!define DBURL "mysql://kamailio:kamailiorw@localhost/kamailio" 25 | #-!endif 26 | 27 | # - flags 28 | # FLT_ - per transaction (message) flags 29 | # FLB_ - per branch flags 30 | #!define FLT_ACC 1 31 | #!define FLT_ACCMISSED 2 32 | #!define FLT_ACCFAILED 3 33 | 34 | #!define FLT_FS 10 35 | 36 | ####### Global Parameters ######### 37 | 38 | #!ifdef WITH_DEBUG 39 | debug=4 40 | log_stderror=yes 41 | #!else 42 | debug=2 43 | log_stderror=no 44 | #!endif 45 | 46 | memdbg=5 47 | memlog=5 48 | 49 | log_facility=LOG_LOCAL0 50 | 51 | fork=yes 52 | children=4 53 | 54 | /* comment the next line to enable TCP */ 55 | disable_tcp=yes 56 | 57 | /* uncomment the next line to disable the auto discovery of local aliases 58 | based on revers DNS on IPs (default on) */ 59 | auto_aliases=no 60 | 61 | /* add local domain aliases */ 62 | # alias="mysipserver.com" 63 | 64 | port=5060 65 | 66 | /* uncomment and configure the following line if you want Kamailio to 67 | bind on a specific interface/port/proto (default bind on all available) */ 68 | # listen=udp:127.0.0.1:5060 69 | 70 | sip_warning=no 71 | 72 | ####### Modules Section ######## 73 | 74 | # set module path 75 | #mpath="/usr/local/lib/kamailio/modules/" 76 | 77 | #loadmodule "db_mysql.so" 78 | loadmodule "jsonrpcs.so" 79 | loadmodule "kex.so" 80 | loadmodule "corex.so" 81 | loadmodule "tm.so" 82 | loadmodule "tmx.so" 83 | loadmodule "sl.so" 84 | loadmodule "rr.so" 85 | loadmodule "pv.so" 86 | loadmodule "maxfwd.so" 87 | loadmodule "textops.so" 88 | loadmodule "siputils.so" 89 | loadmodule "xlog.so" 90 | loadmodule "sanity.so" 91 | loadmodule "ctl.so" 92 | loadmodule "acc.so" 93 | loadmodule "dispatcher.so" 94 | loadmodule "path.so" 95 | 96 | # ----------------- setting module-specific parameters --------------- 97 | 98 | 99 | # ----- jsonrpcs params ----- 100 | modparam("jsonrpcs", "pretty_format", 1) 101 | 102 | 103 | # ----- rr params ----- 104 | # add value to ;lr param to cope with most of the UAs 105 | modparam("rr", "enable_full_lr", 1) 106 | # do not append from tag to the RR (no need for this script) 107 | modparam("rr", "append_fromtag", 0) 108 | 109 | 110 | # ----- acc params ----- 111 | modparam("acc", "log_flag", FLT_ACC) 112 | modparam("acc", "failed_transaction_flag", FLT_ACCFAILED) 113 | modparam("acc", "log_extra", "src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd;src_ip=$si") 114 | 115 | # ----- tm params ----- 116 | modparam("tm", "fr_timer", 2000) 117 | modparam("tm", "fr_inv_timer", 40000) 118 | 119 | # ----- dispatcher params ----- 120 | #modparam("dispatcher", "db_url", DBURL) 121 | #modparam("dispatcher", "table_name", "dispatcher") 122 | modparam("dispatcher", "list_file", "/usr/local/etc/kamailio/dispatcher.list") 123 | modparam("dispatcher", "flags", 2) 124 | modparam("dispatcher", "xavp_dst", "_dsdst_") 125 | modparam("dispatcher", "xavp_ctx", "_dsctx_") 126 | modparam("dispatcher", "ds_ping_from", "sip:proxy@mykamailio") 127 | modparam("dispatcher", "ds_ping_interval", 5) 128 | modparam("dispatcher", "ds_probing_threshold", 5) 129 | modparam("dispatcher", "ds_inactive_threshold", 5) 130 | modparam("dispatcher", "ds_ping_reply_codes", "class=2;code=403;code=488;class=3") 131 | modparam("dispatcher", "ds_probing_mode", 1) 132 | 133 | modparam("path", "use_received", 1) 134 | 135 | ####### Routing Logic ######## 136 | 137 | 138 | # main request routing logic 139 | 140 | request_route { 141 | 142 | # per request initial checks 143 | route(REQINIT); 144 | 145 | if(ds_is_from_list()) { 146 | setflag(FLT_FS); 147 | } 148 | 149 | # CANCEL processing 150 | if (is_method("CANCEL")) { 151 | if (t_check_trans()) { 152 | route(RELAY); 153 | } 154 | exit; 155 | } 156 | 157 | # handle retransmissions 158 | if (!is_method("ACK")) { 159 | if(t_precheck_trans()) { 160 | t_check_trans(); 161 | exit; 162 | } 163 | t_check_trans(); 164 | } 165 | 166 | # handle requests within SIP dialogs 167 | route(WITHINDLG); 168 | 169 | ### only initial requests (no To tag) 170 | 171 | # record routing for dialog forming requests (in case they are routed) 172 | # - remove preloaded route headers 173 | remove_hf("Route"); 174 | if (is_method("INVITE|SUBSCRIBE")) { 175 | record_route(); 176 | } 177 | 178 | if (isflagset(FLT_FS)) { 179 | route(FROM_FS); 180 | exit; 181 | } 182 | 183 | # account only INVITEs 184 | if (is_method("INVITE")) { 185 | setflag(FLT_ACC); # do accounting 186 | } 187 | 188 | # handle presence related requests 189 | route(PRESENCE); 190 | 191 | # handle registrations 192 | route(REGISTRAR); 193 | 194 | if ($rU==$null) { 195 | # request with no Username in RURI 196 | sl_send_reply("484","Address Incomplete"); 197 | exit; 198 | } 199 | 200 | # dispatch destinations 201 | route(DISPATCH); 202 | } 203 | 204 | route[FROM_FS] 205 | { 206 | route(RELAY); 207 | exit; 208 | } 209 | 210 | route[RELAY] { 211 | if (!t_relay()) { 212 | sl_reply_error(); 213 | } 214 | exit; 215 | } 216 | 217 | # Per SIP request initial checks 218 | route[REQINIT] { 219 | if (!mf_process_maxfwd_header("10")) { 220 | sl_send_reply("483","Too Many Hops"); 221 | exit; 222 | } 223 | 224 | if(!sanity_check("1511", "7")) { 225 | xlog("Malformed SIP message from $si:$sp\n"); 226 | exit; 227 | } 228 | } 229 | 230 | # Handle requests within SIP dialogs 231 | route[WITHINDLG] { 232 | if (has_totag()) { 233 | # sequential request withing a dialog should 234 | # take the path determined by record-routing 235 | if (loose_route()) { 236 | if (is_method("BYE")) { 237 | setflag(FLT_ACC); # do accounting ... 238 | setflag(FLT_ACCFAILED); # ... even if the transaction fails 239 | } 240 | route(RELAY); 241 | } else { 242 | if (is_method("SUBSCRIBE") && uri == myself) { 243 | # in-dialog subscribe requests 244 | route(PRESENCE); 245 | exit; 246 | } 247 | if ( is_method("ACK") ) { 248 | if ( t_check_trans() ) { 249 | # non loose-route, but stateful ACK; 250 | # must be ACK after a 487 or e.g. 404 from upstream server 251 | t_relay(); 252 | exit; 253 | } else { 254 | # ACK without matching transaction ... ignore and discard. 255 | exit; 256 | } 257 | } 258 | sl_send_reply("404","Not here"); 259 | } 260 | exit; 261 | } 262 | } 263 | 264 | # Handle SIP registrations 265 | route[REGISTRAR] { 266 | if(!is_method("REGISTER")) 267 | return; 268 | add_path_received(); 269 | route(DISPATCH); 270 | } 271 | 272 | # Presence server route 273 | route[PRESENCE] { 274 | if(!is_method("PUBLISH|SUBSCRIBE")) 275 | return; 276 | 277 | sl_send_reply("404", "Not here"); 278 | exit; 279 | } 280 | 281 | # Dispatch requests 282 | route[DISPATCH] { 283 | # round robin dispatching on gateways group '1' 284 | if(!ds_select_dst("1", "4")) { 285 | send_reply("404", "No destination"); 286 | exit; 287 | } 288 | xdbg("--- SCRIPT: going to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n"); 289 | t_on_failure("RTF_DISPATCH"); 290 | route(RELAY); 291 | exit; 292 | } 293 | 294 | # Try next destionations in failure route 295 | failure_route[RTF_DISPATCH] { 296 | if (t_is_canceled()) { 297 | exit; 298 | } 299 | # next DST - only for 500 or local timeout 300 | if (t_check_status("500") 301 | or (t_branch_timeout() and !t_branch_replied())) { 302 | if(ds_next_dst()) { 303 | xdbg("--- SCRIPT: retrying to <$ru> via <$du> (attrs: $xavp(_dsdst_=>attrs))\n"); 304 | t_on_failure("RTF_DISPATCH"); 305 | route(RELAY); 306 | exit; 307 | } 308 | } 309 | } 310 | --------------------------------------------------------------------------------