[svn-commits] tilghman: trunk r138260 - in /trunk: ./ channels/ configs/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Fri Aug 15 17:54:57 CDT 2008


Author: tilghman
Date: Fri Aug 15 17:54:57 2008
New Revision: 138260

URL: http://svn.digium.com/view/asterisk?view=rev&rev=138260
Log:
Merged revisions 138258 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r138258 | tilghman | 2008-08-15 17:33:42 -0500 (Fri, 15 Aug 2008) | 8 lines

More fixes for realtime peers.
(closes issue #12921)
 Reported by: Nuitari
 Patches: 
       20080804__bug12921.diff.txt uploaded by Corydon76 (license 14)
       20080815__bug12921.diff.txt uploaded by Corydon76 (license 14)
 Tested by: Corydon76

........

Modified:
    trunk/   (props changed)
    trunk/channels/chan_sip.c
    trunk/configs/sip.conf.sample

Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=138260&r1=138259&r2=138260
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Fri Aug 15 17:54:57 2008
@@ -2063,7 +2063,7 @@
 static void set_peer_defaults(struct sip_peer *peer);
 static struct sip_peer *temp_peer(const char *name);
 static void register_peer_exten(struct sip_peer *peer, int onoff);
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch);
+static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch, int devstate_only);
 static int sip_poke_peer_s(const void *data);
 static enum parse_register_result parse_register_contact(struct sip_pvt *pvt, struct sip_peer *p, struct sip_request *req);
 static void reg_source_db(struct sip_peer *peer);
@@ -2076,7 +2076,7 @@
 static void update_peer(struct sip_peer *p, int expire);
 static struct ast_variable *get_insecure_variable_from_config(struct ast_config *config);
 static const char *get_name_from_variable(struct ast_variable *var, const char *newpeername);
-static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin);
+static struct sip_peer *realtime_peer(const char *peername, struct sockaddr_in *sin, int devstate_only);
 static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 /*--- Internal UA client handling (outbound registrations) */
@@ -3856,7 +3856,7 @@
  * This returns a pointer to a peer and because we use build_peer, we can rest
  * assured that the refcount is bumped.
 */
-static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin)
+static struct sip_peer *realtime_peer(const char *newpeername, struct sockaddr_in *sin, int devstate_only)
 {
 	struct sip_peer *peer;
 	struct ast_variable *var = NULL;
@@ -4015,7 +4015,7 @@
 
 	ast_debug(3, "-REALTIME- loading peer from database to memory. Name: %s. Peer objects: %d\n", peer->name, rpeerobjs);
 
-	if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
+	if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && !devstate_only) {
 		/* Cache peer */
 		ast_copy_flags(&peer->flags[1], &global_flags[1], SIP_PAGE2_RTAUTOCLEAR|SIP_PAGE2_RTCACHEFRIENDS);
 		if (ast_test_flag(&global_flags[1], SIP_PAGE2_RTAUTOCLEAR)) {
@@ -4046,7 +4046,7 @@
 	\note Avoid using this function in new functions if there is a way to avoid it, i
 	since it might cause a database lookup.
 */
-static struct sip_peer *find_peer(const char *peer, struct sockaddr_in *sin, int realtime, int forcenamematch)
+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;
@@ -4068,8 +4068,8 @@
 		}
 	}
 
-	if (!p && realtime)
-		p = realtime_peer(peer, sin);
+	if (!p && (realtime || devstate_only))
+		p = realtime_peer(peer, sin, devstate_only);
 
 	return p;
 }
