use proper next hop in strict routing mode (issue #3609)
authorKevin P. Fleming <kpfleming@digium.com>
Mon, 29 Aug 2005 23:03:07 +0000 (23:03 +0000)
committerKevin P. Fleming <kpfleming@digium.com>
Mon, 29 Aug 2005 23:03:07 +0000 (23:03 +0000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@6443 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index c86b0bd..f43fd73 100755 (executable)
@@ -3809,6 +3809,7 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, in
        char newto[256];
        char *c, *n;
        char *ot, *of;
        char newto[256];
        char *c, *n;
        char *ot, *of;
+       int is_strict = 0;      /* Strict routing flag */
 
        memset(req, 0, sizeof(struct sip_request));
        
 
        memset(req, 0, sizeof(struct sip_request));
        
@@ -3823,17 +3824,23 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, in
                p->branch ^= rand();
                build_via(p, p->via, sizeof(p->via));
        }
                p->branch ^= rand();
                build_via(p, p->via, sizeof(p->via));
        }
+
+
+       /* Check for strict or loose router */
+       if (p->route && !ast_strlen_zero(p->route->hop) && strstr(p->route->hop,";lr") == NULL)
+               is_strict = 1;
+
        if (sipmethod == SIP_CANCEL) {
                c = p->initreq.rlPart2; /* Use original URI */
        } else if (sipmethod == SIP_ACK) {
                /* Use URI from Contact: in 200 OK (if INVITE) 
                (we only have the contacturi on INVITEs) */
                if (!ast_strlen_zero(p->okcontacturi))
        if (sipmethod == SIP_CANCEL) {
                c = p->initreq.rlPart2; /* Use original URI */
        } else if (sipmethod == SIP_ACK) {
                /* Use URI from Contact: in 200 OK (if INVITE) 
                (we only have the contacturi on INVITEs) */
                if (!ast_strlen_zero(p->okcontacturi))
-                       c = p->okcontacturi;
-               else
-                       c = p->initreq.rlPart2;
+                       c = is_strict ? p->route->hop : p->okcontacturi;
+               else
+                       c = p->initreq.rlPart2;
        } else if (!ast_strlen_zero(p->okcontacturi)) {
        } else if (!ast_strlen_zero(p->okcontacturi)) {
-               c = p->okcontacturi; /* Use for BYE, REFER or REINVITE */
+                       c = is_strict ? p->route->hop : p->okcontacturi; /* Use for BYE or REINVITE */
        } else if (!ast_strlen_zero(p->uri)) {
                c = p->uri;
        } else {
        } else if (!ast_strlen_zero(p->uri)) {
                c = p->uri;
        } else {
@@ -3852,7 +3859,10 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, in
        add_header(req, "Via", p->via);
        if (p->route) {
                set_destination(p, p->route->hop);
        add_header(req, "Via", p->via);
        if (p->route) {
                set_destination(p, p->route->hop);
-               add_route(req, p->route->next);
+               if (is_strict)
+                       add_route(req, p->route->next);
+               else
+                       add_route(req, p->route);
        }
 
        ot = get_header(orig, "To");
        }
 
        ot = get_header(orig, "To");
@@ -5486,33 +5496,38 @@ static void build_route(struct sip_pvt *p, struct sip_request *req, int backward
                        rr += len;
                }
        }
                        rr += len;
                }
        }
-       /* 2nd append the Contact: if there is one */
-       /* Can be multiple Contact headers, comma separated values - we just take the first */
-       contact = get_header(req, "Contact");
-       if (!ast_strlen_zero(contact)) {
-               ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
-               /* Look for <: delimited address */
-               c = strchr(contact, '<');
-               if (c) {
-                       /* Take to > */
-                       ++c;
-                       len = strcspn(c, ">") + 1;
-               } else {
-                       /* No <> - just take the lot */
-                       c = contact;
-                       len = strlen(contact) + 1;
-               }
-               thishop = malloc(sizeof(*thishop) + len);
-               if (thishop) {
-                       ast_copy_string(thishop->hop, c, len);
-                       thishop->next = NULL;
-                       /* Goes at the end */
-                       if (tail)
-                               tail->next = thishop;
-                       else
-                               head = thishop;
+
+       /* Only append the contact if we are dealing with a strict router */
+       if (!head || (!ast_strlen_zero(head->hop) && strstr(head->hop,";lr") == NULL) ) {
+               /* 2nd append the Contact: if there is one */
+               /* Can be multiple Contact headers, comma separated values - we just take the first */
+               contact = get_header(req, "Contact");
+               if (!ast_strlen_zero(contact)) {
+                       ast_log(LOG_DEBUG, "build_route: Contact hop: %s\n", contact);
+                       /* Look for <: delimited address */
+                       c = strchr(contact, '<');
+                       if (c) {
+                               /* Take to > */
+                               ++c;
+                               len = strcspn(c, ">") + 1;
+                       } else {
+                               /* No <> - just take the lot */
+                               c = contact;
+                               len = strlen(contact) + 1;
+                       }
+                       thishop = malloc(sizeof(*thishop) + len);
+                       if (thishop) {
+                               strcpy(thishop->hop, c);
+                               thishop->next = NULL;
+                               /* Goes at the end */
+                               if (tail)
+                                       tail->next = thishop;
+                               else
+                                       head = thishop;
+                       }
                }
        }
                }
        }
+
        /* Store as new route */
        p->route = head;
 
        /* Store as new route */
        p->route = head;