00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00031 #include <string.h>
00032 #include "../../ut.h"
00033 #include "../../str.h"
00034 #include "../../dprint.h"
00035 #include "../../forward.h"
00036 #include "../../data_lump.h"
00037 #include "../../socket_info.h"
00038 #include "../../parser/parse_rr.h"
00039 #include "../../parser/parse_uri.h"
00040 #include "../../parser/parse_from.h"
00041 #include "../../mem/mem.h"
00042 #include "../../dset.h"
00043 #include "loose.h"
00044 #include "rr_cb.h"
00045 #include "rr_mod.h"
00046
00047
00048 #define RR_ERROR -1
00049 #define RR_DRIVEN 1
00050 #define NOT_RR_DRIVEN -1
00052 #define ROUTE_SUFFIX ">\r\n"
00053 #define ROUTE_SUFFIX_LEN (sizeof(ROUTE_SUFFIX)-1)
00054
00056 static unsigned int routed_msg_id;
00057 static str routed_params = {0,0};
00058
00059
00065 static int is_preloaded(struct sip_msg* msg)
00066 {
00067 str tag;
00068
00069 if (!msg->to && parse_headers(msg, HDR_TO_F, 0) == -1) {
00070 LM_ERR("failed to parse To header field\n");
00071 return -1;
00072 }
00073
00074 if (!msg->to) {
00075 LM_ERR("To header field not found\n");
00076 return -1;
00077 }
00078
00079 tag = get_to(msg)->tag_value;
00080 if (tag.s == 0 || tag.len == 0) {
00081 LM_DBG("is_preloaded: Yes\n");
00082 return 1;
00083 }
00084
00085 LM_DBG("is_preloaded: No\n");
00086 return 0;
00087 }
00088
00089
00095 static inline int find_first_route(struct sip_msg* _m)
00096 {
00097 if (parse_headers(_m, HDR_ROUTE_F, 0) == -1) {
00098 LM_ERR("failed to parse headers\n");
00099 return -1;
00100 } else {
00101 if (_m->route) {
00102 if (parse_rr(_m->route) < 0) {
00103 LM_ERR("failed to parse Route HF\n");
00104 return -2;
00105 }
00106 return 0;
00107 } else {
00108 LM_DBG("No Route headers found\n");
00109 return 1;
00110 }
00111 }
00112 }
00113
00114
00121 static inline int is_myself(sip_uri_t *_puri)
00122 {
00123 int ret;
00124
00125 ret = check_self(&_puri->host,
00126 _puri->port_no?_puri->port_no:SIP_PORT, 0);
00127 if (ret < 0) return 0;
00128
00129 #ifdef ENABLE_USER_CHECK
00130 if(ret==1 && i_user.len && i_user.len==_puri->user.len
00131 && strncmp(i_user.s, _puri->user.s, _puri->user.len)==0)
00132 {
00133 LM_DBG("ignore user matched - URI is not to the server itself\n");
00134 return 0;
00135 }
00136 #endif
00137
00138 if(ret==1) {
00139
00140 if(_puri->gr.s!=NULL)
00141 return 0;
00142 }
00143
00144 return ret;
00145 }
00146
00147
00155 static inline int find_next_route(struct sip_msg* _m, struct hdr_field** _hdr)
00156 {
00157 struct hdr_field* ptr;
00158
00159 ptr = (*_hdr)->next;
00160
00161
00162 while(ptr) {
00163 if (ptr->type == HDR_ROUTE_T) goto found;
00164 ptr = ptr->next;
00165 }
00166
00167
00168
00169
00170 if (parse_headers(_m, HDR_ROUTE_F, 1) == -1) {
00171 LM_ERR("failed to parse headers\n");
00172 return -1;
00173 }
00174
00175 if ((_m->last_header->type!=HDR_ROUTE_T) || (_m->last_header==*_hdr)) {
00176 LM_DBG("No next Route HF found\n");
00177 return 1;
00178 }
00179
00180 ptr = _m->last_header;
00181
00182 found:
00183 if (parse_rr(ptr) < 0) {
00184 LM_ERR("failed to parse Route body\n");
00185 return -2;
00186 }
00187
00188 *_hdr = ptr;
00189 return 0;
00190 }
00191
00192
00198 static inline int is_strict(str* _params)
00199 {
00200 str s;
00201 int i, state = 0;
00202
00203 if (_params->len == 0) return 1;
00204
00205 s.s = _params->s;
00206 s.len = _params->len;
00207
00208 for(i = 0; i < s.len; i++) {
00209 switch(state) {
00210 case 0:
00211 switch(s.s[i]) {
00212 case ' ':
00213 case '\r':
00214 case '\n':
00215 case '\t': break;
00216 case 'l':
00217 case 'L': state = 1; break;
00218 default: state = 4; break;
00219 }
00220 break;
00221
00222 case 1:
00223 switch(s.s[i]) {
00224 case 'r':
00225 case 'R': state = 2; break;
00226 default: state = 4; break;
00227 }
00228 break;
00229
00230 case 2:
00231 switch(s.s[i]) {
00232 case ';': return 0;
00233 case '=': return 0;
00234 case ' ':
00235 case '\r':
00236 case '\n':
00237 case '\t': state = 3; break;
00238 default: state = 4; break;
00239 }
00240 break;
00241
00242 case 3:
00243 switch(s.s[i]) {
00244 case ';': return 0;
00245 case '=': return 0;
00246 case ' ':
00247 case '\r':
00248 case '\n':
00249 case '\t': break;
00250 default: state = 4; break;
00251 }
00252 break;
00253
00254 case 4:
00255 switch(s.s[i]) {
00256 case '\"': state = 5; break;
00257 case ';': state = 0; break;
00258 default: break;
00259 }
00260 break;
00261
00262 case 5:
00263 switch(s.s[i]) {
00264 case '\\': state = 6; break;
00265 case '\"': state = 4; break;
00266 default: break;
00267 }
00268 break;
00269
00270 case 6: state = 5; break;
00271 }
00272 }
00273
00274 if ((state == 2) || (state == 3)) return 0;
00275 else return 1;
00276 }
00277
00278
00288 static inline int save_ruri(struct sip_msg* _m)
00289 {
00290 struct lump* anchor;
00291 char *s;
00292 int len;
00293
00294
00295
00296
00297 if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
00298 LM_ERR("failed to parse message\n");
00299 return -1;
00300 }
00301
00302
00303 anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
00304 if (anchor == 0) {
00305 LM_ERR("failed to get anchor\n");
00306 return -2;
00307 }
00308
00309
00310 len = ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len + ROUTE_SUFFIX_LEN;
00311 s = (char*)pkg_malloc(len);
00312 if (!s) {
00313 LM_ERR("No memory pkg left\n");
00314 return -3;
00315 }
00316
00317
00318 memcpy(s, ROUTE_PREFIX, ROUTE_PREFIX_LEN);
00319 memcpy(s + ROUTE_PREFIX_LEN, _m->first_line.u.request.uri.s, _m->first_line.u.request.uri.len);
00320 memcpy(s + ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len, ROUTE_SUFFIX, ROUTE_SUFFIX_LEN);
00321
00322 LM_DBG("New header: '%.*s'\n", len, ZSW(s));
00323
00324
00325 if (insert_new_lump_before(anchor, s, len, 0) == 0) {
00326 pkg_free(s);
00327 LM_ERR("failed to insert lump\n");
00328 return -4;
00329 }
00330
00331 return 0;
00332 }
00333
00334
00341 static inline int get_maddr_uri(str *uri, struct sip_uri *puri)
00342 {
00343
00344 static char builturi[127+1];
00345 struct sip_uri turi;
00346
00347 if(uri==NULL || uri->s==NULL)
00348 return RR_ERROR;
00349 if(puri==NULL)
00350 {
00351 if (parse_uri(uri->s, uri->len, &turi) < 0)
00352 {
00353 LM_ERR("failed to parse the URI\n");
00354 return RR_ERROR;
00355 }
00356 puri = &turi;
00357 }
00358
00359 if(puri->maddr.s==NULL)
00360 return 0;
00361
00362
00363 if( (puri->maddr_val.len) > (127 - 10) )
00364 {
00365 LM_ERR( "Too long maddr parameter\n");
00366 return RR_ERROR;
00367 }
00368 memcpy( builturi, "sip:", 4 );
00369 memcpy( builturi+4, puri->maddr_val.s, puri->maddr_val.len );
00370
00371 if( puri->port.len > 0 )
00372 {
00373 builturi[4+puri->maddr_val.len] =':';
00374 memcpy(builturi+5+puri->maddr_val.len, puri->port.s,
00375 puri->port.len);
00376 }
00377
00378 uri->len = 4+puri->maddr_val.len
00379 + ((puri->port.len>0)?(1+puri->port.len):0);
00380 builturi[uri->len]='\0';
00381 uri->s = builturi;
00382
00383 LM_DBG("uri is %s\n", builturi );
00384 return 0;
00385 }
00386
00387
00395 static inline int handle_sr(struct sip_msg* _m, struct hdr_field* _hdr, rr_t* _r)
00396 {
00397 str uri;
00398 char* rem_off;
00399 int rem_len;
00400
00401
00402 if (save_ruri(_m) < 0) {
00403 LM_ERR("failed to save Request-URI\n");
00404 return -1;
00405 }
00406
00407
00408 uri = _r->nameaddr.uri;
00409 if(get_maddr_uri(&uri, 0)!=0) {
00410 LM_ERR("failed to check maddr\n");
00411 return RR_ERROR;
00412 }
00413 if (rewrite_uri(_m, &uri) < 0) {
00414 LM_ERR("failed to rewrite request URI\n");
00415 return -2;
00416 }
00417
00418 if (!_r->next) {
00419 rem_off = _hdr->name.s;
00420 rem_len = _hdr->len;
00421 } else {
00422 rem_off = _hdr->body.s;
00423 rem_len = _r->next->nameaddr.name.s - _hdr->body.s;
00424 }
00425
00426 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
00427 LM_ERR("failed to remove Route HF\n");
00428 return -9;
00429 }
00430
00431 return 0;
00432 }
00433
00434
00446 static inline int find_rem_target(struct sip_msg* _m, struct hdr_field** _h, rr_t** _l, rr_t** _p)
00447 {
00448 struct hdr_field* ptr, *last;
00449
00450 if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
00451 LM_ERR("failed to parse message header\n");
00452 return -1;
00453 }
00454
00455 ptr = _m->route;
00456 last = 0;
00457
00458 while(ptr) {
00459 if (ptr->type == HDR_ROUTE_T) last = ptr;
00460 ptr = ptr->next;
00461 }
00462
00463 if (last) {
00464 if (parse_rr(last) < 0) {
00465 LM_ERR("failed to parse last Route HF\n");
00466 return -2;
00467 }
00468
00469 *_p = 0;
00470 *_l = (rr_t*)last->parsed;
00471 *_h = last;
00472 while ((*_l)->next) {
00473 *_p = *_l;
00474 *_l = (*_l)->next;
00475 }
00476 return 0;
00477 } else {
00478 LM_ERR("search for last Route HF failed\n");
00479 return 1;
00480 }
00481 }
00482
00483
00489 static inline int after_strict(struct sip_msg* _m)
00490 {
00491 int res, rem_len;
00492 struct hdr_field* hdr;
00493 struct sip_uri puri;
00494 rr_t* rt, *prev;
00495 char* rem_off;
00496 str uri;
00497 struct socket_info *si;
00498
00499 hdr = _m->route;
00500 rt = (rr_t*)hdr->parsed;
00501 uri = rt->nameaddr.uri;
00502
00503
00504 routed_msg_id = 0;
00505 routed_params.s = NULL;
00506 routed_params.len = 0;
00507
00508 if (parse_uri(uri.s, uri.len, &puri) < 0) {
00509 LM_ERR("failed to parse the first route URI\n");
00510 return RR_ERROR;
00511 }
00512
00513 if ( enable_double_rr && is_2rr(&puri.params) && is_myself(&puri)) {
00514
00515
00516 si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
00517 if (si) {
00518 set_force_socket(_m, si);
00519 } else {
00520 if (enable_socket_mismatch_warning)
00521 LM_WARN("no socket found for match second RR\n");
00522 }
00523
00524 if (!rt->next) {
00525
00526
00527
00528 if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
00529 LM_ERR("failed to remove Route HF\n");
00530 return RR_ERROR;
00531 }
00532 res = find_next_route(_m, &hdr);
00533 if (res < 0) {
00534 LM_ERR("searching next route failed\n");
00535 return RR_ERROR;
00536 }
00537 if (res > 0) {
00538 LM_DBG("after_strict: No next URI found\n");
00539 return NOT_RR_DRIVEN;
00540 }
00541 rt = (rr_t*)hdr->parsed;
00542 } else rt = rt->next;
00543
00544
00545 uri = rt->nameaddr.uri;
00546 if (parse_uri(uri.s, uri.len, &puri) < 0) {
00547 LM_ERR("failed to parse URI\n");
00548 return RR_ERROR;
00549 }
00550 }
00551
00552
00553
00554
00555 routed_msg_id = _m->id;
00556 routed_params = _m->parsed_uri.params;
00557
00558 if (is_strict(&puri.params)) {
00559 LM_DBG("Next hop: '%.*s' is strict router\n", uri.len, ZSW(uri.s));
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569 if(get_maddr_uri(&uri, &puri)!=0) {
00570 LM_ERR("failed to check maddr\n");
00571 return RR_ERROR;
00572 }
00573 if (rewrite_uri(_m, &uri) < 0) {
00574 LM_ERR("failed to rewrite request URI\n");
00575 return RR_ERROR;
00576 }
00577
00578 if (rt->next) {
00579 rem_off = hdr->body.s;
00580 rem_len = rt->next->nameaddr.name.s - hdr->body.s;
00581 } else {
00582 rem_off = hdr->name.s;
00583 rem_len = hdr->len;
00584 }
00585 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
00586 LM_ERR("failed to remove Route HF\n");
00587 return RR_ERROR;
00588 }
00589 } else {
00590 LM_DBG("Next hop: '%.*s' is loose router\n",
00591 uri.len, ZSW(uri.s));
00592
00593 if(get_maddr_uri(&uri, &puri)!=0) {
00594 LM_ERR("failed to check maddr\n");
00595 return RR_ERROR;
00596 }
00597 if (set_dst_uri(_m, &uri) < 0) {
00598 LM_ERR("failed to set dst_uri\n");
00599 return RR_ERROR;
00600 }
00601
00602
00603
00604
00605
00606 if (rt != hdr->parsed) {
00607
00608
00609 rem_off = hdr->body.s;
00610 rem_len = rt->nameaddr.name.s - hdr->body.s;
00611 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
00612 LM_ERR("failed to remove Route HF\n");
00613 return RR_ERROR;
00614 }
00615 }
00616
00617
00618 res = find_rem_target(_m, &hdr, &rt, &prev);
00619 if (res < 0) {
00620 LM_ERR("searching for last Route URI failed\n");
00621 return RR_ERROR;
00622 } else if (res > 0) {
00623
00624 return RR_ERROR;
00625 }
00626
00627 uri = rt->nameaddr.uri;
00628 if(get_maddr_uri(&uri, 0)!=0) {
00629 LM_ERR("checking maddr failed\n");
00630 return RR_ERROR;
00631 }
00632 if (rewrite_uri(_m, &uri) < 0) {
00633 LM_ERR("failed to rewrite R-URI\n");
00634 return RR_ERROR;
00635 }
00636
00637
00638
00639
00640 LM_DBG("The last route URI: '%.*s'\n", rt->nameaddr.uri.len,
00641 ZSW(rt->nameaddr.uri.s));
00642
00643 if (prev) {
00644 rem_off = prev->nameaddr.name.s + prev->len;
00645 rem_len = rt->nameaddr.name.s + rt->len - rem_off;
00646 } else {
00647 rem_off = hdr->name.s;
00648 rem_len = hdr->len;
00649 }
00650 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
00651 LM_ERR("failed to remove Route HF\n");
00652 return RR_ERROR;
00653 }
00654 }
00655
00656
00657 if(routed_params.len > 0)
00658 run_rr_callbacks( _m, &routed_params );
00659
00660 return RR_DRIVEN;
00661 }
00662
00663
00670 static inline int after_loose(struct sip_msg* _m, int preloaded)
00671 {
00672 struct hdr_field* hdr;
00673 struct sip_uri puri;
00674 rr_t* rt;
00675 int res;
00676 int status;
00677 int ret;
00678 str uri;
00679 struct socket_info *si;
00680
00681 hdr = _m->route;
00682 rt = (rr_t*)hdr->parsed;
00683 uri = rt->nameaddr.uri;
00684
00685
00686 routed_msg_id = 0;
00687 routed_params.s = NULL;
00688 routed_params.len = 0;
00689
00690 if (parse_uri(uri.s, uri.len, &puri) < 0) {
00691 LM_ERR("failed to parse the first route URI\n");
00692 return RR_ERROR;
00693 }
00694
00695
00696 ret=is_myself(&puri);
00697 if (ret>0)
00698 {
00699 LM_DBG("Topmost route URI: '%.*s' is me\n",
00700 uri.len, ZSW(uri.s));
00701
00702 routed_msg_id = _m->id;
00703 routed_params = puri.params;
00704
00705 if (!rt->next) {
00706
00707
00708
00709 if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
00710 LM_ERR("failed to remove Route HF\n");
00711 return RR_ERROR;
00712 }
00713 res = find_next_route(_m, &hdr);
00714 if (res < 0) {
00715 LM_ERR("failed to find next route\n");
00716 return RR_ERROR;
00717 }
00718 if (res > 0) {
00719 LM_DBG("No next URI found\n");
00720 status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);
00721 goto done;
00722 }
00723 rt = (rr_t*)hdr->parsed;
00724 } else rt = rt->next;
00725
00726 if (enable_double_rr && is_2rr(&puri.params)) {
00727
00728
00729 if (parse_uri(rt->nameaddr.uri.s,rt->nameaddr.uri.len,&puri)<0) {
00730 LM_ERR("failed to parse the double route URI\n");
00731 return RR_ERROR;
00732 }
00733 si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
00734 if (si) {
00735 set_force_socket(_m, si);
00736 } else {
00737 if (enable_socket_mismatch_warning)
00738 LM_WARN("no socket found for match second RR\n");
00739 }
00740
00741 if (!rt->next) {
00742
00743
00744 if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
00745 LM_ERR("failed to remove Route HF\n");
00746 return RR_ERROR;
00747 }
00748 res = find_next_route(_m, &hdr);
00749 if (res < 0) {
00750 LM_ERR("failed to find next route\n");
00751 return RR_ERROR;
00752 }
00753 if (res > 0) {
00754 LM_DBG("no next URI found\n");
00755 status = (preloaded ? NOT_RR_DRIVEN : RR_DRIVEN);
00756 goto done;
00757 }
00758 rt = (rr_t*)hdr->parsed;
00759 } else rt = rt->next;
00760 }
00761
00762 uri = rt->nameaddr.uri;
00763 if (parse_uri(uri.s, uri.len, &puri) < 0) {
00764 LM_ERR("failed to parse the first route URI\n");
00765 return RR_ERROR;
00766 }
00767 } else {
00768 #ifdef ENABLE_USER_CHECK
00769
00770 if(ret < 0)
00771 return NOT_RR_DRIVEN;
00772 #endif
00773 LM_DBG("Topmost URI is NOT myself\n");
00774 }
00775
00776 LM_DBG("URI to be processed: '%.*s'\n", uri.len, ZSW(uri.s));
00777 if (is_strict(&puri.params)) {
00778 LM_DBG("Next URI is a strict router\n");
00779 if (handle_sr(_m, hdr, rt) < 0) {
00780 LM_ERR("failed to handle strict router\n");
00781 return RR_ERROR;
00782 }
00783 } else {
00784
00785 LM_DBG("Next URI is a loose router\n");
00786
00787 if(get_maddr_uri(&uri, &puri)!=0) {
00788 LM_ERR("checking maddr failed\n");
00789 return RR_ERROR;
00790 }
00791 if (set_dst_uri(_m, &uri) < 0) {
00792 LM_ERR("failed to set dst_uri\n");
00793 return RR_ERROR;
00794 }
00795
00796
00797 ruri_mark_new();
00798
00799
00800
00801 if (rt != hdr->parsed) {
00802 if (!del_lump(_m, hdr->body.s - _m->buf,
00803 rt->nameaddr.name.s - hdr->body.s, 0)) {
00804 LM_ERR("failed to remove Route HF\n");
00805 return RR_ERROR;
00806 }
00807 }
00808 }
00809 status = RR_DRIVEN;
00810
00811 done:
00812
00813 if(routed_params.len > 0)
00814 run_rr_callbacks( _m, &routed_params );
00815 return status;
00816 }
00817
00818
00824 int loose_route(struct sip_msg* _m)
00825 {
00826 int ret;
00827
00828 if (find_first_route(_m) != 0) {
00829 LM_DBG("There is no Route HF\n");
00830 return -1;
00831 }
00832
00833 if (parse_sip_msg_uri(_m)<0) {
00834 LM_ERR("failed to parse Request URI\n");
00835 return -1;
00836 }
00837
00838 ret = is_preloaded(_m);
00839 if (ret < 0) {
00840 return -1;
00841 } else if (ret == 1) {
00842 return after_loose(_m, 1);
00843 } else {
00844 if (is_myself(&_m->parsed_uri)) {
00845 return after_strict(_m);
00846 } else {
00847 return after_loose(_m, 0);
00848 }
00849 }
00850 }
00851
00852
00865 int check_route_param(struct sip_msg * msg, regex_t* re)
00866 {
00867 regmatch_t pmatch;
00868 char bk;
00869 str params;
00870
00871
00872 if (routed_msg_id != msg->id)
00873 return -1;
00874
00875
00876 if ( !routed_params.s || !routed_params.len )
00877 return -1;
00878
00879
00880 for( params=routed_params ; params.s[0]!=';' ; params.s--,params.len++ );
00881
00882
00883 bk = params.s[params.len];
00884 params.s[params.len] = 0;
00885 LM_DBG("params are <%s>\n", params.s);
00886 if (regexec( re, params.s, 1, &pmatch, 0)!=0) {
00887 params.s[params.len] = bk;
00888 return -1;
00889 } else {
00890 params.s[params.len] = bk;
00891 return 0;
00892 }
00893 }
00894
00895
00909 int get_route_param( struct sip_msg *msg, str *name, str *val)
00910 {
00911 char *p;
00912 char *end;
00913 char c;
00914 int quoted;
00915
00916
00917 if (routed_msg_id != msg->id)
00918 goto notfound;
00919
00920
00921 if ( !routed_params.s || !routed_params.len )
00922 goto notfound;
00923
00924 end = routed_params.s + routed_params.len;
00925 p = routed_params.s;
00926
00927
00928
00929 while ( end-p>name->len+2 ) {
00930 if (p!=routed_params.s) {
00931
00932 for( quoted=0 ; p<end && !(*p==';' && !quoted) ; p++ )
00933 if ( (*p=='"' || *p=='\'') && *(p-1)!='\\' )
00934 quoted ^= 0x1;
00935 if (p==end)
00936 goto notfound;
00937 p++;
00938 }
00939
00940 while( p<end && (*p==' ' || *p=='\t') )
00941 p++;
00942
00943 if ( end-p<name->len+2 )
00944 goto notfound;
00945 if ( memcmp(p,name->s,name->len)!=0 ) {
00946 p++;
00947 continue;
00948 }
00949 p+=name->len;
00950 while( p<end && (*p==' ' || *p=='\t') )
00951 p++;
00952 if (p==end|| *p==';') {
00953
00954 val->len = 0;
00955 val->s = 0;
00956 goto found;
00957 }
00958 if (*(p++)!='=')
00959 continue;
00960 while( p<end && (*p==' ' || *p=='\t') )
00961 p++;
00962 if (p==end)
00963 goto notfound;
00964
00965 if ( *p=='\'' || *p=='"') {
00966 for( val->s = ++p ; p<end ; p++) {
00967 if ((*p=='"' || *p=='\'') && *(p-1)!='\\' )
00968 break;
00969 }
00970 } else {
00971 for( val->s=p ; p<end ; p++) {
00972 if ( (c=*p)==';' || c==' ' || c=='\t' )
00973 break;
00974 }
00975 }
00976 val->len = p-val->s;
00977 if (val->len==0)
00978 val->s = 0;
00979 goto found;
00980 }
00981
00982 notfound:
00983 return -1;
00984 found:
00985 return 0;
00986 }
00987
00988
01001 int is_direction(struct sip_msg * msg, int dir)
01002 {
01003 static str ftag_param = {"ftag",4};
01004 static unsigned int last_id = (unsigned int)-1;
01005 static unsigned int last_dir = 0;
01006 str ftag_val;
01007 str tag;
01008
01009 if ( last_id==msg->id && last_dir!=0) {
01010 if (last_dir==RR_FLOW_UPSTREAM)
01011 goto upstream;
01012 else
01013 goto downstream;
01014 }
01015
01016 ftag_val.s = 0;
01017 ftag_val.len = 0;
01018
01019 if (get_route_param( msg, &ftag_param, &ftag_val)!=0) {
01020 LM_DBG("param ftag not found\n");
01021 goto downstream;
01022 }
01023
01024 if ( ftag_val.s==0 || ftag_val.len==0 ) {
01025 LM_DBG("param ftag has empty val\n");
01026 goto downstream;
01027 }
01028
01029
01030 if ( parse_from_header(msg)!=0 )
01031 goto downstream;
01032
01033 tag = ((struct to_body*)msg->from->parsed)->tag_value;
01034 if (tag.s==0 || tag.len==0)
01035 goto downstream;
01036
01037
01038 if (tag.len!=ftag_val.len || memcmp(tag.s,ftag_val.s,ftag_val.len))
01039 goto upstream;
01040
01041 downstream:
01042 last_id = msg->id;
01043 last_dir = RR_FLOW_DOWNSTREAM;
01044 return (dir==RR_FLOW_DOWNSTREAM)?0:-1;
01045 upstream:
01046 last_id = msg->id;
01047 last_dir = RR_FLOW_UPSTREAM;
01048 return (dir==RR_FLOW_UPSTREAM)?0:-1;
01049 }