Index: channels/chan_sip.c
===================================================================
--- channels/chan_sip.c	(revision 274242)
+++ channels/chan_sip.c	(working copy)
@@ -14171,6 +14171,20 @@
 	}
 }
 
+static int peer_match_callbackextension_cb(void *obj, void *arg, void *data, int flags)
+{
+	struct sip_peer *peer = arg;
+	struct sip_peer *peer2 = obj;
+	char *callback = data;
+	if ((peer->addr.sin_addr.s_addr == peer2->addr.sin_addr.s_addr) &&
+		(peer->addr.sin_port == peer2->addr.sin_port) &&
+		!(strcasecmp(callback, peer2->callback))) {
+		return CMP_MATCH | CMP_STOP;
+	}
+
+	return 0;
+}
+
 /*! \brief Validate device authentication */
 static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
 	struct sip_request *req, int sipmethod, struct sockaddr_in *sin,
@@ -14191,8 +14205,17 @@
 		peer = find_peer(of, NULL, TRUE, FINDUSERS, FALSE, 0);
 
 		/* Then find devices based on IP */
-		if (!peer) {
-			peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type);
+		if (!peer && (peer = find_peer(NULL, &p->recv, TRUE, FINDPEERS, FALSE, p->socket.type))) {
+			char *uri_tmp, *callback = NULL, *dummy, *domain;
+			uri_tmp = ast_strdupa(uri2);
+			parse_uri(uri_tmp, "sip:,sips:", &callback, &dummy, &domain, &dummy, NULL);
+			if (!ast_strlen_zero(callback) && strcasecmp(callback, peer->callback)) {
+				struct sip_peer *peer2;
+				if ((peer2 = ao2_t_callback_data(peers_by_ip, OBJ_POINTER, peer_match_callbackextension_cb, peer, callback, "ao2_find in peers_by_ip table, matching callback"))) {
+					unref_peer(peer, "check_peer_ok: unref_peer: new peer with better matching callback extension found, tossing this one");
+					peer = peer2;
+				}
+			}
 		}
 	}
 
@@ -25013,6 +25036,7 @@
 	ast_string_field_set(peer, fromdomain, "");
 	ast_string_field_set(peer, fromuser, "");
 	ast_string_field_set(peer, regexten, "");
+	ast_string_field_set(peer, callback, "");
 	peer->callgroup = 0;
 	peer->pickupgroup = 0;
 	peer->maxms = default_qualify;
@@ -25110,7 +25134,6 @@
 	time_t regseconds = 0;
 	struct ast_flags peerflags[3] = {{(0)}};
 	struct ast_flags mask[3] = {{(0)}};
-	char callback[256] = "";
 	struct sip_peer tmp_peer;
 	const char *srvlookup = NULL;
 	static int deprecation_warning = 1;
@@ -25374,7 +25397,7 @@
 			} else if (!strcasecmp(v->name, "regexten")) {
 				ast_string_field_set(peer, regexten, v->value);
 			} else if (!strcasecmp(v->name, "callbackextension")) {
-				ast_copy_string(callback, v->value, sizeof(callback));
+				ast_string_field_set(peer, callback, v->value);
 			} else if (!strcasecmp(v->name, "amaflags")) {
 				format = ast_cdr_amaflags2int(v->value);
 				if (format < 0) {
@@ -25716,9 +25739,9 @@
 
 	ast_free_ha(oldha);
 	ast_free_ha(olddirectmediaha);
-	if (!ast_strlen_zero(callback)) { /* build string from peer info */
+	if (!ast_strlen_zero(peer->callback)) { /* build string from peer info */
 		char *reg_string;
-		if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, callback) < 0) {
+		if (asprintf(&reg_string, "%s?%s:%s@%s/%s", peer->name, peer->username, !ast_strlen_zero(peer->remotesecret) ? peer->remotesecret : peer->secret, peer->tohost, peer->callback) < 0) {
 			ast_log(LOG_WARNING, "asprintf() failed: %s\n", strerror(errno));
 		} else if (reg_string) {
 			sip_register(reg_string, 0); /* XXX TODO: count in registry_count */
Index: channels/sip/include/sip.h
===================================================================
--- channels/sip/include/sip.h	(revision 274242)
+++ channels/sip/include/sip.h	(working copy)
@@ -1164,6 +1164,7 @@
 		AST_STRING_FIELD(useragent);    /*!<  User agent in SIP request (saved from registration) */
 		AST_STRING_FIELD(mwi_from);     /*!< Name to place in From header for outgoing NOTIFY requests */
 		AST_STRING_FIELD(engine);       /*!<  RTP Engine to use */
+		AST_STRING_FIELD(callback);	/*!<  Holds callbackextension if specified */
 		AST_STRING_FIELD(unsolicited_mailbox);  /*!< Mailbox to store received unsolicited MWI NOTIFY messages information in */
 		);
 	struct sip_socket socket;       /*!< Socket used for this peer */
