2 * Copyright (C) 2001-2004 FhG Fokus
4 * This file is part of Kamailio, a free SIP server.
6 * Kamailio is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version
11 * Kamailio is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 * \brief Route & Record-Route module, loose routing support
30 #include "../../core/ut.h"
31 #include "../../core/str.h"
32 #include "../../core/dprint.h"
33 #include "../../core/forward.h"
34 #include "../../core/data_lump.h"
35 #include "../../core/socket_info.h"
36 #include "../../core/parser/parse_rr.h"
37 #include "../../core/parser/parse_uri.h"
38 #include "../../core/parser/parse_from.h"
39 #include "../../core/parser/parse_param.h"
40 #include "../../core/mem/mem.h"
41 #include "../../core/dset.h"
47 #define RR_ROUTE_PREFIX ROUTE_PREFIX "<"
48 #define RR_ROUTE_PREFIX_LEN (sizeof(RR_ROUTE_PREFIX)-1)
50 #define ROUTE_SUFFIX ">\r\n" /*!< SIP header suffix */
51 #define ROUTE_SUFFIX_LEN (sizeof(ROUTE_SUFFIX)-1)
53 /*! variables used to hook the param part of the local route */
54 static msg_ctx_id_t routed_msg_id = {0};
55 static str routed_params = {0,0};
57 extern int rr_force_send_socket;
58 extern int rr_sockname_mode;
61 * \brief Test whether we are processing pre-loaded route set by looking at the To tag
62 * \param msg SIP message
63 * \return -1 on failure, 0 on success
65 static int is_preloaded(struct sip_msg* msg)
69 if (!msg->to && parse_headers(msg, HDR_TO_F, 0) == -1) {
70 LM_ERR("failed to parse To header field\n");
75 LM_ERR("To header field not found\n");
79 tag = get_to(msg)->tag_value;
80 if (tag.s == 0 || tag.len == 0) {
81 LM_DBG("is_preloaded: Yes\n");
85 LM_DBG("is_preloaded: No\n");
91 * \brief Parse the message and find first occurrence of Route header field.
92 * \param _m SIP message
93 * \return -1 or -2 on a parser error, 0 if there is a Route HF and 1 if there is no Route HF
95 static inline int find_first_route(struct sip_msg* _m)
97 if (parse_headers(_m, HDR_ROUTE_F, 0) == -1) {
98 LM_ERR("failed to parse headers\n");
102 if (parse_rr(_m->route) < 0) {
103 LM_ERR("failed to parse Route HF\n");
108 LM_DBG("No Route headers found\n");
116 * \brief Check if URI is myself
119 * \return 0 if the URI is not myself, 1 otherwise
121 static inline int is_myself(sip_uri_t *_puri)
125 if(_puri->host.len==0) {
126 /* catch uri without host (e.g., tel uri) */
130 ret = check_self(&_puri->host,
131 _puri->port_no?_puri->port_no:SIP_PORT, 0);/* match all protos*/
132 if (ret < 0) return 0;
134 #ifdef ENABLE_USER_CHECK
135 if(ret==1 && i_user.len && i_user.len==_puri->user.len
136 && strncmp(i_user.s, _puri->user.s, _puri->user.len)==0)
138 LM_DBG("ignore user matched - URI is not to the server itself\n");
144 /* match on host:port, but if gruu, then fail */
145 if(_puri->gr.s!=NULL)
154 * \brief Find and parse next Route header field
155 * \param _m SIP message
156 * \param _hdr SIP header
157 * \return negative on failure, 0 if the Route header was already parsed, 1 if no next
158 * Route header could be found
160 static inline int find_next_route(struct sip_msg* _m, struct hdr_field** _hdr)
162 struct hdr_field* ptr;
166 /* Try to find already parsed Route headers */
168 if (ptr->type == HDR_ROUTE_T) goto found;
172 /* There are no already parsed Route headers, try to find next
173 * occurrence of Route header
175 if (parse_headers(_m, HDR_ROUTE_F, 1) == -1) {
176 LM_ERR("failed to parse headers\n");
180 if ((_m->last_header->type!=HDR_ROUTE_T) || (_m->last_header==*_hdr)) {
181 LM_DBG("No next Route HF found\n");
185 ptr = _m->last_header;
188 if (parse_rr(ptr) < 0) {
189 LM_ERR("failed to parse Route body\n");
199 * \brief Check if the given uri contains lr parameter which marks loose routers
200 * \param _params URI string
201 * \return 1 if URI contains no lr parameter, 0 if it contains a lr parameter
203 static inline int is_strict(str* _params)
208 if (_params->len == 0) return 1;
211 s.len = _params->len;
213 for(i = 0; i < s.len; i++) {
222 case 'L': state = 1; break;
223 default: state = 4; break;
230 case 'R': state = 2; break;
231 default: state = 4; break;
242 case '\t': state = 3; break;
243 default: state = 4; break;
255 default: state = 4; break;
261 case '\"': state = 5; break;
262 case ';': state = 0; break;
269 case '\\': state = 6; break;
270 case '\"': state = 4; break;
275 case 6: state = 5; break;
279 if ((state == 2) || (state == 3)) return 0;
285 * \brief Set Request-URI as last Route header of a SIP
287 * Set Request-URI as last Route header of a SIP message,
288 * this is necessary when forwarding to a strict router.
289 * Allocates memory for message lump in private memory.
290 * \param _m SIP message
291 * \return negative on failure, 0 on success
293 static inline int save_ruri(struct sip_msg* _m)
299 /* We must parse the whole message header here, because
300 * the Request-URI must be saved in last Route HF in the message
302 if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
303 LM_ERR("failed to parse message\n");
307 /* Create an anchor */
308 anchor = anchor_lump(_m, _m->unparsed - _m->buf, 0, 0);
310 LM_ERR("failed to get anchor\n");
314 /* Create buffer for new lump */
315 len = RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len
317 s = (char*)pkg_malloc(len);
319 LM_ERR("No memory pkg left\n");
323 /* Create new header field */
324 memcpy(s, RR_ROUTE_PREFIX, RR_ROUTE_PREFIX_LEN);
325 memcpy(s + RR_ROUTE_PREFIX_LEN, _m->first_line.u.request.uri.s,
326 _m->first_line.u.request.uri.len);
327 memcpy(s + RR_ROUTE_PREFIX_LEN + _m->first_line.u.request.uri.len,
328 ROUTE_SUFFIX, ROUTE_SUFFIX_LEN);
330 LM_DBG("New header: '%.*s'\n", len, ZSW(s));
333 if (insert_new_lump_before(anchor, s, len, 0) == 0) {
335 LM_ERR("failed to insert lump\n");
344 * \brief Parse URI and check if it has a maddr parameter
345 * \param uri URI to be checked if it has maddr, and also the output URI
346 * \param puri parsed URI
347 * \return -1 on failure, 0 on success
349 static inline int get_maddr_uri(str *uri, struct sip_uri *puri)
351 /* The max length of the maddr parameter is 127 */
352 static char builturi[127+1];
355 if(uri==NULL || uri->s==NULL)
359 if (parse_uri(uri->s, uri->len, &turi) < 0)
361 LM_ERR("failed to parse the URI\n");
367 if(puri->maddr.s==NULL)
370 /* sip: + maddr + : + port */
371 if( (puri->maddr_val.len) > (127 - 10) )
373 LM_ERR( "Too long maddr parameter\n");
376 memcpy( builturi, "sip:", 4 );
377 memcpy( builturi+4, puri->maddr_val.s, puri->maddr_val.len );
379 if( puri->port.len > 0 )
381 builturi[4+puri->maddr_val.len] =':';
382 memcpy(builturi+5+puri->maddr_val.len, puri->port.s,
386 uri->len = 4+puri->maddr_val.len
387 + ((puri->port.len>0)?(1+puri->port.len):0);
388 builturi[uri->len]='\0';
391 LM_DBG("uri is %s\n", builturi );
397 * \brief Necessary logic to forward request to strict routers
398 * \param _m SIP message
399 * \param _hdr SIP header field
400 * \param _r Route & Record-Route header field body
401 * \return 0 on success, negative on an error
403 static inline int handle_sr(struct sip_msg* _m, struct hdr_field* _hdr, rr_t* _r)
409 /* Next hop is strict router, save R-URI here */
410 if (save_ruri(_m) < 0) {
411 LM_ERR("failed to save Request-URI\n");
415 /* Put the first Route in Request-URI */
416 uri = _r->nameaddr.uri;
417 if(get_maddr_uri(&uri, 0)!=0) {
418 LM_ERR("failed to check maddr\n");
421 if (rewrite_uri(_m, &uri) < 0) {
422 LM_ERR("failed to rewrite request URI\n");
427 rem_off = _hdr->name.s;
430 rem_off = _hdr->body.s;
431 rem_len = _r->next->nameaddr.name.s - _hdr->body.s;
434 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
435 LM_ERR("failed to remove Route HF\n");
444 * \brief Find last route in the last Route header field
446 * Find last route in the last Route header field, if there was a previous
447 * route in the last Route header field, it will be saved in _p parameter
448 * \param _m SIP message
449 * \param _h SIP header field
450 * \param _l Route & Record-Route header field body
451 * \param _p Route & Record-Route header field body
452 * \return negative on failure, 0 on success
454 static inline int find_rem_target(struct sip_msg* _m, struct hdr_field** _h, rr_t** _l, rr_t** _p)
456 struct hdr_field* ptr, *last;
458 if (parse_headers(_m, HDR_EOH_F, 0) == -1) {
459 LM_ERR("failed to parse message header\n");
467 if (ptr->type == HDR_ROUTE_T) last = ptr;
472 if (parse_rr(last) < 0) {
473 LM_ERR("failed to parse last Route HF\n");
478 *_l = (rr_t*)last->parsed;
480 while ((*_l)->next) {
486 LM_ERR("search for last Route HF failed\n");
491 /* Largest route URI is of the form:
492 sip:[1234:5678:9012:3456:7890:1234:5678:9012]:12345;transport=sctp
493 this is 66 characters long */
494 #define MAX_ROUTE_URI_LEN 66
495 static char uri_buf[MAX_ROUTE_URI_LEN];
498 * \brief Perform outbound processing - force local socket and set destination URI
499 * \param _m SIP message
500 * \param flow_token string containing the flow-token extracted from the Route: header
501 * \param dst_uri string to write the destination URI to (extracted from flow-token)
502 * \return -1 on error, 0 when outbound not in use, 1 when outbound in use
504 static inline int process_outbound(struct sip_msg *_m, str flow_token)
507 struct receive_info *rcv = NULL;
508 struct socket_info *si;
511 if (!rr_obb.decode_flow_token)
514 ret = rr_obb.decode_flow_token(_m, &rcv, flow_token);
517 LM_DBG("no flow token found - outbound not in use\n");
519 } else if (ret == -1) {
520 LM_INFO("failed to decode flow token\n");
522 } else if (!ip_addr_cmp(&rcv->src_ip, &_m->rcv.src_ip)
523 || rcv->src_port != _m->rcv.src_port) {
524 LM_DBG("\"incoming\" request found. Using flow-token for "
527 /* First, force the local socket */
528 si = find_si(&rcv->dst_ip, rcv->dst_port, rcv->proto);
530 set_force_socket(_m, si);
532 LM_INFO("cannot find socket from flow-token\n");
536 /* Second, override the destination URI */
540 dst_uri.len += snprintf(dst_uri.s + dst_uri.len,
541 MAX_ROUTE_URI_LEN - dst_uri.len,
543 rcv->src_ip.af == AF_INET6 ? "[" : "");
544 dst_uri.len += ip_addr2sbuf(&rcv->src_ip,
545 dst_uri.s + dst_uri.len,
546 MAX_ROUTE_URI_LEN - dst_uri.len);
547 dst_uri.len += snprintf(dst_uri.s + dst_uri.len,
548 MAX_ROUTE_URI_LEN - dst_uri.len,
549 "%s:%d;transport=%s",
550 rcv->src_ip.af == AF_INET6 ? "]" : "",
552 get_proto_name(rcv->proto));
554 if (set_dst_uri(_m, &dst_uri) < 0) {
555 LM_ERR("failed to set dst_uri\n");
563 LM_DBG("Not using flow-token for routing\n");
568 * \brief Previous hop was a strict router, handle this case
569 * \param _m SIP message
570 * \return -1 on error, 1 on success
572 static inline int after_strict(struct sip_msg* _m)
575 struct hdr_field* hdr;
580 struct socket_info *si;
583 rt = (rr_t*)hdr->parsed;
584 uri = rt->nameaddr.uri;
586 /* reset rr handling static vars for safety in error case */
587 routed_msg_id.msgid = 0;
588 routed_msg_id.pid = 0;
589 routed_params.s = NULL;
590 routed_params.len = 0;
592 if (parse_uri(uri.s, uri.len, &puri) < 0) {
593 LM_ERR("failed to parse the first route URI\n");
597 if ( enable_double_rr && is_2rr(&puri.params) && is_myself(&puri)) {
598 /* double route may occure due different IP and port, so force as
599 * send interface the one advertise in second Route */
600 si = grep_sock_info( &puri.host, puri.port_no, puri.proto);
602 set_force_socket(_m, si);
604 if (enable_socket_mismatch_warning)
605 LM_WARN("no socket found for match second RR\n");
609 /* No next route in the same header, remove the whole header
612 if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
613 LM_ERR("failed to remove Route HF\n");
616 res = find_next_route(_m, &hdr);
618 LM_ERR("searching next route failed\n");
621 if (res > 0) { /* No next route found */
622 LM_DBG("after_strict: No next URI found\n");
623 return RR_NOT_DRIVEN;
625 rt = (rr_t*)hdr->parsed;
626 } else rt = rt->next;
628 /* parse the new found uri */
629 uri = rt->nameaddr.uri;
630 if (parse_uri(uri.s, uri.len, &puri) < 0) {
631 LM_ERR("failed to parse URI\n");
636 /* set the hooks for the param
637 * important note: RURI is already parsed by the above function, so
638 * we just used it without any checking */
639 routed_msg_id.msgid = _m->id;
640 routed_msg_id.pid = _m->pid;
641 routed_params = _m->parsed_uri.params;
643 if (is_strict(&puri.params)) {
644 LM_DBG("Next hop: '%.*s' is strict router\n", uri.len, ZSW(uri.s));
645 /* Previous hop was a strict router and the next hop is strict
646 * router too. There is no need to save R-URI again because it
647 * is saved already. In fact, in this case we will behave exactly
648 * like a strict router. */
650 /* Note: when there is only one Route URI left (endpoint), it will
651 * always be a strict router because endpoints don't use ;lr parameter
652 * In this case we will simply put the URI in R-URI and forward it,
653 * which will work perfectly */
654 if(get_maddr_uri(&uri, &puri)!=0) {
655 LM_ERR("failed to check maddr\n");
658 if (rewrite_uri(_m, &uri) < 0) {
659 LM_ERR("failed to rewrite request URI\n");
664 rem_off = hdr->body.s;
665 rem_len = rt->next->nameaddr.name.s - hdr->body.s;
667 rem_off = hdr->name.s;
670 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
671 LM_ERR("failed to remove Route HF\n");
675 LM_DBG("Next hop: '%.*s' is loose router\n",
676 uri.len, ZSW(uri.s));
678 if(get_maddr_uri(&uri, &puri)!=0) {
679 LM_ERR("failed to check maddr\n");
682 if (set_dst_uri(_m, &uri) < 0) {
683 LM_ERR("failed to set dst_uri\n");
687 /* Next hop is a loose router - Which means that is is not endpoint yet
688 * In This case we have to recover from previous strict routing, that
689 * means we have to find the last Route URI and put in in R-URI and
690 * remove the last Route URI. */
691 if (rt != hdr->parsed) {
692 /* There is a previous route uri which was 2nd uri of mine
693 * and must be removed here */
694 rem_off = hdr->body.s;
695 rem_len = rt->nameaddr.name.s - hdr->body.s;
696 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
697 LM_ERR("failed to remove Route HF\n");
703 res = find_rem_target(_m, &hdr, &rt, &prev);
705 LM_ERR("searching for last Route URI failed\n");
707 } else if (res > 0) {
708 /* No remote target is an error */
712 uri = rt->nameaddr.uri;
713 if(get_maddr_uri(&uri, 0)!=0) {
714 LM_ERR("checking maddr failed\n");
717 if (rewrite_uri(_m, &uri) < 0) {
718 LM_ERR("failed to rewrite R-URI\n");
722 /* The first character if uri will be either '<' when it is the
723 * only URI in a Route header field or ',' if there is more than
724 * one URI in the header field */
725 LM_DBG("The last route URI: '%.*s'\n", rt->nameaddr.uri.len,
726 ZSW(rt->nameaddr.uri.s));
729 rem_off = prev->nameaddr.name.s + prev->len;
730 rem_len = rt->nameaddr.name.s + rt->len - rem_off;
732 rem_off = hdr->name.s;
735 if (!del_lump(_m, rem_off - _m->buf, rem_len, 0)) {
736 LM_ERR("failed to remove Route HF\n");
741 /* run RR callbacks only if we have Route URI parameters */
742 if(routed_params.len > 0)
743 run_rr_callbacks( _m, &routed_params );
749 static inline void rr_do_force_send_socket(sip_msg_t *_m, sip_uri_t *puri,
752 socket_info_t *si = NULL;
753 param_hooks_t phooks;
754 param_t* plist = NULL;
759 if(rr_sockname_mode!=0 && puri->params.len>0) {
761 if(s.s[s.len-1]==';') {
764 if (parse_params(&s, CLASS_ANY, &phooks, &plist)<0) {
765 LM_ERR("bad sip uri parameters: %.*s\n", s.len, s.s);
768 for (pit = plist; pit; pit=pit->next) {
769 if (pit->name.len==SOCKNAME_ATTR_LEN
770 && strncasecmp(pit->name.s, SOCKNAME_ATTR,
771 SOCKNAME_ATTR_LEN)==0) {
772 if(pit->body.len>0) {
773 si = ksr_get_socket_by_name(&pit->body);
775 LM_DBG("found socket with name: %.*s\n",
776 pit->body.len, pit->body.s);
777 set_force_socket(_m, si);
781 LM_DBG("failed to find socket with name: %.*s\n",
782 pit->body.len, pit->body.s);
787 LM_DBG("use of sockname parameter enabled, but failed to find it\n");
791 if ((si = grep_sock_info(&puri->host,
792 puri->port_no?puri->port_no:proto_default_port(puri->proto),
793 puri->proto)) != 0) {
794 LM_DBG("set send socket %p for local route uri: %.*s\n", si,
795 rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));
796 set_force_socket(_m, si);
797 } else if ((si = grep_sock_info(&puri->host, puri->port_no,
798 puri->proto)) != 0) {
799 LM_DBG("set send socket %p for local route uri: %.*s\n", si,
800 rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));
801 set_force_socket(_m, si);
803 if (enable_socket_mismatch_warning && rr2on) {
804 LM_WARN("no socket found to match second RR (%.*s)\n",
805 rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));
806 if(!is_myself(puri)) {
807 LM_WARN("second RR uri is not myself (%.*s)\n",
808 rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));
811 LM_DBG("no socket found to match second RR (%.*s)\n",
812 rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));
818 * \brief Previous hop was a loose router, handle this case
819 * \param _m SIP message
820 * \param preloaded do we have a preloaded route set
821 * \return -1 on failure, 1 on success
823 static inline int after_loose(struct sip_msg* _m, int preloaded)
825 struct hdr_field* hdr;
829 int status = RR_DRIVEN;
836 rt = (rr_t*)hdr->parsed;
837 uri = rt->nameaddr.uri;
839 /* reset rr handling static vars for safety in error case */
840 routed_msg_id.msgid = 0;
841 routed_msg_id.pid = 0;
843 if (parse_uri(uri.s, uri.len, &puri) < 0) {
844 LM_ERR("failed to parse the first route URI (%.*s)\n",
845 uri.len, ZSW(uri.s));
849 routed_params = puri.params;
850 uri_is_myself = is_myself(&puri);
852 /* IF the URI was added by me, remove it */
855 LM_DBG("Topmost route URI: '%.*s' is me\n",
856 uri.len, ZSW(uri.s));
857 /* set the hooks for the params */
858 routed_msg_id.msgid = _m->id;
859 routed_msg_id.pid = _m->pid;
861 if ((use_ob = process_outbound(_m, puri.user)) < 0) {
862 LM_INFO("failed to process outbound flow-token\n");
863 return RR_FLOW_TOKEN_BROKEN;
866 if (rr_force_send_socket && !use_ob) {
867 if (!enable_double_rr || !is_2rr(&puri.params)) {
868 rr_do_force_send_socket(_m, &puri, rt, 0);
872 /* No next route in the same header, remove the whole header
875 if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
876 LM_ERR("failed to remove Route HF\n");
880 res = find_next_route(_m, &hdr);
882 LM_ERR("failed to find next route\n");
885 if (res > 0) { /* No next route found */
886 LM_DBG("No next URI found\n");
887 status = (preloaded ? RR_PRELOADED : RR_DRIVEN);
890 rt = (rr_t*)hdr->parsed;
891 } else rt = rt->next;
893 if (enable_double_rr && is_2rr(&puri.params)) {
894 /* double route may occure due different IP and port, so force as
895 * send interface the one advertise in second Route */
896 if (parse_uri(rt->nameaddr.uri.s,rt->nameaddr.uri.len,&puri)<0) {
897 LM_ERR("failed to parse the double route URI (%.*s)\n",
898 rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));
903 rr_do_force_send_socket(_m, &puri, rt, 1);
907 /* No next route in the same header, remove the whole header
908 * field immediately */
909 if (!del_lump(_m, hdr->name.s - _m->buf, hdr->len, 0)) {
910 LM_ERR("failed to remove Route HF\n");
913 res = find_next_route(_m, &hdr);
915 LM_ERR("failed to find next route\n");
918 if (res > 0) { /* No next route found */
919 LM_DBG("no next URI found\n");
920 status = (preloaded ? RR_PRELOADED : RR_DRIVEN);
923 rt = (rr_t*)hdr->parsed;
924 } else rt = rt->next;
927 uri = rt->nameaddr.uri;
928 if (parse_uri(uri.s, uri.len, &puri) < 0) {
929 LM_ERR("failed to parse the next route URI (%.*s)\n",
930 uri.len, ZSW(uri.s));
933 _m->msg_flags |= FL_ROUTE_ADDR;
935 #ifdef ENABLE_USER_CHECK
936 /* check if it the ignored user */
937 if(uri_is_myself < 0)
938 return RR_NOT_DRIVEN;
940 LM_DBG("Topmost URI is NOT myself\n");
941 routed_params.s = NULL;
942 routed_params.len = 0;
945 LM_DBG("URI to be processed: '%.*s'\n", uri.len, ZSW(uri.s));
946 if (is_strict(&puri.params)) {
947 LM_DBG("Next URI is a strict router\n");
948 if (handle_sr(_m, hdr, rt) < 0) {
949 LM_ERR("failed to handle strict router\n");
953 /* Next hop is loose router */
954 LM_DBG("Next URI is a loose router\n");
957 if(get_maddr_uri(&uri, &puri)!=0) {
958 LM_ERR("checking maddr failed\n");
962 if (set_dst_uri(_m, &uri) < 0) {
963 LM_ERR("failed to set dst_uri\n");
966 /* dst_uri changed, so it makes sense to re-use the current uri for
968 ruri_mark_new(); /* re-use uri for serial forking */
971 /* There is a previous route uri which was 2nd uri of mine
972 * and must be removed here */
973 if (rt != hdr->parsed) {
974 if (!del_lump(_m, hdr->body.s - _m->buf,
975 rt->nameaddr.name.s - hdr->body.s, 0)) {
976 LM_ERR("failed to remove Route HF\n");
984 status = RR_OB_DRIVEN;
986 /* run RR callbacks only if we have Route URI parameters */
987 if(routed_params.len > 0) {
988 rparams = routed_params;
989 run_rr_callbacks( _m, &rparams );
996 * \brief Do loose routing as per RFC3261
997 * \param _m SIP message
998 * \return negative on failure or preloaded, 1 on success
1000 int loose_route(struct sip_msg* _m)
1004 if (find_first_route(_m) != 0) {
1005 LM_DBG("There is no Route HF\n");
1009 if (parse_sip_msg_uri(_m)<0) {
1010 LM_ERR("failed to parse Request URI\n");
1014 ret = is_preloaded(_m);
1017 } else if (ret == 1) {
1018 return after_loose(_m, 1);
1020 if (is_myself(&_m->parsed_uri)) {
1021 return after_strict(_m);
1023 return after_loose(_m, 0);
1031 int redo_route_params(sip_msg_t *msg)
1041 if(msg->first_line.type != SIP_REQUEST) {
1045 if(msg->route==NULL) {
1049 if(msg->route->parsed==NULL) {
1050 if (parse_rr(msg->route) < 0) {
1051 LM_ERR("failed to parse Route HF\n");
1056 if(msg->route->parsed==NULL) {
1057 LM_ERR("NULL parsed Route header\n");
1061 /* check if the hooked params belong to the same message */
1062 if (routed_msg_id.msgid != msg->id || routed_msg_id.pid != msg->pid) {
1065 if((redo==0) && (routed_params.s==NULL || routed_params.len<=0)) {
1068 if((redo==0) && (routed_params.s<msg->buf
1069 || routed_params.s>msg->buf+msg->len)) {
1074 rt = (rr_t*)hdr->parsed;
1075 uri = rt->nameaddr.uri;
1077 /* reset rr handling static vars for safety in error case */
1078 routed_msg_id.msgid = 0;
1079 routed_msg_id.pid = 0;
1081 if (parse_uri(uri.s, uri.len, &puri) < 0) {
1082 LM_ERR("failed to parse the first route URI (%.*s)\n",
1083 uri.len, ZSW(uri.s));
1087 uri_is_myself = is_myself(&puri);
1089 /* if the URI was added by me, remove it */
1090 if (uri_is_myself>0) {
1091 LM_DBG("Topmost route URI: '%.*s' is me\n",
1092 uri.len, ZSW(uri.s));
1093 /* set the hooks for the params */
1094 routed_msg_id.msgid = msg->id;
1095 routed_msg_id.pid = msg->pid;
1096 routed_params = puri.params;
1106 * \brief Check if the route hdr has the required parameter
1108 * The function checks for the request "msg" if the URI parameters
1109 * of the local Route header (corresponding to the local server)
1110 * matches the given regular expression "re". It must be call
1111 * after the loose_route was done.
1113 * \param msg SIP message request that will has the Route header parameters checked
1114 * \param re compiled regular expression to be checked against the Route header parameters
1115 * \return -1 on failure, 1 on success
1117 int check_route_param(sip_msg_t * msg, regex_t* re)
1124 /* check if the hooked params belong to the same message */
1125 if(redo_route_params(msg)<0) {
1129 /* check if params are present */
1130 if ( !routed_params.s || routed_params.len<=0 ) {
1133 rruri = ((rr_t*)(msg->route->parsed))->nameaddr.uri;
1135 /* include also the first ';' */
1136 for( params=routed_params ;
1137 params.s>rruri.s && params.s[0]!=';' ;
1138 params.s--,params.len++ );
1140 LM_DBG("route params checking against [%.*s] (orig: [%.*s])\n",
1141 params.len, params.s, routed_params.len, routed_params.s);
1143 /* do the well-known trick to convert to null terminted */
1144 bk = params.s[params.len];
1145 params.s[params.len] = 0;
1146 LM_DBG("params are <%s>\n", params.s);
1147 if (regexec( re, params.s, 1, &pmatch, 0)!=0) {
1148 params.s[params.len] = bk;
1151 params.s[params.len] = bk;
1158 * \brief Gets the value of a route parameter
1160 * The function search in to the "msg"'s Route header parameters
1161 * the parameter called "name" and returns its value into "val".
1162 * It must be call only after the loose_route is done.
1164 * \param msg - request that will have the Route header parameter searched
1165 * \param name - contains the Route header parameter to be serached
1166 * \param val returns the value of the searched Route header parameter if found.
1167 * It might be an empty string if the parameter had no value.
1168 * \return 0 if parameter was found (even if it has no value), -1 otherwise
1170 int get_route_param(sip_msg_t *msg, str *name, str *val)
1177 /* check if the hooked params belong to the same message */
1178 if(redo_route_params(msg)<0) {
1182 /* check if params are present */
1183 if ( !routed_params.s || routed_params.len<=0 )
1186 end = routed_params.s + routed_params.len;
1187 p = routed_params.s;
1190 /* parse the parameters string and find the "name" param */
1191 while ( end-p>name->len+2 ) {
1192 if (p!=routed_params.s) {
1193 /* go to first ';' char */
1194 for( quoted=0 ; p<end && !(*p==';' && !quoted) ; p++ )
1195 if ( (*p=='"' || *p=='\'') && *(p-1)!='\\' )
1201 /* get first non space char */
1202 while( p<end && (*p==' ' || *p=='\t') )
1204 /* check the name - length first and content after */
1205 if ( end-p<name->len+2 )
1207 if ( memcmp(p,name->s,name->len)!=0 ) {
1212 while( p<end && (*p==' ' || *p=='\t') )
1214 if (p==end|| *p==';') {
1222 while( p<end && (*p==' ' || *p=='\t') )
1227 if ( *p=='\'' || *p=='"') {
1228 for( val->s = ++p ; p<end ; p++) {
1229 if ((*p=='"' || *p=='\'') && *(p-1)!='\\' )
1233 for( val->s=p ; p<end ; p++) {
1234 if ( (c=*p)==';' || c==' ' || c=='\t' )
1238 val->len = p-val->s;
1252 * \brief Check the direction of the message
1254 * The function checks the flow direction of the request "msg". As
1255 * for checking it's used the "ftag" Route header parameter, the
1256 * append_fromtag module parameter must be enables.
1257 * Also this must be call only after the loose_route is done.
1259 * \param msg SIP message request that will have the direction checked
1260 * \param dir direction to be checked against. It may be RR_FLOW_UPSTREAM or RR_FLOW_DOWNSTREAM
1261 * \return 0 if the request flow direction is the same as the given direction, -1 otherwise
1263 int is_direction(struct sip_msg * msg, int dir)
1265 static str ftag_param = {"ftag",4};
1266 static msg_ctx_id_t last_id = {0};
1267 static unsigned int last_dir = 0;
1271 if ( last_id.msgid==msg->id && last_id.pid==msg->pid && last_dir!=0) {
1272 if (last_dir==RR_FLOW_UPSTREAM)
1281 if (get_route_param( msg, &ftag_param, &ftag_val)!=0) {
1282 LM_DBG("param ftag not found\n");
1286 if ( ftag_val.s==0 || ftag_val.len==0 ) {
1287 LM_DBG("param ftag has empty val\n");
1291 /* get the tag value from FROM hdr */
1292 if ( parse_from_header(msg)!=0 )
1295 tag = ((struct to_body*)msg->from->parsed)->tag_value;
1296 if (tag.s==0 || tag.len==0)
1299 /* compare the 2 strings */
1300 if (tag.len!=ftag_val.len || memcmp(tag.s,ftag_val.s,ftag_val.len))
1304 last_id.msgid = msg->id;
1305 last_id.pid = msg->pid;
1306 last_dir = RR_FLOW_DOWNSTREAM;
1307 return (dir==RR_FLOW_DOWNSTREAM)?0:-1;
1309 last_id.msgid = msg->id;
1310 last_id.pid = msg->pid;
1311 last_dir = RR_FLOW_UPSTREAM;
1312 return (dir==RR_FLOW_UPSTREAM)?0:-1;