[svn-commits] file: branch 1.6.1 r165606 - in /branches/1.6.1: ./ channels/chan_sip.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Thu Dec 18 11:59:38 CST 2008


Author: file
Date: Thu Dec 18 11:59:37 2008
New Revision: 165606

URL: http://svn.digium.com/view/asterisk?view=rev&rev=165606
Log:
Merge in changes to return chan_sip to matching based on how it was previously done and how it is done in trunk. It will do name based for users and friends and IP based for peers.
(closes issue #14107)
Reported by: jsmith

Modified:
    branches/1.6.1/   (props changed)
    branches/1.6.1/channels/chan_sip.c

Propchange: branches/1.6.1/
------------------------------------------------------------------------------
Binary property 'trunk-merged' - no diff available.

Modified: branches/1.6.1/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/branches/1.6.1/channels/chan_sip.c?view=diff&rev=165606&r1=165605&r2=165606
==============================================================================
--- branches/1.6.1/channels/chan_sip.c (original)
+++ branches/1.6.1/channels/chan_sip.c Thu Dec 18 11:59:37 2008
@@ -208,6 +208,10 @@
 #endif
 
 #define	SIPBUFSIZE		512
+
+/* Arguments for find_peer */
+#define	FINDALLDEVICES	FALSE
+#define FINDONLYUSERS	TRUE
 
 #define XMIT_ERROR		-2
 
@@ -1690,15 +1694,18 @@
 {
 	struct sip_peer *peer = obj, *peer2 = arg;
 
-	if (peer->addr.sin_addr.s_addr != peer2->addr.sin_addr.s_addr)
+	if (peer->addr.sin_addr.s_addr != peer2->addr.sin_addr.s_addr) {
 		return 0;
+	}
 	
 	if (!ast_test_flag(&peer->flags[0], SIP_INSECURE_PORT) && !ast_test_flag(&peer2->flags[0], SIP_INSECURE_PORT)) {
-		if (peer->addr.sin_port == peer2->addr.sin_port)
+		if (peer->addr.sin_port == peer2->addr.sin_port) {
 			return CMP_MATCH | CMP_STOP;
-		else
+		} else {
 			return 0;
-	}
+		}
+	}
+
 	return CMP_MATCH | CMP_STOP;
 }
 
@@ -4080,6 +4087,31 @@
 	return peer;
 }
 
+struct peer_finding_info {
+	struct sip_peer tmp_peer;
+	int forcenamematch;
+};
+
+/* Function to assist finding peers by name only */
+static int find_by_name(void *obj, void *arg, int flags)
+{
+	struct sip_peer *search = obj;
+	struct peer_finding_info *pfi = arg;
+
+	/* Usernames in SIP uri's are case sensitive. Domains are not */
+	if (strcmp(search->name, pfi->tmp_peer.name)) {
+		return 0;
+	}
+
+	/* If we're only looking for name matches, we should avoid type=peer devices,
+	   since these should not match on any name-based search */
+	if (pfi->forcenamematch && search->onlymatchonip) {
+		return 0;
+	}
+
+	return CMP_MATCH | CMP_STOP;
+}
+
 /*! \brief Locate device by name or ip address 
  *	This is used on find matching device on name or ip/port.
 	If the device was declared as type=peer, we don't match on peer name on incoming INVITEs.
@@ -4090,12 +4122,13 @@
 static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch, int devstate_only)
 {
 	struct sip_peer *p = NULL;
-	struct sip_peer tmp_peer;
-	
+
 	if (peer) {
-		ast_copy_string(tmp_peer.name, peer, sizeof(tmp_peer.name));
-		p = ao2_t_find(peers, &tmp_peer, OBJ_POINTER, "ao2_find in peers table");
+		struct peer_finding_info pfi = { .forcenamematch = forcenamematch, };
+		ast_copy_string(pfi.tmp_peer.name, peer, sizeof(pfi.tmp_peer.name));
+		p = ao2_t_callback(peers, OBJ_POINTER, find_by_name, &pfi, "ao2_callback in peers table");
 	} else if (sin) { /* search by addr? */
+		struct sip_peer tmp_peer;
 		tmp_peer.addr.sin_addr.s_addr = sin->sin_addr.s_addr;
 		tmp_peer.addr.sin_port = sin->sin_port;
 		tmp_peer.flags[0].flags = 0;
