diff options
Diffstat (limited to 'channels')
-rw-r--r-- | channels/chan_sip.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 1d8d4dbf6..d846737b2 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -1296,7 +1296,7 @@ static int auto_congest(const void *arg); static struct sip_pvt *find_call(struct sip_request *req, struct ast_sockaddr *addr, const int intended_method); static void free_old_route(struct sip_route *route); static void list_route(struct sip_route *route); -static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards); +static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp); static enum check_auth_result register_verify(struct sip_pvt *p, struct ast_sockaddr *addr, struct sip_request *req, const char *uri); static struct sip_pvt *get_sip_pvt_byid_locked(const char *callid, const char *totag, const char *fromtag); @@ -8184,7 +8184,7 @@ static void forked_invite_init(struct sip_request *req, const char *new_theirtag ast_string_field_set(p, our_contact, original->our_contact); ast_string_field_set(p, fullcontact, original->fullcontact); parse_ok_contact(p, req); - build_route(p, req, 1); + build_route(p, req, 1, 0); transmit_request(p, SIP_ACK, p->ocseq, XMIT_UNRELIABLE, TRUE); transmit_request(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE); @@ -10663,7 +10663,11 @@ static int reqprep(struct sip_request *req, struct sip_pvt *p, int sipmethod, ui snprintf(tmp, sizeof(tmp), "%u %s", seqno, sip_methods[sipmethod].text); add_header(req, "Via", p->via); - if (p->route) { + /* + * Use the learned route set unless this is a CANCEL. For a CANCEL + * we have to send to the same destination as the original INVITE. + */ + if (p->route && sipmethod != SIP_CANCEL) { set_destination(p, p->route->hop); add_route(req, is_strict ? p->route->next : p->route); } @@ -14632,8 +14636,9 @@ static void list_route(struct sip_route *route) } } -/*! \brief Build route list from Record-Route header */ -static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards) +/*! \brief Build route list from Record-Route header + \param resp the SIP response code or 0 for a request */ +static void build_route(struct sip_pvt *p, struct sip_request *req, int backwards, int resp) { struct sip_route *thishop, *head, *tail; int start = 0; @@ -14651,8 +14656,11 @@ static void build_route(struct sip_pvt *p, struct sip_request *req, int backward p->route = NULL; } - /* We only want to create the route set the first time this is called */ - p->route_persistent = 1; + /* We only want to create the route set the first time this is called except + it is called from a provisional response.*/ + if ((resp < 100) || (resp > 199)) { + p->route_persistent = 1; + } /* Build a tailq, then assign it to p->route when done. * If backwards, we add entries from the head so they end up @@ -20775,7 +20783,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest * */ parse_ok_contact(p, req); if (!reinvite) { - build_route(p, req, 1); + build_route(p, req, 1, resp); } if (!req->ignore && p->owner) { if (get_rpid(p, req)) { @@ -20826,7 +20834,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest * */ parse_ok_contact(p, req); if (!reinvite) { - build_route(p, req, 1); + build_route(p, req, 1, resp); } if (!req->ignore && p->owner) { struct ast_party_redirecting redirecting; @@ -20853,7 +20861,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest * */ parse_ok_contact(p, req); if (!reinvite) { - build_route(p, req, 1); + build_route(p, req, 1, resp); } if (!req->ignore && p->owner) { if (get_rpid(p, req)) { @@ -20955,7 +20963,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest parse_ok_contact(p, req); /* Save Record-Route for any later requests we make on this dialogue */ if (!reinvite) { - build_route(p, req, 1); + build_route(p, req, 1, resp); } if(set_address_from_contact(p)) { @@ -23530,7 +23538,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int *recount = 1; /* Save Record-Route for any later requests we make on this dialogue */ - build_route(p, req, 0); + build_route(p, req, 0, 0); if (c) { ast_party_redirecting_init(&redirecting); @@ -25567,7 +25575,7 @@ static int handle_request_subscribe(struct sip_pvt *p, struct sip_request *req, if (sipdebug) ast_debug(4, "Initializing initreq for method %s - callid %s\n", sip_methods[req->method].text, p->callid); check_via(p, req); - build_route(p, req, 0); + build_route(p, req, 0, 0); } else if (req->debug && req->ignore) ast_verbose("Ignoring this SUBSCRIBE request\n"); |