--- channels/chan_sip.c.orig 2009-02-02 11:34:58.000000000 +0100 +++ channels/chan_sip.c 2009-02-02 15:46:04.000000000 +0100 @@ -1828,6 +1828,7 @@ static int sip_refer_allocate(struct sip_pvt *p); static void ast_quiet_chan(struct ast_channel *chan); static int attempt_transfer(struct sip_dual *transferer, struct sip_dual *target); +static int sip_uri_cmp(const char *input1, const char *input2); /*! * \brief generic function for determining if a correct transport is being * used to contact a peer @@ -6070,6 +6071,12 @@ if (strcmp(totag, p->tag)) { found = FALSE; /* This is not our packet */ } + } else if (!totag[0]) { + if (sip_uri_cmp(p->initreq.rlPart2, req->rlPart2)) { + found = FALSE; + if (option_debug > 2) + ast_log(LOG_DEBUG, "Test for Difference #1: Res=1 RURI=%s, new RURI=%s\n", p->initreq.rlPart2, req->rlPart2); + } } if (!found) ast_debug(5, "= Being pedantic: This is not our match on request: Call ID: %s Ourtag Totag %s Method %s\n", p->callid, totag, sip_methods[req->method].text); @@ -16757,9 +16764,12 @@ being able to call yourself */ /* If pedantic is on, we need to check the tags. If they're different, this is in fact a forked call through a SIP proxy somewhere. */ - int different; + int different = 0; if (pedanticsipchecking) different = sip_uri_cmp(p->initreq.rlPart2, req->rlPart2); + if (option_debug > 2) { + ast_log(LOG_DEBUG, "Test for Difference #2: Res=%d RURI=%s, new RURI=%s\n", different, p->initreq.rlPart2, req->rlPart2); + } else different = strcmp(p->initreq.rlPart2, req->rlPart2); if (!different) { @@ -16772,25 +16782,29 @@ * so that it now routes to the new Request URI. Since we created the INVITE ourselves * that should be all we need to do. */ + char *uri = ast_strdupa(req->rlPart2); char *at = strchr(uri, '@'); char *peerorhost; + struct sip_pkt *pkt = NULL; if (option_debug > 2) { ast_log(LOG_DEBUG, "Potential spiral detected. Original RURI was %s, new RURI is %s\n", p->initreq.rlPart2, req->rlPart2); } if (at) { *at = '\0'; } - /* Parse out "sip:" */ + // Parse out "sip:" if ((peerorhost = strchr(uri, ':'))) { *peerorhost++ = '\0'; } + create_addr(p, peerorhost); ast_string_field_set(p, theirtag, NULL); - /* Treat this as if there were a call forward instead... - */ - ast_string_field_set(p->owner, call_forward, peerorhost); - ast_queue_control(p->owner, AST_CONTROL_BUSY); - return 0; + for (pkt = p->packets; pkt; pkt = pkt->next) { + if (pkt->seqno == p->icseq && pkt->method == SIP_INVITE) { + AST_SCHED_DEL(sched, pkt->retransid); + } + } + return transmit_invite(p, SIP_INVITE, 1, 3); } }