00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00030 #include <ctype.h>
00031 #include <assert.h>
00032 #include <stdlib.h>
00033 #include "cr_func.h"
00034 #include "cr_db.h"
00035 #include "../../sr_module.h"
00036 #include "../../action.h"
00037 #include "../../parser/parse_uri.h"
00038 #include "../../parser/parse_from.h"
00039 #include "../../ut.h"
00040 #include "../../parser/digest/digest.h"
00041 #include "../../parser/hf.h"
00042 #include "../../mem/mem.h"
00043 #include "../../qvalue.h"
00044 #include "../../dset.h"
00045 #include "cr_map.h"
00046 #include "cr_rule.h"
00047 #include "cr_domain.h"
00048 #include "cr_carrier.h"
00049 #include "carrierroute.h"
00050 #include "config.h"
00051
00052 enum hash_algorithm {
00053 alg_crc32 = 1,
00054 alg_crc32_nofallback,
00056 alg_error
00057 };
00058
00059
00060 static const str SIP_URI = { .s="sip:", .len=4 };
00061 static const str SIPS_URI = { .s="sips:", .len=5 };
00062 static const str AT_SIGN = { .s="@", .len=1 };
00063 static char g_rewrite_uri[MAX_URI_SIZE+1];
00064
00076 static inline int cr_gp2id(struct sip_msg *_msg, gparam_t *gp, struct name_map_t *map, int size) {
00077 int id;
00078 struct usr_avp *avp;
00079 int_str avp_val;
00080 str tmp;
00081
00082 switch (gp->type) {
00083 case GPARAM_TYPE_INT:
00084 return gp->v.i;
00085 break;
00086 case GPARAM_TYPE_PVE:
00087
00088 if (gp->v.pve->spec.type==PVT_AVP) {
00089 avp = search_first_avp(gp->v.pve->spec.pvp.pvn.u.isname.type,
00090 gp->v.pve->spec.pvp.pvn.u.isname.name, &avp_val, 0);
00091 if (!avp) {
00092 if(gp->v.pve->spec.pvp.pvn.u.isname.type & AVP_NAME_STR)
00093 LM_ERR("cannot find AVP '%.*s'\n", gp->v.pve->spec.pvp.pvn.u.isname.name.s.len,
00094 gp->v.pve->spec.pvp.pvn.u.isname.name.s.s);
00095 else if(gp->v.pve->spec.pvp.pvn.u.isname.type & AVP_NAME_RE)
00096 LM_ERR("cannot find AVP regex\n");
00097 else LM_ERR("cannot find AVP '%d'\n", gp->v.pve->spec.pvp.pvn.u.isname.name.n);
00098 return -1;
00099 }
00100 if ((avp->flags&AVP_VAL_STR)==0) {
00101 return avp_val.n;
00102 } else {
00103 id = map_name2id(map, size, &avp_val.s);
00104 if (id < 0) {
00105 if(gp->v.pve->spec.pvp.pvn.u.isname.type & AVP_NAME_STR)
00106 LM_ERR("cannot map carrier with id %.*s from AVP '%.*s'\n", avp_val.s.len, avp_val.s.s, gp->v.pve->spec.pvp.pvn.u.isname.name.s.len,
00107 gp->v.pve->spec.pvp.pvn.u.isname.name.s.s);
00108 else if(gp->v.pve->spec.pvp.pvn.u.isname.type & AVP_NAME_RE)
00109 LM_ERR("cannot map carrier with id %.*s from AVP regex\n", avp_val.s.len, avp_val.s.s);
00110 else LM_ERR("cannot map carrier with id %.*s from AVP '%d'\n", avp_val.s.len, avp_val.s.s, gp->v.pve->spec.pvp.pvn.u.isname.name.n);
00111 return -1;
00112 }
00113 return id;
00114 }
00115 } else {
00116
00117 if (fixup_get_svalue(_msg, gp, &tmp)<0) {
00118 LM_ERR("cannot print the name from PV\n");
00119 return -1;
00120 }
00121 id = map_name2id(map, size, &tmp);
00122 if (id < 0) {
00123 LM_ERR("could not find id '%.*s' from PV\n", tmp.len, tmp.s);
00124 return -1;
00125 }
00126 return id;
00127 }
00128 default:
00129 LM_ERR("invalid parameter type\n");
00130 return -1;
00131 }
00132 }
00133
00134
00143 static inline int reply_code_matcher(const str *rcw, const str *rc) {
00144 int i;
00145
00146 if (rcw->len==0) return 0;
00147
00148 if (rcw->len != rc->len) return -1;
00149
00150 for (i=0; i<rc->len; i++) {
00151 if (rcw->s[i]!='.' && rcw->s[i]!=rc->s[i]) return -1;
00152 }
00153
00154 return 0;
00155 }
00156
00157
00169 static int set_next_domain_on_rule(struct failure_route_rule *frr_head,
00170 const str *host, const str *reply_code, const flag_t flags,
00171 const gparam_t *dstavp) {
00172 struct failure_route_rule * rr;
00173 int_str avp_val;
00174
00175 assert(frr_head != NULL);
00176
00177 LM_DBG("searching for matching routing rules");
00178 for (rr = frr_head; rr != NULL; rr = rr->next) {
00179
00180
00181
00182
00183
00184
00185
00186 if (((rr->mask & flags) == rr->flags) &&
00187 ((rr->host.len == 0) || (str_strcmp(host, &rr->host)==0)) &&
00188 (reply_code_matcher(&(rr->reply_code), reply_code)==0)) {
00189 avp_val.n = rr->next_domain;
00190 if (add_avp(dstavp->v.pve->spec.pvp.pvn.u.isname.type,
00191 dstavp->v.pve->spec.pvp.pvn.u.isname.name, avp_val)<0) {
00192 LM_ERR("set AVP failed\n");
00193 return -1;
00194 }
00195
00196 LM_INFO("next_domain is %d\n", rr->next_domain);
00197 return 0;
00198 }
00199 }
00200
00201 LM_INFO("no matching rule for (flags=%d, host='%.*s', reply_code='%.*s') found\n", flags, host->len, host->s, reply_code->len, reply_code->s);
00202 return -1;
00203 }
00204
00205
00220 static int set_next_domain_recursor(struct dtrie_node_t *failure_node,
00221 const str *uri, const str *host, const str *reply_code, const flag_t flags,
00222 const gparam_t *dstavp) {
00223 str re_uri = *uri;
00224 void **ret;
00225
00226
00227 while (re_uri.len > 0 && (!isdigit(*re_uri.s) && cr_match_mode == 10)) {
00228 ++re_uri.s;
00229 --re_uri.len;
00230 }
00231 ret = dtrie_longest_match(failure_node, re_uri.s, re_uri.len, NULL, cr_match_mode);
00232
00233 if (ret == NULL) {
00234 LM_INFO("URI or prefix tree nodes empty, empty rule list\n");
00235 return 1;
00236 }
00237 else return set_next_domain_on_rule(*ret, host, reply_code, flags, dstavp);
00238 }
00239
00240
00251 static struct route_rule * get_rule_by_hash(const struct route_flags * rf,
00252 const int prob) {
00253 struct route_rule * act_hash = NULL;
00254
00255 if (prob > rf->rule_num) {
00256 LM_WARN("too large desired hash, taking highest\n");
00257 act_hash = rf->rules[rf->rule_num - 1];
00258 }
00259 else act_hash = rf->rules[prob - 1];
00260
00261 if (!act_hash->status) {
00262 if (act_hash->backup && act_hash->backup->rr) {
00263 act_hash = act_hash->backup->rr;
00264 } else {
00265 act_hash = NULL;
00266 }
00267 }
00268 LM_INFO("desired hash was %i, return %i\n", prob, act_hash ? act_hash->hash_index : -1);
00269 return act_hash;
00270 }
00271
00272
00285 static int actually_rewrite(const struct route_rule *rs, str *dest,
00286 const struct sip_msg *msg, const str * user, gparam_t *descavp) {
00287 size_t len;
00288 char *p;
00289 int_str avp_val;
00290 int strip = 0;
00291
00292 str l_user;
00293
00294 if( !rs || !dest || !msg || !user) {
00295 LM_ERR("NULL parameter\n");
00296 return -1;
00297 }
00298
00299 l_user = *user;
00300
00301 strip = (rs->strip > user->len ? user->len : rs->strip);
00302 strip = (strip < 0 ? 0 : strip);
00303
00304 if ( strcmp(user->s, "<null>") == 0 || user->len == 0)
00305 {
00306 l_user.s = NULL;
00307 l_user.len = 0;
00308 len = rs->host.len;
00309 strip = 0;
00310 }
00311 else{
00312 len = rs->local_prefix.len + l_user.len + rs->local_suffix.len +
00313 AT_SIGN.len + rs->host.len - strip;
00314 }
00315
00316 if (msg->parsed_uri.type == SIPS_URI_T) {
00317 len += SIPS_URI.len;
00318 } else {
00319 len += SIP_URI.len;
00320 }
00321 if ( len > MAX_URI_SIZE ) {
00322 LM_ERR("Calculated uri size too large: %lu\n", (unsigned long)len);
00323 return -1;
00324 }
00325
00326 dest->s = g_rewrite_uri;
00327 dest->len = len;
00328 p = dest->s;
00329 if (msg->parsed_uri.type == SIPS_URI_T) {
00330 memcpy(p, SIPS_URI.s, SIPS_URI.len);
00331 p += SIPS_URI.len;
00332 } else {
00333 memcpy(p, SIP_URI.s, SIP_URI.len);
00334 p += SIP_URI.len;
00335 }
00336 if (l_user.len) {
00337 memcpy(p, rs->local_prefix.s, rs->local_prefix.len);
00338 p += rs->local_prefix.len;
00339 memcpy(p, l_user.s + strip, l_user.len - strip);
00340 p += l_user.len - strip;
00341 memcpy(p, rs->local_suffix.s, rs->local_suffix.len);
00342 p += rs->local_suffix.len;
00343 memcpy(p, AT_SIGN.s, AT_SIGN.len);
00344 p += AT_SIGN.len;
00345 }
00346
00347 if (rs->host.len == 0) {
00348 *p = '\0';
00349 return -1;
00350 }
00351 memcpy(p, rs->host.s, rs->host.len);
00352 p += rs->host.len;
00353 *p = '\0';
00354
00355 if (descavp) {
00356 avp_val.s = rs->comment;
00357 if (add_avp(AVP_VAL_STR | descavp->v.pve->spec.pvp.pvn.u.isname.type,
00358 descavp->v.pve->spec.pvp.pvn.u.isname.name, avp_val)<0) {
00359 LM_ERR("set AVP failed\n");
00360 return -1;
00361 }
00362 }
00363
00364 return 0;
00365 }
00366
00367
00382 static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest,
00383 struct sip_msg * msg, const str * user, const enum hash_source hash_source,
00384 const enum hash_algorithm alg, gparam_t *descavp) {
00385 struct route_flags * rf;
00386 struct route_rule * rr;
00387 int prob;
00388
00389 assert(rf_head != NULL);
00390
00391 LM_DBG("searching for matching routing rules");
00392 for (rf = rf_head; rf != NULL; rf = rf->next) {
00393
00394 if ((flags&rf->mask) == rf->flags) break;
00395 }
00396
00397 if (rf==NULL) {
00398 LM_INFO("did not find a match for flags %d\n", flags);
00399 return -1;
00400 }
00401
00402 if (rf->rule_list == NULL) {
00403 LM_INFO("empty rule list\n");
00404 return 1;
00405 }
00406
00407 switch (alg) {
00408 case alg_crc32:
00409 if(rf->dice_max == 0) {
00410 LM_ERR("invalid dice_max value\n");
00411 return -1;
00412 }
00413 if ((prob = hash_func(msg, hash_source, rf->dice_max)) < 0) {
00414 LM_ERR("could not hash message with CRC32");
00415 return -1;
00416 }
00417
00418
00419
00420
00421
00422
00423 for (rr = rf->rule_list;
00424 rr->next != NULL && rr->dice_to <= prob;
00425 rr = rr->next) {}
00426 if (!rr->status) {
00427 if (!rr->backup) {
00428 LM_ERR("all routes are off\n");
00429 return -1;
00430 } else {
00431 if (!rr->backup->rr) {
00432 LM_ERR("all routes are off\n");
00433 return -1;
00434 }
00435 rr = rr->backup->rr;
00436 }
00437 }
00438 break;
00439 case alg_crc32_nofallback:
00440 if ((prob = (hash_func(msg, hash_source, rf->max_targets))) < 0) {
00441 LM_ERR("could not hash message with CRC32");
00442 return -1;
00443 }
00444
00445
00446
00447
00448 if ((rr = get_rule_by_hash(rf, prob + 1)) == NULL) {
00449 LM_CRIT("no route found\n");
00450 return -1;
00451 }
00452 break;
00453 default:
00454 LM_ERR("invalid hash algorithm\n");
00455 return -1;
00456 }
00457 return actually_rewrite(rr, dest, msg, user, descavp);
00458 }
00459
00460
00478 static int rewrite_uri_recursor(struct dtrie_node_t * node,
00479 const str * pm, flag_t flags, str * dest, struct sip_msg * msg, const str * user,
00480 const enum hash_source hash_source, const enum hash_algorithm alg,
00481 gparam_t *descavp) {
00482 str re_pm = *pm;
00483 void **ret;
00484
00485
00486 while (re_pm.len > 0 && (!isdigit(*re_pm.s) && cr_match_mode == 10)) {
00487 ++re_pm.s;
00488 --re_pm.len;
00489 }
00490 ret = dtrie_longest_match(node, re_pm.s, re_pm.len, NULL, cr_match_mode);
00491
00492 if (ret == NULL) {
00493 LM_INFO("URI or prefix tree nodes empty, empty rule list\n");
00494 return 1;
00495 }
00496 else return rewrite_on_rule(*ret, flags, dest, msg, user, hash_source, alg, descavp);
00497 }
00498
00499
00515 int cr_do_route(struct sip_msg * _msg, gparam_t *_carrier,
00516 gparam_t *_domain, gparam_t *_prefix_matching,
00517 gparam_t *_rewrite_user, enum hash_source _hsrc,
00518 enum hash_algorithm _halg, gparam_t *_dstavp) {
00519
00520 int carrier_id, domain_id, ret = -1;
00521 str rewrite_user, prefix_matching, dest;
00522 flag_t flags;
00523 struct route_data_t * rd;
00524 struct carrier_data_t * carrier_data;
00525 struct domain_data_t * domain_data;
00526 struct action act;
00527 struct run_act_ctx ra_ctx;
00528
00529 if (fixup_get_svalue(_msg, _rewrite_user, &rewrite_user)<0) {
00530 LM_ERR("cannot print the rewrite_user\n");
00531 return -1;
00532 }
00533
00534 if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) {
00535 LM_ERR("cannot print the prefix_matching\n");
00536 return -1;
00537 }
00538
00539 flags = _msg->flags;
00540
00541 do {
00542 rd = get_data();
00543 } while (rd == NULL);
00544
00545 carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num);
00546 if (carrier_id < 0) {
00547 LM_ERR("invalid carrier id %d\n", carrier_id);
00548 release_data(rd);
00549 return -1;
00550 }
00551
00552 domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num);
00553 if (domain_id < 0) {
00554 LM_ERR("invalid domain id %d\n", domain_id);
00555 release_data(rd);
00556 return -1;
00557 }
00558
00559 carrier_data=NULL;
00560 if (carrier_id < 0) {
00561 if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
00562 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00563 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00564 }
00565 } else if (carrier_id == 0) {
00566 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00567 } else {
00568 carrier_data = get_carrier_data(rd, carrier_id);
00569 if (carrier_data == NULL) {
00570 if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
00571 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00572 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00573 }
00574 }
00575 }
00576 if (carrier_data == NULL) {
00577 LM_ERR("cannot get carrier data\n");
00578 goto unlock_and_out;
00579 }
00580
00581 domain_data = get_domain_data(carrier_data, domain_id);
00582 if (domain_data == NULL) {
00583 LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n",
00584 prefix_matching.len, prefix_matching.s, carrier_id, domain_id);
00585 goto unlock_and_out;
00586 }
00587
00588 if (rewrite_uri_recursor(domain_data->tree, &prefix_matching, flags, &dest, _msg, &rewrite_user, _hsrc, _halg, _dstavp) != 0) {
00589
00590 LM_INFO("rewrite_uri_recursor doesn't complete, uri %.*s, carrier %d, domain %d\n", prefix_matching.len,
00591 prefix_matching.s, carrier_id, domain_id);
00592 goto unlock_and_out;
00593 }
00594
00595 LM_INFO("uri %.*s was rewritten to %.*s, carrier %d, domain %d\n", rewrite_user.len, rewrite_user.s, dest.len, dest.s, carrier_id, domain_id);
00596
00597 memset(&act, 0, sizeof(act));
00598 act.type = SET_URI_T;
00599 act.val[0].type = STRING_ST;
00600 act.val[0].u.string = dest.s;
00601 init_run_actions_ctx(&ra_ctx);
00602 ret = do_action(&ra_ctx, &act, _msg);
00603 if (ret < 0) {
00604 LM_ERR("Error in do_action()\n");
00605 }
00606
00607 unlock_and_out:
00608 release_data(rd);
00609 return ret;
00610 }
00611
00612
00623 int cr_load_user_carrier(struct sip_msg * _msg, gparam_t *_user, gparam_t *_domain, gparam_t *_dstavp) {
00624 str user, domain;
00625 int_str avp_val;
00626
00627 if (fixup_get_svalue(_msg, _user, &user)<0) {
00628 LM_ERR("cannot print the user\n");
00629 return -1;
00630 }
00631
00632 if (fixup_get_svalue(_msg, _domain, &domain)<0) {
00633 LM_ERR("cannot print the domain\n");
00634 return -1;
00635 }
00636
00637 if ((avp_val.n = load_user_carrier(&user, &domain)) < 0) {
00638 LM_ERR("error in load user carrier");
00639 return -1;
00640 } else {
00641
00642 if (add_avp(_dstavp->v.pve->spec.pvp.pvn.u.isname.type,
00643 _dstavp->v.pve->spec.pvp.pvn.u.isname.name, avp_val)<0) {
00644 LM_ERR("add AVP failed\n");
00645 return -1;
00646 }
00647 }
00648 return 1;
00649 }
00650
00651
00666 int cr_route(struct sip_msg * _msg, gparam_t *_carrier,
00667 gparam_t *_domain, gparam_t *_prefix_matching,
00668 gparam_t *_rewrite_user, enum hash_source _hsrc,
00669 gparam_t *_descavp)
00670 {
00671 return cr_do_route(_msg, _carrier, _domain, _prefix_matching,
00672 _rewrite_user, _hsrc, alg_crc32, _descavp);
00673 }
00674
00675 int cr_route5(struct sip_msg * _msg, gparam_t *_carrier,
00676 gparam_t *_domain, gparam_t *_prefix_matching,
00677 gparam_t *_rewrite_user, enum hash_source _hsrc)
00678 {
00679 return cr_do_route(_msg, _carrier, _domain, _prefix_matching,
00680 _rewrite_user, _hsrc, alg_crc32, NULL);
00681 }
00682
00683
00700 int cr_nofallback_route(struct sip_msg * _msg, gparam_t *_carrier,
00701 gparam_t *_domain, gparam_t *_prefix_matching,
00702 gparam_t *_rewrite_user, enum hash_source _hsrc,
00703 gparam_t *_dstavp)
00704 {
00705 return cr_do_route(_msg, _carrier, _domain, _prefix_matching,
00706 _rewrite_user, _hsrc, alg_crc32_nofallback, _dstavp);
00707 }
00708
00709 int cr_nofallback_route5(struct sip_msg * _msg, gparam_t *_carrier,
00710 gparam_t *_domain, gparam_t *_prefix_matching,
00711 gparam_t *_rewrite_user, enum hash_source _hsrc)
00712 {
00713 return cr_do_route(_msg, _carrier, _domain, _prefix_matching,
00714 _rewrite_user, _hsrc, alg_crc32_nofallback, NULL);
00715 }
00716
00717
00731 int cr_load_next_domain(struct sip_msg * _msg, gparam_t *_carrier,
00732 gparam_t *_domain, gparam_t *_prefix_matching,
00733 gparam_t *_host, gparam_t *_reply_code, gparam_t *_dstavp) {
00734
00735 int carrier_id, domain_id, ret = -1;
00736 str prefix_matching, host, reply_code;
00737 flag_t flags;
00738 struct route_data_t * rd;
00739 struct carrier_data_t * carrier_data;
00740 struct domain_data_t * domain_data;
00741
00742 if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) {
00743 LM_ERR("cannot print the prefix_matching\n");
00744 return -1;
00745 }
00746 if (fixup_get_svalue(_msg, _host, &host)<0) {
00747 LM_ERR("cannot print the host\n");
00748 return -1;
00749 }
00750 if (fixup_get_svalue(_msg, _reply_code, &reply_code)<0) {
00751 LM_ERR("cannot print the reply_code\n");
00752 return -1;
00753 }
00754
00755 flags = _msg->flags;
00756
00757 do {
00758 rd = get_data();
00759 } while (rd == NULL);
00760
00761 carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num);
00762 if (carrier_id < 0) {
00763 LM_ERR("invalid carrier id %d\n", carrier_id);
00764 release_data(rd);
00765 return -1;
00766 }
00767
00768 domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num);
00769 if (domain_id < 0) {
00770 LM_ERR("invalid domain id %d\n", domain_id);
00771 release_data(rd);
00772 return -1;
00773 }
00774
00775 carrier_data=NULL;
00776 if (carrier_id < 0) {
00777 if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
00778 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00779 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00780 }
00781 } else if (carrier_id == 0) {
00782 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00783 } else {
00784 carrier_data = get_carrier_data(rd, carrier_id);
00785 if (carrier_data == NULL) {
00786 if (cfg_get(carrierroute, carrierroute_cfg, fallback_default)) {
00787 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00788 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00789 }
00790 }
00791 }
00792 if (carrier_data == NULL) {
00793 LM_ERR("cannot get carrier data\n");
00794 goto unlock_and_out;
00795 }
00796
00797 domain_data = get_domain_data(carrier_data, domain_id);
00798 if (domain_data == NULL) {
00799 LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n",
00800 prefix_matching.len, prefix_matching.s, carrier_id, domain_id);
00801 goto unlock_and_out;
00802 }
00803
00804 if (set_next_domain_recursor(domain_data->failure_tree, &prefix_matching, &host, &reply_code, flags, _dstavp) != 0) {
00805 LM_INFO("set_next_domain_recursor doesn't complete, prefix '%.*s', carrier %d, domain %d\n", prefix_matching.len,
00806 prefix_matching.s, carrier_id, domain_id);
00807 goto unlock_and_out;
00808 }
00809
00810 ret = 1;
00811
00812 unlock_and_out:
00813 release_data(rd);
00814 return ret;
00815 }