[asterisk-commits] rizzo: branch rizzo/astobj2 r77166 - /team/rizzo/astobj2/channels/chan_sip.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 25 17:11:42 CDT 2007


Author: rizzo
Date: Wed Jul 25 17:11:42 2007
New Revision: 77166

URL: http://svn.digium.com/view/asterisk?view=rev&rev=77166
Log:
save the bits to honor the received= and rport= options in
Via: headers.

This is definitely a trunk candidate, and possibly even one for 1.4
and 1.2 given that 1. the change is totally unintrusive, and
2. not honoring these options could well be considered a bug in asterisk,
and a big source of grief for users.

With this change you can pretty much forget about STUN and other
unreliable tricks for NAT traversal, at least for the SIP socket,
even in the case of a "symmetric nat", which STUN cannot handle.


Modified:
    team/rizzo/astobj2/channels/chan_sip.c

Modified: team/rizzo/astobj2/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/astobj2/channels/chan_sip.c?view=diff&rev=77166&r1=77165&r2=77166
==============================================================================
--- team/rizzo/astobj2/channels/chan_sip.c (original)
+++ team/rizzo/astobj2/channels/chan_sip.c Wed Jul 25 17:11:42 2007
@@ -9898,6 +9898,44 @@
 
 	return -1;
 }
+
+/*! \brief check received= and rport= in a SIP response.
+ * If we get a response with received= and/or rport= in the Via:
+ * line, we can use them as 'ourip' (see RFC 3581 for rport,
+ * and RFC 3261 for received (?)
+ */
+static void check_via_response(struct sip_pvt *p, struct sip_request *req)
+{
+	char via[256];
+	char *cur, *opts;
+
+	ast_copy_string(via, get_header(req, "Via"), sizeof(via));
+
+	/* Work on the leftmost value of the topmost Via header */
+	opts = strchr(via, ',');
+	if (opts)
+		*opts = '\0';
+
+	/* parse all relevant options */
+	ast_log(LOG_WARNING, "doing Via: %s\n", via);
+	opts = strchr(via, ';');
+	if (!opts)
+		return;	/* no options to parse */
+	*opts++ = '\0';
+	while ( (cur = strsep(&opts, ";")) ) {
+		if (!strncmp(cur, "rport=", 6)) {
+			int port = strtol(cur+6, NULL, 10);
+			ast_log(LOG_WARNING, "found rport: %s\n", cur);
+			/* XXX error checking */
+			p->ourip.sin_port = ntohs(port);
+		} else if (!strncmp(cur, "received=", 9)) {
+			ast_log(LOG_WARNING, "found received: %s\n", cur);
+			if (ast_parse_arg(cur+9, PARSE_INADDR, &p->ourip))
+				;	/* XXX error checking */
+		}
+	}
+}
+
 /*! \brief check Via: header for hostname, port and rport request/answer */
 static void check_via(struct sip_pvt *p, struct sip_request *req)
 {
@@ -13598,6 +13636,7 @@
 		gettag(req, "To", tag, sizeof(tag));
 		ast_string_field_set(p, theirtag, tag);
 	}
+	check_via_response(p, req);
 	if (p->relatedpeer && p->method == SIP_OPTIONS) {
 		/* We don't really care what the response is, just that it replied back. 
 		   Well, as long as it's not a 100 response...  since we might




More information about the asterisk-commits mailing list