[Asterisk-cvs] asterisk/channels chan_sip.c,1.591,1.592
markster at lists.digium.com
markster at lists.digium.com
Sat Dec 18 09:30:13 CST 2004
Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv18482/channels
Modified Files:
chan_sip.c
Log Message:
Merge olle's amazing ACK fix (bug #2687)
Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.591
retrieving revision 1.592
diff -u -d -r1.591 -r1.592
--- chan_sip.c 13 Dec 2004 15:26:26 -0000 1.591
+++ chan_sip.c 18 Dec 2004 14:26:24 -0000 1.592
@@ -315,6 +315,7 @@
char peername[256];
char authname[256]; /* Who we use for authentication */
char uri[256]; /* Original requested URI */
+ char okcontacturi[256]; /* URI from the 200 OK on INVITE */
char peersecret[256]; /* Password */
char peermd5secret[256];
char cid_num[256]; /* Caller*ID */
@@ -3133,9 +3134,15 @@
else /* Some implementations (e.g. Uniden UIP200) can't handle rport being in the message!! */
snprintf(p->via, sizeof(p->via), "SIP/2.0/UDP %s:%d;branch=z9hG4bK%08x", ast_inet_ntoa(iabuf, sizeof(iabuf), p->ourip), ourport, p->branch);
}
- if (!strcasecmp(msg, "CANCEL") || !strcasecmp(msg, "ACK")) {
- /* MUST use original URI */
- c = p->initreq.rlPart2;
+ if (!strcasecmp(msg, "CANCEL")) {
+ c = p->initreq.rlPart2; /* Use original URI */
+ } else if (!strcasecmp(msg, "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;
} else if (!ast_strlen_zero(p->uri)) {
c = p->uri;
} else {
@@ -4437,6 +4444,86 @@
}
}
+/*--- parse_ok_contact: Parse contact header for 200 OK on INVITE ---*/
+static int parse_ok_contact(struct sip_pvt *pvt, struct sip_request *req)
+{
+ char contact[250]= "";
+ char *c, *n, *pt;
+ int port;
+ struct hostent *hp;
+ struct ast_hostent ahp;
+ struct sockaddr_in oldsin;
+
+ /* Look for brackets */
+ strncpy(contact, get_header(req, "Contact"), sizeof(contact) - 1);
+ c = contact;
+
+ if ((n=strchr(c, '<'))) {
+ c = n + 1;
+ n = strchr(c, '>');
+ /* Lose the part after the > */
+ if (n)
+ *n = '\0';
+ }
+
+
+ /* Save full contact to call pvt for later bye or re-invite */
+ strncpy(pvt->fullcontact, c, sizeof(pvt->fullcontact) - 1);
+ snprintf(pvt->our_contact, sizeof(pvt->our_contact) - 1, "<%s>", c);
+
+
+ /* Make sure it's a SIP URL */
+ if (strncasecmp(c, "sip:", 4)) {
+ ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", c);
+ } else
+ c += 4;
+
+ strncpy(pvt->okcontacturi, c, sizeof(pvt->okcontacturi) - 1);
+
+ /* Ditch arguments */
+ n = strchr(c, ';');
+ if (n)
+ *n = '\0';
+
+ /* Grab host */
+ n = strchr(c, '@');
+ if (!n) {
+ n = c;
+ c = NULL;
+ } else {
+ *n = '\0';
+ n++;
+ }
+ pt = strchr(n, ':');
+ if (pt) {
+ *pt = '\0';
+ pt++;
+ port = atoi(pt);
+ } else
+ port = DEFAULT_SIP_PORT;
+
+ memcpy(&oldsin, &pvt->sa, sizeof(oldsin));
+
+ if (!(pvt->nat & SIP_NAT_ROUTE)) {
+ /* XXX This could block for a long time XXX */
+ /* We should only do this if it's a name, not an IP */
+ hp = ast_gethostbyname(n, &ahp);
+ if (!hp) {
+ ast_log(LOG_WARNING, "Invalid host '%s'\n", n);
+ return -1;
+ }
+ pvt->sa.sin_family = AF_INET;
+ memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
+ pvt->sa.sin_port = htons(port);
+ } else {
+ /* Don't trust the contact field. Just use what they came to us
+ with. */
+ memcpy(&pvt->sa, &pvt->recv, sizeof(pvt->sa));
+ }
+ return 0;
+}
+
+
/*--- parse_contact: Parse contact header and save registration ---*/
static int parse_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req)
{
@@ -6808,6 +6895,11 @@
sip_cancel_destroy(p);
if (!ast_strlen_zero(get_header(req, "Content-Type")))
process_sdp(p, req);
+
+ /* Parse contact header for continued conversation */
+ /* When we get 200 OK, we now which device (and IP) to contact for this call */
+ /* This is important when we have a SIP proxy between us and the phone */
+ parse_ok_contact(p, req);
/* Save Record-Route for any later requests we make on this dialogue */
build_route(p, req, 1);
if (p->owner) {
More information about the svn-commits
mailing list