Index: CHANGES
===================================================================
--- CHANGES	(revision 402874)
+++ CHANGES	(working copy)
@@ -9,6 +9,21 @@
 ======================================================================
 
 ------------------------------------------------------------------------------
+--- Functionality changes since Asterisk 1.8.24.0 ----------------------------
+------------------------------------------------------------------------------
+
+SIP Changes
+-----------
+    * Outbound proxy support has been fixed so the hostname provided for the "host"
+      configuration option is no longer resolved in DNS when an outbound proxy is
+      configured. As a result peer matching may be impacted depending on
+      configuration. To explicitly match using the IP address you must create
+      a different peer. The matching behavior has also been changed so if a
+      request is received and no peers or users are found using normal matching
+      logic a peer with the same username and an outbound proxy matching the
+      source address will be looked for and used if found.
+
+------------------------------------------------------------------------------
 --- Functionality changes since Asterisk 1.8.19.1 ----------------------------
 ------------------------------------------------------------------------------
 
Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(revision 402874)
+++ channels/chan_sip.c	(working copy)
@@ -5424,6 +5424,13 @@
 	if (peer) {
 		ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
 		p = ao2_t_callback_data(peers, OBJ_POINTER, find_by_name, &tmp_peer, &which_objects, "ao2_find in peers table");
+		if (p && addr) {
+			struct sip_proxy *outboundproxy = obproxy_get(NULL, p);
+			if (!outboundproxy || ast_sockaddr_cmp_addr(&outboundproxy->ip, addr)) {
+				ao2_ref(p, -1);
+				p = NULL;
+			}
+		}
 	} else if (addr) { /* search by addr? */
 		ast_sockaddr_copy(&tmp_peer.addr, addr);
 		tmp_peer.flags[0].flags = 0;
@@ -5630,8 +5637,10 @@
  */
 static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
 {
+	struct sip_proxy *outboundproxy;
 	struct sip_auth_container *credentials;
 
+
 	/* this checks that the dialog is contacting the peer on a valid
 	 * transport type based on the peers transport configuration,
 	 * otherwise, this function bails out */
@@ -5639,12 +5648,16 @@
 		return -1;
 	copy_socket_data(&dialog->socket, &peer->socket);
 
-	if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
+	if ((outboundproxy = obproxy_get(dialog, peer))) {
+		dialog->sa = outboundproxy->ip;
+		dialog->recv = dialog->sa;
+	} else if (!(ast_sockaddr_isnull(&peer->addr) && ast_sockaddr_isnull(&peer->defaddr)) &&
 	    (!peer->maxms || ((peer->lastms >= 0)  && (peer->lastms <= peer->maxms)))) {
 		dialog->sa = ast_sockaddr_isnull(&peer->addr) ? peer->defaddr : peer->addr;
 		dialog->recv = dialog->sa;
-	} else
+	} else {
 		return -1;
+	}
 
 	/* XXX TODO: get flags directly from peer only as they are needed using dialog->relatedpeer */
 	ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
@@ -5841,6 +5854,10 @@
 	if (addr) {
 		/* This address should be updated using dnsmgr */
 		ast_sockaddr_copy(&dialog->sa, addr);
+	} else if (dialog->outboundproxy) {
+		dialog->sa = dialog->outboundproxy->ip;
+		dialog->recv = dialog->sa;
+		ast_string_field_set(dialog, tohost, peername);
 	} else {
 
 		/* Let's see if we can find the host in DNS. First try DNS SRV records,
@@ -16622,6 +16639,11 @@
 		if (!peer) {
 			peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
 		}
+
+		/* Then find based on user and outbound proxy */
+		if (!peer) {
+			peer = find_peer(of, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
+		}
 	}
 
 	if (!peer) {
@@ -28617,7 +28639,9 @@
 		}
 	}
 
-	if (srvlookup && peer->dnsmgr == NULL) {
+	if (srvlookup && obproxy_get(NULL, peer)) {
+		ast_string_field_set(peer, tohost, srvlookup);
+	} else if (srvlookup && peer->dnsmgr == NULL) {
 		char transport[MAXHOSTNAMELEN];
 		char _srvlookup[MAXHOSTNAMELEN];
 		char *params;