@@ -4359,7 +4392,7 @@
 	dialog->sa.sin_family = AF_INET;
 	dialog->timer_t1 = global_t1; /* Default SIP retransmission timer T1 (RFC 3261) */
 	dialog->timer_b = global_timer_b; /* Default SIP transaction timer B (RFC 3261) */
-	peer = find_peer(peername, NULL, TRUE, TRUE, FALSE);
+	peer = find_peer(peername, NULL, TRUE, FINDALLDEVICES, FALSE);
 
 	if (peer) {
 		int res;
@@ -4714,7 +4747,7 @@
 	ast_copy_string(name, fup->username, sizeof(name));
 
 	/* Check the list of devices */
-	if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, TRUE, FALSE, FALSE) ) ) { /* Try to find peer */
+	if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, TRUE, FINDALLDEVICES, FALSE) ) ) { /* Try to find peer */
 		inuse = &p->inUse;
 		call_limit = &p->call_limit;
 		inringing = &p->inRinging;
@@ -10892,7 +10925,7 @@
 /*! \brief Change onhold state of a peer using a pvt structure */
 static void sip_peer_hold(struct sip_pvt *p, int hold)
 {
-	struct sip_peer *peer = find_peer(p->peername, NULL, 1, TRUE, FALSE);
+	struct sip_peer *peer = find_peer(p->peername, NULL, 1, FINDALLDEVICES, FALSE);
 
 	if (!peer)
 		return;
@@ -11041,7 +11074,7 @@
 
 	ast_string_field_set(p, exten, name);
 	build_contact(p);
-	peer = find_peer(name, NULL, TRUE, TRUE, FALSE);
+	peer = find_peer(name, NULL, TRUE, FINDALLDEVICES, FALSE);
 	if (!(peer && ast_apply_ha(peer->ha, sin))) {
 		/* Peer fails ACL check */
 		if (peer) {
@@ -11912,7 +11945,7 @@
 	}
 }
 
-/*! \brief Validate peer authentication */
+/*! \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,
 	struct sip_peer **authpeer,
@@ -11923,10 +11956,20 @@
 	int debug=sip_debug_test_addr(sin);
 	struct sip_peer *peer;
 
-	/* For subscribes, match on device name only; for other methods,
-	 * match on IP address-port of the incoming request.
-	 */
-	peer = (sipmethod == SIP_SUBSCRIBE) ? find_peer(of, NULL, TRUE, FALSE, FALSE) : find_peer(NULL, &p->recv, TRUE, FALSE, FALSE);
+	if (sipmethod == SIP_SUBSCRIBE) {
+		/* For subscribes, match on device name only; for other methods,
+	 	* match on IP address-port of the incoming request.
+	 	*/
+		peer = find_peer(of, NULL, TRUE, FINDALLDEVICES, FALSE);
+	} else {
+		/* First find devices based on username (avoid all type=peer's) */
+		peer = find_peer(of, NULL, TRUE, FINDONLYUSERS, FALSE);
+
+		/* Then find devices based on IP */
+		if (!peer) {
+			peer = find_peer(NULL, &p->recv, TRUE, FINDALLDEVICES, FALSE);
+		}
+	}
 
 	if (!peer) {
 		if (debug)
@@ -13175,7 +13218,7 @@
 		return CLI_SHOWUSAGE;
 
 	load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
-	if ((peer = find_peer(argv[3], NULL, load_realtime, FALSE, FALSE))) {
+	if ((peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE))) {
 		sip_poke_peer(peer, 1);
 		unref_peer(peer, "qualify: done with peer");
 	} else if (type == 0) {
@@ -13257,7 +13300,7 @@
 		return CLI_SHOWUSAGE;
 
 	load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
-	peer = find_peer(argv[3], NULL, load_realtime, TRUE, FALSE);
+	peer = find_peer(argv[3], NULL, load_realtime, FINDALLDEVICES, FALSE);
 	if (s) { 	/* Manager */
 		if (peer) {
 			const char *id = astman_get_header(m, "ActionID");
@@ -13578,7 +13621,7 @@
 	if (a->argc != 3)
 		return CLI_SHOWUSAGE;
 	
-	if ((peer = find_peer(a->argv[2], NULL, load_realtime, TRUE, TRUE))) {
+	if ((peer = find_peer(a->argv[2], NULL, load_realtime, FINDALLDEVICES, TRUE))) {
 		if (peer->expire > 0) {
 			expire_register(ref_peer(peer, "ref for expire_register"));
 			ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
@@ -14550,7 +14593,7 @@
 /*! \brief  Turn on SIP debugging for a given peer */
 static char *sip_do_debug_peer(int fd, char *arg)
 {
-	struct sip_peer *peer = find_peer(arg, NULL, TRUE, TRUE, FALSE);
+	struct sip_peer *peer = find_peer(arg, NULL, TRUE, FINDALLDEVICES, FALSE);
 	if (!peer)
 		ast_cli(fd, "No such peer '%s'\n", arg);
 	else if (peer->addr.sin_addr.s_addr == 0)
@@ -15046,7 +15089,7 @@
 	else
 		colname = "ip";
 
-	if (!(peer = find_peer(data, NULL, TRUE, TRUE, FALSE)))
+	if (!(peer = find_peer(data, NULL, TRUE, FINDALLDEVICES, FALSE)))
 		return -1;
 
 	if (!strcasecmp(colname, "ip")) {
@@ -17374,9 +17417,12 @@
 			sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
 			return 0;
 		} else {
-			/* This is a spiral. What we need to do is to just change the outgoing INVITE
+			/*! This is a spiral. What we need to do is to just change the outgoing INVITE
 			 * so that it now routes to the new Request URI. Since we created the INVITE ourselves
 			 * that should be all we need to do.
+			 * 
+ 			 * \todo XXX This needs to be reviewed.  YOu don't change the request URI really, you route the packet
+			 * correctly instead...
 			 */
 			char *uri = ast_strdupa(req->rlPart2);
 			char *at = strchr(uri, '@');
@@ -20111,7 +20157,7 @@
 		if (p->stimer->st_cached_max_se) {
 			return p->stimer->st_cached_max_se;
 		} else if (p->peername) {
-			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
+			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
 			if (pp) {
 				p->stimer->st_cached_max_se = pp->stimer.st_max_se;
 				unref_peer(pp, "unref peer pointer from find_peer call in st_get_se");
@@ -20124,7 +20170,7 @@
 		if (p->stimer->st_cached_min_se) {
 			return p->stimer->st_cached_min_se;
 		} else if (p->peername) {
-			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
+			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
 			if (pp) {
 				p->stimer->st_cached_min_se = pp->stimer.st_min_se;
 				unref_peer(pp, "unref peer pointer from find_peer call in st_get_se (2)");
@@ -20146,7 +20192,7 @@
 		return p->stimer->st_cached_ref;
 
 	if (p->peername) {
-		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
+		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
 		if (pp) {
 			p->stimer->st_cached_ref = pp->stimer.st_ref;
 			unref_peer(pp, "unref peer pointer from find_peer call in st_get_refresher");
@@ -20171,7 +20217,7 @@
 		return p->stimer->st_cached_mode;
 
 	if (p->peername) {
-		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, FALSE);
+		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, FINDALLDEVICES, FALSE);
 		if (pp) {
 			p->stimer->st_cached_mode = pp->stimer.st_mode_oper;
 			unref_peer(pp, "unref peer pointer from find_peer call in st_get_mode");
@@ -20358,7 +20404,7 @@
 	 * load it BACK into memory, thus defeating the point of trying to clear dead
 	 * hosts out of memory.
 	 */
-	if ((p = find_peer(host, NULL, FALSE, TRUE, TRUE))) {
+	if ((p = find_peer(host, NULL, FALSE, FINDALLDEVICES, TRUE))) {
 		if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
 			/* we have an address for the peer */
 		
@@ -22147,7 +22193,7 @@
 			if (!strcasecmp(utype, "user")) {
 				is_peer = 1;
 			} else if (!strcasecmp(utype, "friend")) {
-				is_peer = 2;
+				is_peer = 1;
 			} else if (!strcasecmp(utype, "peer"))
 				is_peer = 2;
 			else {




More information about the svn-commits mailing list