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 #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
00051
00052 enum hash_algorithm {
00053 alg_crc32 = 1,
00054 alg_prime,
00055 alg_error
00056 };
00057
00058
00059 static const str SIP_URI = { .s="sip:", .len=4 };
00060 static const str SIPS_URI = { .s="sips:", .len=5 };
00061 static const str AT_SIGN = { .s="@", .len=1 };
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 static inline int cr_gp2id(struct sip_msg *_msg, gparam_t *gp, struct name_map_t *map, int size) {
00076 int id;
00077 struct usr_avp *avp;
00078 int_str avp_val;
00079 str tmp;
00080
00081 switch (gp->type) {
00082 case GPARAM_TYPE_INT:
00083 return gp->v.ival;
00084 break;
00085 case GPARAM_TYPE_PVE:
00086
00087 if (gp->v.pve->spec.type==PVT_AVP) {
00088 avp = search_first_avp(gp->v.pve->spec.pvp.pvn.u.isname.type,
00089 gp->v.pve->spec.pvp.pvn.u.isname.name, &avp_val, 0);
00090 if (!avp) {
00091 LM_ERR("cannot find AVP '%.*s'\n", gp->v.pve->spec.pvp.pvn.u.isname.name.s.len,
00092 gp->v.pve->spec.pvp.pvn.u.isname.name.s.s);
00093 return -1;
00094 }
00095 if ((avp->flags&AVP_VAL_STR)==0) {
00096 return avp_val.n;
00097 } else {
00098 id = map_name2id(map, size, &avp_val.s);
00099 if (id < 0) {
00100 LM_ERR("could not find id '%.*s' from AVP\n",
00101 gp->v.pve->spec.pvp.pvn.u.isname.name.s.len,
00102 gp->v.pve->spec.pvp.pvn.u.isname.name.s.s);
00103 return -1;
00104 }
00105 return id;
00106 }
00107 } else {
00108
00109 if (fixup_get_svalue(_msg, gp, &tmp)<0) {
00110 LM_ERR("cannot print the name from PV\n");
00111 return -1;
00112 }
00113 id = map_name2id(map, size, &tmp);
00114 if (id < 0) {
00115 LM_ERR("could not find id '%.*s' from PV\n", tmp.len, tmp.s);
00116 return -1;
00117 }
00118 return id;
00119 }
00120 default:
00121 LM_ERR("invalid parameter type\n");
00122 return -1;
00123 }
00124 }
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135 static inline int reply_code_matcher(const str *rcw, const str *rc) {
00136 int i;
00137
00138 if (rcw->len==0) return 0;
00139
00140 if (rcw->len != rc->len) return -1;
00141
00142 for (i=0; i<rc->len; i++) {
00143 if (rcw->s[i]!='.' && rcw->s[i]!=rc->s[i]) return -1;
00144 }
00145
00146 return 0;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 static int set_next_domain_on_rule(struct failure_route_rule *frr_head,
00162 const str *host, const str *reply_code, const flag_t flags,
00163 const gparam_t *dstavp) {
00164 struct failure_route_rule * rr;
00165 int_str avp_val;
00166
00167 assert(frr_head != NULL);
00168
00169 LM_DBG("searching for matching routing rules");
00170 for (rr = frr_head; rr != NULL; rr = rr->next) {
00171
00172
00173
00174
00175
00176
00177
00178 if (((rr->mask & flags) == rr->flags) &&
00179 ((rr->host.len == 0) || (str_strcmp(host, &rr->host)==0)) &&
00180 (reply_code_matcher(&(rr->reply_code), reply_code)==0)) {
00181 avp_val.n = rr->next_domain;
00182 if (add_avp(dstavp->v.pve->spec.pvp.pvn.u.isname.type,
00183 dstavp->v.pve->spec.pvp.pvn.u.isname.name, avp_val)<0) {
00184 LM_ERR("set AVP failed\n");
00185 return -1;
00186 }
00187
00188 LM_INFO("next_domain is %d\n", rr->next_domain);
00189 return 0;
00190 }
00191 }
00192
00193 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);
00194 return -1;
00195 }
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 static int set_next_domain_recursor(struct dtrie_node_t *failure_node,
00213 const str *uri, const str *host, const str *reply_code, const flag_t flags,
00214 const gparam_t *dstavp) {
00215 str re_uri = *uri;
00216 void **ret;
00217
00218
00219 while (re_uri.len > 0 && (!isdigit(*re_uri.s) && cr_match_mode == 10)) {
00220 ++re_uri.s;
00221 --re_uri.len;
00222 }
00223 ret = dtrie_longest_match(failure_node, re_uri.s, re_uri.len, NULL, cr_match_mode);
00224
00225 if (ret == NULL) {
00226 LM_INFO("URI or prefix tree nodes empty, empty rule list\n");
00227 return 1;
00228 }
00229 else return set_next_domain_on_rule(*ret, host, reply_code, flags, dstavp);
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 static struct route_rule * get_rule_by_hash(const struct route_flags * rf,
00244 const int prob) {
00245 struct route_rule * act_hash = NULL;
00246
00247 if (prob > rf->rule_num) {
00248 LM_WARN("too large desired hash, taking highest\n");
00249 act_hash = rf->rules[rf->rule_num - 1];
00250 }
00251 act_hash = rf->rules[prob - 1];
00252
00253 if (!act_hash->status) {
00254 if (act_hash->backup && act_hash->backup->rr) {
00255 act_hash = act_hash->backup->rr;
00256 } else {
00257 act_hash = NULL;
00258 }
00259 }
00260 LM_INFO("desired hash was %i, return %i\n", prob, act_hash ? act_hash->hash_index : -1);
00261 return act_hash;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278 static int actually_rewrite(const struct route_rule *rs, str *dest,
00279 const struct sip_msg *msg, const str * user, gparam_t *descavp) {
00280 size_t len;
00281 char *p;
00282 int_str avp_val;
00283 int strip = 0;
00284
00285 strip = (rs->strip > user->len ? user->len : rs->strip);
00286 strip = (strip < 0 ? 0 : strip);
00287
00288 len = rs->local_prefix.len + user->len + rs->local_suffix.len +
00289 AT_SIGN.len + rs->host.len - strip;
00290 if (msg->parsed_uri.type == SIPS_URI_T) {
00291 len += SIPS_URI.len;
00292 } else {
00293 len += SIP_URI.len;
00294 }
00295 dest->len = 0;
00296 dest->s = (char *)pkg_malloc(len + 1);
00297 if (dest->s == NULL) {
00298 PKG_MEM_ERROR;
00299 return -1;
00300 }
00301 dest->len = len;
00302 p = dest->s;
00303 if (msg->parsed_uri.type == SIPS_URI_T) {
00304 memcpy(p, SIPS_URI.s, SIPS_URI.len);
00305 p += SIPS_URI.len;
00306 } else {
00307 memcpy(p, SIP_URI.s, SIP_URI.len);
00308 p += SIP_URI.len;
00309 }
00310 if (user->len) {
00311 memcpy(p, rs->local_prefix.s, rs->local_prefix.len);
00312 p += rs->local_prefix.len;
00313 memcpy(p, user->s + strip, user->len - strip);
00314 p += user->len - strip;
00315 memcpy(p, rs->local_suffix.s, rs->local_suffix.len);
00316 p += rs->local_suffix.len;
00317 memcpy(p, AT_SIGN.s, AT_SIGN.len);
00318 p += AT_SIGN.len;
00319 }
00320
00321 if (rs->host.len == 0) {
00322 *p = '\0';
00323 pkg_free(dest->s);
00324 return -1;
00325 }
00326 memcpy(p, rs->host.s, rs->host.len);
00327 p += rs->host.len;
00328 *p = '\0';
00329
00330 if (descavp) {
00331 avp_val.s = rs->comment;
00332 if (add_avp(AVP_VAL_STR | descavp->v.pve->spec.pvp.pvn.u.isname.type,
00333 descavp->v.pve->spec.pvp.pvn.u.isname.name, avp_val)<0) {
00334 LM_ERR("set AVP failed\n");
00335 pkg_free(dest->s);
00336 return -1;
00337 }
00338 }
00339
00340 return 0;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest,
00359 struct sip_msg * msg, const str * user, const enum hash_source hash_source,
00360 const enum hash_algorithm alg, gparam_t *dstavp) {
00361 struct route_flags * rf;
00362 struct route_rule * rr;
00363 int prob;
00364
00365 assert(rf_head != NULL);
00366
00367 LM_DBG("searching for matching routing rules");
00368 for (rf = rf_head; rf != NULL; rf = rf->next) {
00369
00370 if ((flags&rf->mask) == rf->flags) break;
00371 }
00372
00373 if (rf==NULL) {
00374 LM_INFO("did not find a match for flags %d\n", flags);
00375 return -1;
00376 }
00377
00378 if (rf->rule_list == NULL) {
00379 LM_INFO("empty rule list\n");
00380 return 1;
00381 }
00382
00383 switch (alg) {
00384 case alg_prime:
00385 if ((prob = prime_hash_func(msg, hash_source, rf->max_targets)) < 0) {
00386 LM_ERR("could not hash message with prime algorithm");
00387 return -1;
00388 }
00389 if ((rr = get_rule_by_hash(rf, prob)) == NULL) {
00390 LM_CRIT("no route found\n");
00391 return -1;
00392 }
00393 break;
00394 case alg_crc32:
00395 if(rf->dice_max == 0) {
00396 LM_ERR("invalid dice_max value\n");
00397 return -1;
00398 }
00399 if ((prob = hash_func(msg, hash_source, rf->dice_max)) < 0) {
00400 LM_ERR("could not hash message with CRC32");
00401 return -1;
00402 }
00403
00404
00405
00406
00407
00408
00409 for (rr = rf->rule_list;
00410 rr->next != NULL && rr->dice_to <= prob;
00411 rr = rr->next) {}
00412 if (!rr->status) {
00413 if (!rr->backup) {
00414 LM_ERR("all routes are off\n");
00415 return -1;
00416 } else {
00417 if (!rr->backup->rr) {
00418 LM_ERR("all routes are off\n");
00419 return -1;
00420 }
00421 rr = rr->backup->rr;
00422 }
00423 }
00424 break;
00425 default:
00426 LM_ERR("invalid hash algorithm\n");
00427 return -1;
00428 }
00429 return actually_rewrite(rr, dest, msg, user, dstavp);
00430 }
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450 static int rewrite_uri_recursor(struct dtrie_node_t * node,
00451 const str * pm, flag_t flags, str * dest, struct sip_msg * msg, const str * user,
00452 const enum hash_source hash_source, const enum hash_algorithm alg,
00453 gparam_t *dstavp) {
00454 str re_pm = *pm;
00455 void **ret;
00456
00457
00458 while (re_pm.len > 0 && (!isdigit(*re_pm.s) && cr_match_mode == 10)) {
00459 ++re_pm.s;
00460 --re_pm.len;
00461 }
00462 ret = dtrie_longest_match(node, re_pm.s, re_pm.len, NULL, cr_match_mode);
00463
00464 if (ret == NULL) {
00465 LM_INFO("URI or prefix tree nodes empty, empty rule list\n");
00466 return 1;
00467 }
00468 else return rewrite_on_rule(*ret, flags, dest, msg, user, hash_source, alg, dstavp);
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487 int cr_do_route(struct sip_msg * _msg, gparam_t *_carrier,
00488 gparam_t *_domain, gparam_t *_prefix_matching,
00489 gparam_t *_rewrite_user, enum hash_source _hsrc,
00490 enum hash_algorithm _halg, gparam_t *_dstavp) {
00491
00492 int carrier_id, domain_id, ret = -1;
00493 str rewrite_user, prefix_matching, dest;
00494 flag_t flags;
00495 struct route_data_t * rd;
00496 struct carrier_data_t * carrier_data;
00497 struct domain_data_t * domain_data;
00498 struct action act;
00499
00500 if (fixup_get_svalue(_msg, _rewrite_user, &rewrite_user)<0) {
00501 LM_ERR("cannot print the rewrite_user\n");
00502 return -1;
00503 }
00504
00505 if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) {
00506 LM_ERR("cannot print the prefix_matching\n");
00507 return -1;
00508 }
00509
00510 flags = _msg->flags;
00511
00512 do {
00513 rd = get_data();
00514 } while (rd == NULL);
00515
00516 carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num);
00517 if (carrier_id < 0) {
00518 LM_ERR("invalid carrier id %d\n", carrier_id);
00519 release_data(rd);
00520 return -1;
00521 }
00522
00523 domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num);
00524 if (domain_id < 0) {
00525 LM_ERR("invalid domain id %d\n", domain_id);
00526 release_data(rd);
00527 return -1;
00528 }
00529
00530 carrier_data=NULL;
00531 if (carrier_id < 0) {
00532 if (fallback_default) {
00533 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00534 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00535 }
00536 } else if (carrier_id == 0) {
00537 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00538 } else {
00539 carrier_data = get_carrier_data(rd, carrier_id);
00540 if (carrier_data == NULL) {
00541 if (fallback_default) {
00542 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00543 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00544 }
00545 }
00546 }
00547 if (carrier_data == NULL) {
00548 LM_ERR("cannot get carrier data\n");
00549 goto unlock_and_out;
00550 }
00551
00552 domain_data = get_domain_data(carrier_data, domain_id);
00553 if (domain_data == NULL) {
00554 LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n",
00555 prefix_matching.len, prefix_matching.s, carrier_id, domain_id);
00556 goto unlock_and_out;
00557 }
00558
00559 if (rewrite_uri_recursor(domain_data->tree, &prefix_matching, flags, &dest, _msg, &rewrite_user, _hsrc, _halg, _dstavp) != 0) {
00560
00561 LM_INFO("rewrite_uri_recursor doesn't complete, uri %.*s, carrier %d, domain %d\n", prefix_matching.len,
00562 prefix_matching.s, carrier_id, domain_id);
00563 goto unlock_and_out;
00564 }
00565
00566 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);
00567
00568 act.type = SET_URI_T;
00569 act.elem[0].type= STRING_ST;
00570 act.elem[0].u.string = dest.s;
00571 act.next = NULL;
00572
00573 ret = do_action(&act, _msg);
00574 if (ret < 0) {
00575 LM_ERR("Error in do_action()\n");
00576 }
00577 pkg_free(dest.s);
00578
00579 unlock_and_out:
00580 release_data(rd);
00581 return ret;
00582 }
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 int cr_load_user_carrier(struct sip_msg * _msg, gparam_t *_user, gparam_t *_domain, gparam_t *_dstavp) {
00596 str user, domain;
00597 int_str avp_val;
00598
00599 if (fixup_get_svalue(_msg, _user, &user)<0) {
00600 LM_ERR("cannot print the user\n");
00601 return -1;
00602 }
00603
00604 if (fixup_get_svalue(_msg, _domain, &domain)<0) {
00605 LM_ERR("cannot print the domain\n");
00606 return -1;
00607 }
00608
00609
00610 if ((avp_val.n = load_user_carrier(&user, &domain)) < 0) {
00611 LM_ERR("error in load user carrier");
00612 return -1;
00613 } else {
00614
00615 if (add_avp(_dstavp->v.pve->spec.pvp.pvn.u.isname.type,
00616 _dstavp->v.pve->spec.pvp.pvn.u.isname.name, avp_val)<0) {
00617 LM_ERR("add AVP failed\n");
00618 return -1;
00619 }
00620 }
00621 return 1;
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639 int cr_route(struct sip_msg * _msg, gparam_t *_carrier,
00640 gparam_t *_domain, gparam_t *_prefix_matching,
00641 gparam_t *_rewrite_user, enum hash_source _hsrc,
00642 gparam_t *_dstavp)
00643 {
00644 return cr_do_route(_msg, _carrier, _domain, _prefix_matching,
00645 _rewrite_user, _hsrc, alg_crc32, _dstavp);
00646 }
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663 int cr_prime_route(struct sip_msg * _msg, gparam_t *_carrier,
00664 gparam_t *_domain, gparam_t *_prefix_matching,
00665 gparam_t *_rewrite_user, enum hash_source _hsrc,
00666 gparam_t *_dstavp)
00667 {
00668 return cr_do_route(_msg, _carrier, _domain, _prefix_matching,
00669 _rewrite_user, _hsrc, alg_prime, _dstavp);
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685
00686 int cr_load_next_domain(struct sip_msg * _msg, gparam_t *_carrier,
00687 gparam_t *_domain, gparam_t *_prefix_matching,
00688 gparam_t *_host, gparam_t *_reply_code, gparam_t *_dstavp) {
00689
00690 int carrier_id, domain_id, ret = -1;
00691 str prefix_matching, host, reply_code;
00692 flag_t flags;
00693 struct route_data_t * rd;
00694 struct carrier_data_t * carrier_data;
00695 struct domain_data_t * domain_data;
00696
00697 if (fixup_get_svalue(_msg, _prefix_matching, &prefix_matching)<0) {
00698 LM_ERR("cannot print the prefix_matching\n");
00699 return -1;
00700 }
00701 if (fixup_get_svalue(_msg, _host, &host)<0) {
00702 LM_ERR("cannot print the host\n");
00703 return -1;
00704 }
00705 if (fixup_get_svalue(_msg, _reply_code, &reply_code)<0) {
00706 LM_ERR("cannot print the reply_code\n");
00707 return -1;
00708 }
00709
00710 flags = _msg->flags;
00711
00712 do {
00713 rd = get_data();
00714 } while (rd == NULL);
00715
00716 carrier_id = cr_gp2id(_msg, _carrier, rd->carrier_map, rd->carrier_num);
00717 if (carrier_id < 0) {
00718 LM_ERR("invalid carrier id %d\n", carrier_id);
00719 release_data(rd);
00720 return -1;
00721 }
00722
00723 domain_id = cr_gp2id(_msg, _domain, rd->domain_map, rd->domain_num);
00724 if (domain_id < 0) {
00725 LM_ERR("invalid domain id %d\n", domain_id);
00726 release_data(rd);
00727 return -1;
00728 }
00729
00730 carrier_data=NULL;
00731 if (carrier_id < 0) {
00732 if (fallback_default) {
00733 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00734 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00735 }
00736 } else if (carrier_id == 0) {
00737 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00738 } else {
00739 carrier_data = get_carrier_data(rd, carrier_id);
00740 if (carrier_data == NULL) {
00741 if (fallback_default) {
00742 LM_NOTICE("invalid tree id %i specified, using default tree\n", carrier_id);
00743 carrier_data = get_carrier_data(rd, rd->default_carrier_id);
00744 }
00745 }
00746 }
00747 if (carrier_data == NULL) {
00748 LM_ERR("cannot get carrier data\n");
00749 goto unlock_and_out;
00750 }
00751
00752 domain_data = get_domain_data(carrier_data, domain_id);
00753 if (domain_data == NULL) {
00754 LM_ERR("desired routing domain doesn't exist, prefix %.*s, carrier %d, domain %d\n",
00755 prefix_matching.len, prefix_matching.s, carrier_id, domain_id);
00756 goto unlock_and_out;
00757 }
00758
00759 if (set_next_domain_recursor(domain_data->failure_tree, &prefix_matching, &host, &reply_code, flags, _dstavp) != 0) {
00760 LM_INFO("set_next_domain_recursor doesn't complete, prefix '%.*s', carrier %d, domain %d\n", prefix_matching.len,
00761 prefix_matching.s, carrier_id, domain_id);
00762 goto unlock_and_out;
00763 }
00764
00765 ret = 1;
00766
00767 unlock_and_out:
00768 release_data(rd);
00769 return ret;
00770 }