@@ -4318,7 +4318,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);
+	peer = find_peer(peername, NULL, TRUE, TRUE, FALSE);
 
 	if (peer) {
 		int res;
@@ -4664,7 +4664,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) ) ) { /* Try to find peer */
+	if ( (p = find_peer(ast_strlen_zero(fup->peername) ? name : fup->peername, NULL, TRUE, FALSE, FALSE) ) ) { /* Try to find peer */
 		inuse = &p->inUse;
 		call_limit = &p->call_limit;
 		inringing = &p->inRinging;
@@ -10184,8 +10184,7 @@
 	return TRUE;		
 }
 
-/*! \brief Change the other partys IP address based on given contact */
-static int set_address_from_contact(struct sip_pvt *pvt)
+static int __set_address_from_contact(const char *fullcontact, struct sockaddr_in *sin, int tcp)
 {
 	struct hostent *hp;
 	struct ast_hostent ahp;
@@ -10195,22 +10194,14 @@
 	char contact2_buf[256];
 	char *contact, *contact2;
 
-	if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
-		/* NAT: Don't trust the contact field.  Just use what they came to us
-		   with. */
-		pvt->sa = pvt->recv;
-		return 0;
-	}
-
 	/* Work on a copy */
-	ast_copy_string(contact_buf, pvt->fullcontact, sizeof(contact_buf));
-	ast_copy_string(contact2_buf, pvt->fullcontact, sizeof(contact2_buf));
+	ast_copy_string(contact_buf, fullcontact, sizeof(contact_buf));
+	ast_copy_string(contact2_buf, fullcontact, sizeof(contact2_buf));
 	contact = contact_buf;
 	contact2 = contact2_buf;
 
 	/* We have only the part in <brackets> here so we just need to parse a SIP URI.*/
-
-	if (pvt->socket.type == SIP_TRANSPORT_TLS) {
+	if (tcp) {
 		if (parse_uri(contact, "sips:", &contact, NULL, &host, &pt, NULL)) {
 			if (parse_uri(contact2, "sip:", &contact, NULL, &host, &pt, NULL))
 				ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
@@ -10220,10 +10211,6 @@
 		if (parse_uri(contact, "sip:", &contact, NULL, &host, &pt, NULL))
 			ast_log(LOG_NOTICE, "'%s' is not a valid SIP contact (missing sip:) trying to use anyway\n", contact);
 		port = !ast_strlen_zero(pt) ? atoi(pt) : STANDARD_SIP_PORT;
-	}
-
-	if (sip_debug_test_pvt(pvt)) {
-		ast_verbose("--- set_address_from_contact host '%s'\n", host);
 	}
 
 	/* XXX This could block for a long time XXX */
@@ -10233,11 +10220,24 @@
 		ast_log(LOG_WARNING, "Invalid host name in Contact: (can't resolve in DNS) : '%s'\n", host);
 		return -1;
 	}
-	pvt->sa.sin_family = AF_INET;
-	memcpy(&pvt->sa.sin_addr, hp->h_addr, sizeof(pvt->sa.sin_addr));
-	pvt->sa.sin_port = htons(port);
+	sin->sin_family = AF_INET;
+	memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
+	sin->sin_port = htons(port);
 
 	return 0;
+}
+
+/*! \brief Change the other partys IP address based on given contact */
+static int set_address_from_contact(struct sip_pvt *pvt)
+{
+	if (ast_test_flag(&pvt->flags[0], SIP_NAT_ROUTE)) {
+		/* NAT: Don't trust the contact field.  Just use what they came to us
+		   with. */
+		pvt->sa = pvt->recv;
+		return 0;
+	}
+
+	return __set_address_from_contact(pvt->fullcontact, &pvt->sa, pvt->socket.type == SIP_TRANSPORT_TLS ? 1 : 0);
 }
 
 
@@ -10693,7 +10693,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);
+	struct sip_peer *peer = find_peer(p->peername, NULL, 1, TRUE, FALSE);
 
 	if (!peer)
 		return;
@@ -10842,7 +10842,7 @@
 
 	ast_string_field_set(p, exten, name);
 	build_contact(p);
