summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c34
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");