00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00062 #include <stdio.h>
00063 #include "../../sr_module.h"
00064 #include "../../timer.h"
00065 #include "../../dprint.h"
00066 #include "../../error.h"
00067 #include "../../socket_info.h"
00068 #include "../../pvar.h"
00069 #include "../../modules_k/usrloc/usrloc.h"
00070 #include "../../lib/kcore/statistics.h"
00071 #include "../../lib/srutils/sruid.h"
00072 #include "../../modules/sl/sl.h"
00073 #include "../../mod_fix.h"
00074
00075 #include "save.h"
00076 #include "api.h"
00077 #include "lookup.h"
00078 #include "regpv.h"
00079 #include "reply.h"
00080 #include "reg_mod.h"
00081 #include "config.h"
00082
00083 MODULE_VERSION
00084
00085 usrloc_api_t ul;
00088 static int mod_init(void);
00089 static int child_init(int);
00090 static void mod_destroy(void);
00091 static int w_save2(struct sip_msg* _m, char* _d, char* _cflags);
00092 static int w_save3(struct sip_msg* _m, char* _d, char* _cflags, char* _uri);
00093 static int w_lookup(struct sip_msg* _m, char* _d, char* _p2);
00094 static int w_registered(struct sip_msg* _m, char* _d, char* _uri);
00095 static int w_unregister(struct sip_msg* _m, char* _d, char* _uri);
00096
00098 static int domain_fixup(void** param, int param_no);
00099 static int domain_uri_fixup(void** param, int param_no);
00100 static int save_fixup(void** param, int param_no);
00101 static int unreg_fixup(void** param, int param_no);
00102 static int fetchc_fixup(void** param, int param_no);
00104 static int add_sock_hdr(struct sip_msg* msg, char *str, char *foo);
00105
00106 int tcp_persistent_flag = -1;
00107 int method_filtering = 0;
00108 int path_enabled = 0;
00109 int path_mode = PATH_MODE_STRICT;
00114 int path_use_params = 0;
00117
00118 sruid_t _reg_sruid;
00119
00120 int reg_gruu_enabled = 1;
00121
00122
00123 char *reg_callid_avp_param = 0;
00124 unsigned short reg_callid_avp_type = 0;
00125 int_str reg_callid_avp_name;
00126
00127 char* rcv_avp_param = 0;
00128 unsigned short rcv_avp_type = 0;
00129 int_str rcv_avp_name;
00130
00131 str reg_xavp_cfg = {0};
00132 str reg_xavp_rcd = {0};
00133
00134 int reg_use_domain = 0;
00135
00136 int sock_flag = -1;
00137 str sock_hdr_name = {0,0};
00138
00139 #define RCV_NAME "received"
00140 str rcv_param = str_init(RCV_NAME);
00141
00142 stat_var *accepted_registrations;
00143 stat_var *rejected_registrations;
00144 stat_var *max_expires_stat;
00145 stat_var *max_contacts_stat;
00146 stat_var *default_expire_stat;
00147 stat_var *default_expire_range_stat;
00149 sl_api_t slb;
00150
00154 static pv_export_t mod_pvs[] = {
00155 { {"ulc", sizeof("ulc")-1}, PVT_OTHER, pv_get_ulc, pv_set_ulc,
00156 pv_parse_ulc_name, pv_parse_index, 0, 0 },
00157 { {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
00158 };
00159
00160
00164 static cmd_export_t cmds[] = {
00165 {"save", (cmd_function)w_save2, 1, save_fixup, 0,
00166 REQUEST_ROUTE | ONREPLY_ROUTE },
00167 {"save", (cmd_function)w_save2, 2, save_fixup, 0,
00168 REQUEST_ROUTE | ONREPLY_ROUTE },
00169 {"save", (cmd_function)w_save3, 3, save_fixup, 0,
00170 REQUEST_ROUTE | ONREPLY_ROUTE },
00171 {"lookup", (cmd_function)w_lookup, 1, domain_uri_fixup, 0,
00172 REQUEST_ROUTE | FAILURE_ROUTE },
00173 {"lookup", (cmd_function)w_lookup, 2, domain_uri_fixup, 0,
00174 REQUEST_ROUTE | FAILURE_ROUTE },
00175 {"registered", (cmd_function)w_registered, 1, domain_uri_fixup, 0,
00176 REQUEST_ROUTE | FAILURE_ROUTE },
00177 {"registered", (cmd_function)w_registered, 2, domain_uri_fixup, 0,
00178 REQUEST_ROUTE | FAILURE_ROUTE },
00179 {"add_sock_hdr", (cmd_function)add_sock_hdr, 1, fixup_str_null, 0,
00180 REQUEST_ROUTE },
00181 {"unregister", (cmd_function)w_unregister, 2, unreg_fixup, 0,
00182 REQUEST_ROUTE| FAILURE_ROUTE },
00183 {"reg_fetch_contacts", (cmd_function)pv_fetch_contacts, 3,
00184 fetchc_fixup, 0,
00185 REQUEST_ROUTE| FAILURE_ROUTE },
00186 {"reg_free_contacts", (cmd_function)pv_free_contacts, 1,
00187 fixup_str_null, 0,
00188 REQUEST_ROUTE| FAILURE_ROUTE },
00189 {"bind_registrar", (cmd_function)bind_registrar, 0,
00190 0, 0, 0},
00191 {0, 0, 0, 0, 0, 0}
00192 };
00193
00194
00198 static param_export_t params[] = {
00199 {"default_expires", INT_PARAM, &default_registrar_cfg.default_expires },
00200 {"default_expires_range", INT_PARAM, &default_registrar_cfg.default_expires_range },
00201 {"default_q", INT_PARAM, &default_registrar_cfg.default_q },
00202 {"append_branches", INT_PARAM, &default_registrar_cfg.append_branches },
00203 {"case_sensitive", INT_PARAM, &default_registrar_cfg.case_sensitive },
00204
00205 {"realm_prefix", PARAM_STR, &default_registrar_cfg.realm_pref },
00206 {"min_expires", INT_PARAM, &default_registrar_cfg.min_expires },
00207 {"max_expires", INT_PARAM, &default_registrar_cfg.max_expires },
00208 {"received_param", STR_PARAM, &rcv_param },
00209 {"received_avp", STR_PARAM, &rcv_avp_param },
00210 {"reg_callid_avp", STR_PARAM, ®_callid_avp_param },
00211 {"max_contacts", INT_PARAM, &default_registrar_cfg.max_contacts },
00212 {"retry_after", INT_PARAM, &default_registrar_cfg.retry_after },
00213 {"sock_flag", INT_PARAM, &sock_flag },
00214 {"sock_hdr_name", STR_PARAM, &sock_hdr_name.s },
00215 {"method_filtering", INT_PARAM, &method_filtering },
00216 {"use_path", INT_PARAM, &path_enabled },
00217 {"path_mode", INT_PARAM, &path_mode },
00218 {"path_use_received", INT_PARAM, &path_use_params },
00219 {"xavp_cfg", STR_PARAM, ®_xavp_cfg.s },
00220 {"xavp_rcd", STR_PARAM, ®_xavp_rcd.s },
00221 {"gruu_enabled", INT_PARAM, ®_gruu_enabled },
00222 {0, 0, 0}
00223 };
00224
00225
00227 stat_export_t mod_stats[] = {
00228 {"max_expires", STAT_NO_RESET, &max_expires_stat },
00229 {"max_contacts", STAT_NO_RESET, &max_contacts_stat },
00230 {"default_expire", STAT_NO_RESET, &default_expire_stat },
00231 {"default_expires_range", STAT_NO_RESET, &default_expire_range_stat },
00232 {"accepted_regs", 0, &accepted_registrations },
00233 {"rejected_regs", 0, &rejected_registrations },
00234 {0, 0, 0}
00235 };
00236
00237
00238
00242 struct module_exports exports = {
00243 "registrar",
00244 DEFAULT_DLFLAGS,
00245 cmds,
00246 params,
00247 mod_stats,
00248 0,
00249 mod_pvs,
00250 0,
00251 mod_init,
00252 0,
00253 mod_destroy,
00254 child_init,
00255 };
00256
00257
00261 static int mod_init(void)
00262 {
00263 pv_spec_t avp_spec;
00264 str s;
00265 bind_usrloc_t bind_usrloc;
00266 qvalue_t dq;
00267
00268
00269 if(sruid_init(&_reg_sruid, '-', "uloc", SRUID_INC)<0)
00270 return -1;
00271
00272 #ifdef STATISTICS
00273
00274 if (register_module_stats( exports.name, mod_stats)!=0 ) {
00275 LM_ERR("failed to register core statistics\n");
00276 return -1;
00277 }
00278 #endif
00279
00280
00281 if (sl_load_api(&slb)!=0) {
00282 LM_ERR("cannot bind to SL API\n");
00283 return -1;
00284 }
00285
00286 rcv_param.len = strlen(rcv_param.s);
00287
00288 if(cfg_declare("registrar", registrar_cfg_def, &default_registrar_cfg, cfg_sizeof(registrar), ®istrar_cfg)){
00289 LM_ERR("Fail to declare the configuration\n");
00290 return -1;
00291 }
00292
00293
00294
00295 if (rcv_avp_param && *rcv_avp_param) {
00296 s.s = rcv_avp_param; s.len = strlen(s.s);
00297 if (pv_parse_spec(&s, &avp_spec)==0
00298 || avp_spec.type!=PVT_AVP) {
00299 LM_ERR("malformed or non AVP %s AVP definition\n", rcv_avp_param);
00300 return -1;
00301 }
00302
00303 if(pv_get_avp_name(0, &avp_spec.pvp, &rcv_avp_name, &rcv_avp_type)!=0)
00304 {
00305 LM_ERR("[%s]- invalid AVP definition\n", rcv_avp_param);
00306 return -1;
00307 }
00308 } else {
00309 rcv_avp_name.n = 0;
00310 rcv_avp_type = 0;
00311 }
00312
00313 if (reg_callid_avp_param && *reg_callid_avp_param) {
00314 s.s = reg_callid_avp_param; s.len = strlen(s.s);
00315 if (pv_parse_spec(&s, &avp_spec)==0
00316 || avp_spec.type!=PVT_AVP) {
00317 LM_ERR("malformed or non AVP %s AVP definition\n", reg_callid_avp_param);
00318 return -1;
00319 }
00320
00321 if(pv_get_avp_name(0, &avp_spec.pvp, ®_callid_avp_name, ®_callid_avp_type)!=0)
00322 {
00323 LM_ERR("[%s]- invalid AVP definition\n", reg_callid_avp_param);
00324 return -1;
00325 }
00326 } else {
00327 reg_callid_avp_name.n = 0;
00328 reg_callid_avp_type = 0;
00329 }
00330
00331 bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
00332 if (!bind_usrloc) {
00333 LM_ERR("can't bind usrloc\n");
00334 return -1;
00335 }
00336
00337
00338 dq = cfg_get(registrar, registrar_cfg, default_q);
00339 if ( dq!= Q_UNSPECIFIED) {
00340 if (dq > MAX_Q) {
00341 LM_DBG("default_q = %d, lowering to MAX_Q: %d\n", dq, MAX_Q);
00342 dq = MAX_Q;
00343 } else if (dq < MIN_Q) {
00344 LM_DBG("default_q = %d, raising to MIN_Q: %d\n", dq, MIN_Q);
00345 dq = MIN_Q;
00346 }
00347 }
00348 cfg_get(registrar, registrar_cfg, default_q) = dq;
00349
00350 if (bind_usrloc(&ul) < 0) {
00351 return -1;
00352 }
00353
00354
00355
00356
00357 reg_use_domain = ul.use_domain;
00358
00359 if (sock_hdr_name.s) {
00360 sock_hdr_name.len = strlen(sock_hdr_name.s);
00361 if (sock_hdr_name.len==0 || sock_flag==-1) {
00362 LM_WARN("empty sock_hdr_name or sock_flag no set -> reseting\n");
00363 pkg_free(sock_hdr_name.s);
00364 sock_hdr_name.s = 0;
00365 sock_hdr_name.len = 0;
00366 sock_flag = -1;
00367 }
00368 } else if (sock_flag!=-1) {
00369 LM_WARN("sock_flag defined but no sock_hdr_name -> reseting flag\n");
00370 sock_flag = -1;
00371 }
00372
00373
00374 sock_flag = (sock_flag!=-1)?(1<<sock_flag):0;
00375 tcp_persistent_flag = (tcp_persistent_flag!=-1)?(1<<tcp_persistent_flag):0;
00376
00377 if (reg_xavp_cfg.s) {
00378 reg_xavp_cfg.len = strlen(reg_xavp_cfg.s);
00379 }
00380 if (reg_xavp_rcd.s) {
00381 reg_xavp_rcd.len = strlen(reg_xavp_rcd.s);
00382 }
00383 return 0;
00384 }
00385
00386
00387 static int child_init(int rank)
00388 {
00389 if(sruid_init(&_reg_sruid, '-', "uloc", SRUID_INC)<0)
00390 return -1;
00391 if (rank==1) {
00392
00393
00394 update_stat( max_expires_stat, default_registrar_cfg.max_expires );
00395 update_stat( max_contacts_stat, default_registrar_cfg.max_contacts );
00396 update_stat( default_expire_stat, default_registrar_cfg.default_expires );
00397 }
00398
00399 return 0;
00400 }
00401
00405 static int w_save2(struct sip_msg* _m, char* _d, char* _cflags)
00406 {
00407 return save(_m, (udomain_t*)_d, ((int)(unsigned long)_cflags), NULL);
00408 }
00409
00413 static int w_save3(struct sip_msg* _m, char* _d, char* _cflags, char* _uri)
00414 {
00415 str uri;
00416 if(fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0)
00417 {
00418 LM_ERR("invalid uri parameter\n");
00419 return -1;
00420 }
00421
00422 return save(_m, (udomain_t*)_d, ((int)(unsigned long)_cflags), &uri);
00423 }
00424
00428 static int w_lookup(struct sip_msg* _m, char* _d, char* _uri)
00429 {
00430 str uri = {0};
00431 if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
00432 {
00433 LM_ERR("invalid uri parameter\n");
00434 return -1;
00435 }
00436
00437 return lookup(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL);
00438 }
00439
00440 static int w_registered(struct sip_msg* _m, char* _d, char* _uri)
00441 {
00442 str uri = {0};
00443 if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
00444 {
00445 LM_ERR("invalid uri parameter\n");
00446 return -1;
00447 }
00448 return registered(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL);
00449 }
00450
00451 static int w_unregister(struct sip_msg* _m, char* _d, char* _uri)
00452 {
00453 str uri = {0};
00454 if(fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0)
00455 {
00456 LM_ERR("invalid uri parameter\n");
00457 return -1;
00458 }
00459
00460 return unregister(_m, (udomain_t*)_d, &uri);
00461 }
00462
00466 static int domain_fixup(void** param, int param_no)
00467 {
00468 udomain_t* d;
00469
00470 if (param_no == 1) {
00471 if (ul.register_udomain((char*)*param, &d) < 0) {
00472 LM_ERR("failed to register domain\n");
00473 return E_UNSPEC;
00474 }
00475
00476 *param = (void*)d;
00477 }
00478 return 0;
00479 }
00480
00484 static int domain_uri_fixup(void** param, int param_no)
00485 {
00486 if (param_no == 1) {
00487 return domain_fixup(param, 1);
00488 } else if (param_no == 2) {
00489 return fixup_spve_null(param, 1);
00490 }
00491 return 0;
00492 }
00493
00494
00499 static int unreg_fixup(void** param, int param_no)
00500 {
00501 if (param_no == 1) {
00502 return domain_fixup(param, 1);
00503 } else if (param_no == 2) {
00504 return fixup_spve_null(param, 1);
00505 }
00506 return 0;
00507 }
00508
00509
00510
00514 static int save_fixup(void** param, int param_no)
00515 {
00516 unsigned int flags;
00517 str s;
00518
00519 if (param_no == 1) {
00520 return domain_fixup(param,param_no);
00521 } else if (param_no == 2) {
00522 s.s = (char*)*param;
00523 s.len = strlen(s.s);
00524 flags = 0;
00525 if ( (strno2int(&s, &flags )<0) || (flags>REG_SAVE_ALL_FL) ) {
00526 LM_ERR("bad flags <%s>\n", (char *)(*param));
00527 return E_CFG;
00528 }
00529 if (ul.db_mode==DB_ONLY && flags®_SAVE_MEM_FL) {
00530 LM_ERR("MEM flag set while using the DB_ONLY mode in USRLOC\n");
00531 return E_CFG;
00532 }
00533 pkg_free(*param);
00534 *param = (void*)(unsigned long int)flags;
00535 } else if (param_no == 3) {
00536 return fixup_spve_null(param, 1);
00537 }
00538 return 0;
00539 }
00540
00546 static int fetchc_fixup(void** param, int param_no)
00547 {
00548 if (param_no == 1) {
00549 return domain_fixup(param, 1);
00550 } else if (param_no == 2) {
00551 return fixup_spve_null(param, 1);
00552 } else if (param_no == 3) {
00553 return fixup_str_null(param, 1);
00554 }
00555 return 0;
00556 }
00557
00558
00559 static void mod_destroy(void)
00560 {
00561 free_contact_buf();
00562 }
00563
00564
00565 #include "../../data_lump.h"
00566 #include "../../ip_addr.h"
00567 #include "../../ut.h"
00568
00569 static int add_sock_hdr(struct sip_msg* msg, char *name, char *foo)
00570 {
00571 struct socket_info* si;
00572 struct lump* anchor;
00573 str *hdr_name;
00574 str hdr;
00575 char *p;
00576
00577 hdr_name = (str*)name;
00578 si = msg->rcv.bind_address;
00579
00580 if (parse_headers( msg, HDR_EOH_F, 0) == -1) {
00581 LM_ERR("failed to parse message\n");
00582 goto error;
00583 }
00584
00585 anchor = anchor_lump( msg, msg->unparsed-msg->buf, 0, 0);
00586 if (anchor==0) {
00587 LM_ERR("can't get anchor\n");
00588 goto error;
00589 }
00590
00591 hdr.len = hdr_name->len + 2 + si->sock_str.len + CRLF_LEN;
00592 if ( (hdr.s=(char*)pkg_malloc(hdr.len))==0 ) {
00593 LM_ERR("no more pkg mem\n");
00594 goto error;
00595 }
00596
00597 p = hdr.s;
00598 memcpy( p, hdr_name->s, hdr_name->len);
00599 p += hdr_name->len;
00600 *(p++) = ':';
00601 *(p++) = ' ';
00602
00603 memcpy( p, si->sock_str.s, si->sock_str.len);
00604 p += si->sock_str.len;
00605
00606 memcpy( p, CRLF, CRLF_LEN);
00607 p += CRLF_LEN;
00608
00609 if ( p-hdr.s!=hdr.len ) {
00610 LM_CRIT("buffer overflow (%d!=%d)\n", (int)(long)(p-hdr.s),hdr.len);
00611 goto error1;
00612 }
00613
00614 if (insert_new_lump_before( anchor, hdr.s, hdr.len, 0) == 0) {
00615 LM_ERR("can't insert lump\n");
00616 goto error1;
00617 }
00618
00619 return 1;
00620 error1:
00621 pkg_free(hdr.s);
00622 error:
00623 return -1;
00624 }
00625
00626 void default_expires_stats_update(str* gname, str* name){
00627 update_stat(default_expire_stat, cfg_get(registrar, registrar_cfg, default_expires));
00628 }
00629
00630 void max_expires_stats_update(str* gname, str* name){
00631 update_stat(max_expires_stat, cfg_get(registrar, registrar_cfg, max_expires));
00632 }
00633
00634 void default_expires_range_update(str* gname, str* name){
00635 update_stat(default_expire_range_stat, cfg_get(registrar, registrar_cfg, default_expires_range));
00636 }