-	peer = find_peer(name, NULL, TRUE, TRUE);
+	peer = find_peer(name, NULL, TRUE, TRUE, FALSE);
 	if (!(peer && ast_apply_ha(peer->ha, sin))) {
 		/* Peer fails ACL check */
 		if (peer) {
@@ -11718,11 +11718,11 @@
 	 * match on IP address-port of the incoming request.
 	 */
 	/* First find device on name */
-	peer = find_peer(of, NULL, TRUE, FALSE);
+	peer = find_peer(of, NULL, TRUE, FALSE, FALSE);
 
 	/* If not found, then find device on IP (if it's not a SUBSCRIBE) */
 	if (!peer && sipmethod != SIP_SUBSCRIBE) {
-		peer = find_peer(NULL, &p->recv, TRUE, FALSE);
+		peer = find_peer(NULL, &p->recv, TRUE, FALSE, FALSE);
 	}
 
 	if (!peer) {
@@ -12970,7 +12970,7 @@
 		return CLI_SHOWUSAGE;
 
 	load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
-	if ((peer = find_peer(argv[3], NULL, load_realtime, FALSE))) {
+	if ((peer = find_peer(argv[3], NULL, load_realtime, FALSE, FALSE))) {
 		sip_poke_peer(peer, 1);
 		unref_peer(peer, "qualify: done with peer");
 	} else if (type == 0) {
@@ -13052,7 +13052,7 @@
 		return CLI_SHOWUSAGE;
 
 	load_realtime = (argc == 5 && !strcmp(argv[4], "load")) ? TRUE : FALSE;
-	peer = find_peer(argv[3], NULL, load_realtime, TRUE);
+	peer = find_peer(argv[3], NULL, load_realtime, TRUE, FALSE);
 	if (s) { 	/* Manager */
 		if (peer) {
 			const char *id = astman_get_header(m, "ActionID");
@@ -13374,7 +13374,7 @@
 	if (a->argc != 3)
 		return CLI_SHOWUSAGE;
 	
-	if ((peer = find_peer(a->argv[2], NULL, load_realtime, TRUE))) {
+	if ((peer = find_peer(a->argv[2], NULL, load_realtime, TRUE, TRUE))) {
 		if (peer->expire > 0) {
 			expire_register(peer);
 			ast_cli(a->fd, "Unregistered peer \'%s\'\n\n", a->argv[2]);
@@ -14346,7 +14346,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);
+	struct sip_peer *peer = find_peer(arg, NULL, TRUE, TRUE, FALSE);
 	if (!peer)
 		ast_cli(fd, "No such peer '%s'\n", arg);
 	else if (peer->addr.sin_addr.s_addr == 0)
@@ -14842,7 +14842,7 @@
 	else
 		colname = "ip";
 
-	if (!(peer = find_peer(data, NULL, TRUE, TRUE)))
+	if (!(peer = find_peer(data, NULL, TRUE, TRUE, FALSE)))
 		return -1;
 
 	if (!strcasecmp(colname, "ip")) {
@@ -19823,7 +19823,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);
+			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, 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");
@@ -19836,7 +19836,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);
+			struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, 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)");
@@ -19858,7 +19858,7 @@
 		return p->stimer->st_cached_ref;
 
 	if (p->peername) {
-		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE);
+		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, 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");
@@ -19883,7 +19883,7 @@
 		return p->stimer->st_cached_mode;
 
 	if (p->peername) {
-		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE);
+		struct sip_peer *pp = find_peer(p->peername, NULL, TRUE, TRUE, 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");
@@ -20055,7 +20055,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))) {
+	if ((p = find_peer(host, NULL, FALSE, TRUE, TRUE))) {
 		if (p->addr.sin_addr.s_addr || p->defaddr.sin_addr.s_addr) {
 			/* we have an address for the peer */
 		
@@ -21045,6 +21045,14 @@
 	if (fullcontact->used > 0) {
 		ast_copy_string(peer->fullcontact, fullcontact->str, sizeof(peer->fullcontact));
 		peer->rt_fromcontact = TRUE;
+		/* We have a hostname in the fullcontact, but if we don't have an
+		 * address listed on the entry (or if it's 'dynamic'), then we need to
+		 * parse the entry to obtain the IP address, so a dynamic host can be
+		 * contacted immediately after reload (as opposed to waiting for it to
+		 * register once again). */
+		/* XXX May need to revisit the final argument; does the realtime DB store whether
+		 * the original contact was over TLS or not? XXX */
+		__set_address_from_contact(fullcontact->str, &peer->addr, 0);
 	}
 
 	if (srvlookup && peer->dnsmgr == NULL) {

Modified: trunk/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/trunk/configs/sip.conf.sample?view=diff&rev=138260&r1=138259&r2=138260
==============================================================================
--- trunk/configs/sip.conf.sample (original)
+++ trunk/configs/sip.conf.sample Fri Aug 15 17:54:57 2008
@@ -576,7 +576,9 @@
                                 ; If set to yes, when a SIP UA registers successfully, the ip address,
                                 ; the origination port, the registration period, and the username of
                                 ; the UA will be set to database via realtime. 
-                                ; If not present, defaults to 'yes'.
+                                ; If not present, defaults to 'yes'. Note: realtime peers will
+                                ; probably not function across reloads in the way that you expect, if
+                                ; you turn this option off.
 ;rtautoclear=yes                ; Auto-Expire friends created on the fly on the same schedule
                                 ; as if it had just registered? (yes|no|<seconds>)
                                 ; If set to yes, when the registration expires, the friend will




More information about the svn-commits mailing list