diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 9500d2251ed7a978048f6a8e1f81e1d4c89ec345..d28dfcd0f6dc0ea2b2e59fc7a7ae35079d7e24b0 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -9701,6 +9701,46 @@ static int get_also_info(struct sip_pvt *p, struct sip_request *oreq)
 
 	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, use them as 'p->ourip' (see RFC 3581 for rport,
+ * and RFC 3261 for received).
+ * Using these two fields SIP can produce the correct
+ * address and port in the SIP headers without the need for STUN.
+ * The address part is also reused for the media sessions.
+ * Note that ast_sip_ouraddrfor() still rewrites p->ourip
+ * if you specify externip/seternaddr/stunaddr.
+ */
+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 */
+	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);
+			/* XXX add error checking */
+			p->ourip.sin_port = ntohs(port);
+		} else if (!strncmp(cur, "received=", 9)) {
+			if (ast_parse_arg(cur+9, PARSE_INADDR, &p->ourip))
+				;	/* XXX add 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)
 {
@@ -13332,6 +13372,7 @@ static void handle_response(struct sip_pvt *p, int resp, char *rest, struct sip_
 		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