[asterisk-dev] [Code Review] Explicit context set in SIP peer overridden by default domain context

Philip A. Prindeville philipp_subx at redfish-solutions.com
Thu Apr 8 22:46:53 CDT 2010


Summary
--------

Having inbound SIP 'guest' calls associated to a default context is
handy, especially when multi-tenancy or hosting multiple domains is
being done.

However, the code as written will clobber an explicitly configured
context associated with a peer if a domain-list is configured.

This is counter-intuitive, since (a) explicit configuration should
always trump default or implicit config, and (b) puts all internal
domain-bound SIP handsets in the same context as guest callers, making
it hard to apply a restricted dialplan to guest callers.


The Fix
-------

Only override the context if (1) it hasn't been explicitly set and (2)
we're not associated with a specific peer.

(Thanks, Mark!)

Testing
--------

Running patched 1.6.2.6 on our production network.  Seems to work fine.


Diffs
-----

--- asterisk-1.6.2/channels/chan_sip.c.orig	2010-04-08 17:42:21.000000000 -0600
+++ asterisk-1.6.2/channels/chan_sip.c	2010-04-08 21:33:50.000000000 -0600
@@ -1372,6 +1372,8 @@ struct sip_auth {
 /* realtime flags */
 #define SIP_PAGE2_RTCACHEFRIENDS	(1 << 0)	/*!< GP: Should we keep RT objects in memory for extended time? */
 #define SIP_PAGE2_RTAUTOCLEAR		(1 << 2)	/*!< GP: Should we clean memory from peers after expiry? */
+#define SIP_PAGE2_HAVEPEER		(1 << 3)	/*!< Are we associated with a configured peer context? */
+
 /* Space for addition of other realtime flags in the future */
 #define SIP_PAGE2_STATECHANGEQUEUE	(1 << 9)	/*!< D: Unsent state pending change exists */

@@ -5269,6 +5271,8 @@ static int create_addr(struct sip_pvt *d
 		if (newdialog) {
 			set_socket_transport(&dialog->socket, 0);
 		}
+		ast_set_flag(&dialog->flags[1], SIP_PAGE2_HAVEPEER);
+
 		res = create_addr_from_peer(dialog, peer);
 		if (!ast_strlen_zero(port)) {
 			if ((portno = atoi(port))) {
@@ -13365,8 +13369,9 @@ static int get_destination(struct sip_pv
 				return -2;
 			}
 		}
-		/* If we have a context defined, overwrite the original context */
-		if (!ast_strlen_zero(domain_context))
+		/* If we don't have a peer (i.e. we're a guest call),
+		 * overwrite the original context */
+		if (!ast_test_flag(&p->flags[1], SIP_PAGE2_HAVEPEER) && !ast_strlen_zero(domain_context))
 			ast_string_field_set(p, context, domain_context);
 	}

@@ -13963,6 +13968,8 @@ static enum check_auth_result check_peer
 				of, ast_inet_ntoa(p->recv.sin_addr), ntohs(p->recv.sin_port));
 		return AUTH_DONT_KNOW;
 	}
+	ast_set_flag(&p->flags[1], SIP_PAGE2_HAVEPEER);
+
 	if (!ast_apply_ha(peer->ha, sin)) {
 		ast_debug(2, "Found peer '%s' for '%s', but fails host access\n", peer->name, of);
 		unref_peer(peer, "unref_peer: check_peer_ok: from find_peer call, early return of AUTH_ACL_FAILED");




More information about the asterisk-dev mailing list