[asterisk-commits] jpeeler: trunk r112207 - in /trunk: ./ channels/ include/asterisk/ main/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Apr 1 12:53:08 CDT 2008


Author: jpeeler
Date: Tue Apr  1 12:53:08 2008
New Revision: 112207

URL: http://svn.digium.com/view/asterisk?view=rev&rev=112207
Log:
This adds DNS SRV record support to DNS manager.  If there is a SRV record for a given domain, the hostname and port listed in the SRV record will be used. If no SRV record exists or a SRV lookup is not attempted, the DNS lookup on the specified domain will be performed as normal. Chan_sip has been modified to take advantage of the new SRV support.


Modified:
    trunk/CHANGES
    trunk/channels/chan_iax2.c
    trunk/channels/chan_sip.c
    trunk/channels/chan_zap.c
    trunk/include/asterisk/dnsmgr.h
    trunk/include/asterisk/slinfactory.h
    trunk/main/dnsmgr.c
    trunk/main/slinfactory.c

Modified: trunk/CHANGES
URL: http://svn.digium.com/view/asterisk/trunk/CHANGES?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Tue Apr  1 12:53:08 2008
@@ -194,7 +194,8 @@
      configs/sip.conf.sample for more information on how it is used.
   * Added a new configuration option "authfailureevents" that enables manager events when
     a peer can't authenticate properly. 
-  * Added DNS manager support to registrations not referencing a peer entry.
+  * Added DNS manager support to registrations, both for peers referencing
+    and not referencing a peer entry.
 
 IAX2 changes
 ------------
@@ -534,6 +535,11 @@
      not currently supported.
   * The ResetCDR application now has an 'e' option that re-enables a CDR if it
      has been disabled using the NoCDR application.
+
+DNS manager changes
+-------------------
+  * Addresses managed by DNS manager now will check to see if there is a DNS
+    SRV record for a given domain and will use that hostname/port if present.
 
 Miscellaneous New Modules
 -------------------------

Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Tue Apr  1 12:53:08 2008
@@ -6427,7 +6427,7 @@
 	if (!(reg = ast_calloc(1, sizeof(*reg))))
 		return -1;
 
-	if (ast_dnsmgr_lookup(hostname, &reg->addr.sin_addr, &reg->dnsmgr) < 0) {
+	if (ast_dnsmgr_lookup(hostname, &reg->addr, &reg->dnsmgr, NULL) < 0) {
 		ast_free(reg);
 		return -1;
 	}
@@ -10095,7 +10095,7 @@
 					/* Non-dynamic.  Make sure we become that way if we're not */
 					AST_SCHED_DEL(sched, peer->expire);
 					ast_clear_flag(peer, IAX_DYNAMIC);
-					if (ast_dnsmgr_lookup(v->value, &peer->addr.sin_addr, &peer->dnsmgr))
+					if (ast_dnsmgr_lookup(v->value, &peer->addr, &peer->dnsmgr, NULL))
 						return peer_unref(peer);
 					if (!peer->addr.sin_port)
 						peer->addr.sin_port = htons(IAX_DEFAULT_PORTNO);

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Tue Apr  1 12:53:08 2008
@@ -1960,7 +1960,7 @@
 static const struct sockaddr_in *sip_real_dst(const struct sip_pvt *p);
 static void build_via(struct sip_pvt *p);
 static int create_addr_from_peer(struct sip_pvt *r, struct sip_peer *peer);
-static int create_addr(struct sip_pvt *dialog, const char *opeer, struct in_addr *sin);
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin);
 static char *generate_random_string(char *buf, size_t size);
 static void build_callid_pvt(struct sip_pvt *pvt);
 static void build_callid_registry(struct sip_registry *reg, struct in_addr ourip, const char *fromdomain);
@@ -2529,7 +2529,7 @@
 	int res = 0;
 	const struct sockaddr_in *dst = sip_real_dst(p);
 
-	ast_debug(1, "Trying to put '%.10s' onto %s socket destined for %s\n", data->str, get_transport(p->socket.type), ast_inet_ntoa(dst->sin_addr));
+	ast_debug(1, "Trying to put '%.10s' onto %s socket destined for %s:%d\n", data->str, get_transport(p->socket.type), ast_inet_ntoa(dst->sin_addr), htons(dst->sin_port));
 
 	if (sip_prepare_socket(p) < 0)
 		return XMIT_ERROR;
@@ -4053,11 +4053,10 @@
 	
 	return 0;
 }
-
 /*! \brief create address structure from peer name
  *      Or, if peer not found, find it in the global DNS 
  *      returns TRUE (-1) on failure, FALSE on success */
-static int create_addr(struct sip_pvt *dialog, const char *opeer, struct in_addr *sin)
+static int create_addr(struct sip_pvt *dialog, const char *opeer, struct sockaddr_in *sin)
 {
 	struct hostent *hp;
 	struct ast_hostent ahp;
@@ -4096,26 +4095,32 @@
 	if (dialog->outboundproxy)
 		return 0;
 
-	/* Let's see if we can find the host in DNS. First try DNS SRV records,
-   	   then hostname lookup */
-	hostn = peername;
-	portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
-	if (global_srvlookup) {
-		char service[MAXHOSTNAMELEN];
-		int tportno;
-
-		snprintf(service, sizeof(service), "_sip._%s.%s", get_transport(dialog->socket.type), peername);
-		srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
-		if (srv_ret > 0) {
-			hostn = host;
-			portno = tportno;
-		}
-	}
-
-	if (sin && srv_ret <= 0) {
-		memcpy(&dialog->sa.sin_addr, sin, sizeof(dialog->sa.sin_addr));
-		ast_log(LOG_DEBUG, "IP lookup for hostname=%s, using dnsmgr resolved to %s...\n", peername, ast_inet_ntoa(*sin));
+	/* This address should be updated using dnsmgr */
+	if (sin) {
+		memcpy(&dialog->sa.sin_addr, &sin->sin_addr, sizeof(dialog->sa.sin_addr));
+		if (!sin->sin_port) {
+			portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
+		} else {
+			portno = ntohs(sin->sin_port);
+		}
 	} else {
+
+		/* Let's see if we can find the host in DNS. First try DNS SRV records,
+		   then hostname lookup */
+		hostn = peername;
+		portno = port ? atoi(port) : (dialog->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT;
+		if (global_srvlookup) {
+			char service[MAXHOSTNAMELEN];
+			int tportno;
+	
+			snprintf(service, sizeof(service), "_sip._%s.%s", get_transport(dialog->socket.type), peername);
+			srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, service);
+			if (srv_ret > 0) {
+				hostn = host;
+				portno = tportno;
+			}
+		}
+
 		hp = ast_gethostbyname(hostn, &ahp);
 		if (!hp) {
 			ast_log(LOG_WARNING, "No such host: %s\n", peername);
@@ -9221,8 +9226,10 @@
 	}
 
 	if (r->dnsmgr == NULL) {
-		ast_dnsmgr_lookup(r->hostname, &r->us.sin_addr, &r->dnsmgr);
-	} 
+		char transport[MAXHOSTNAMELEN];
+		snprintf(transport, sizeof(transport), "_sip._%s", get_transport(r->transport)); /* have to use static get_transport function */
+		ast_dnsmgr_lookup(r->hostname, &r->us, &r->dnsmgr, global_srvlookup ? transport : NULL);
+	}
 
 	if (r->call) {	/* We have a registration */
 		if (!auth) {
@@ -9250,8 +9257,12 @@
 
 		p->outboundproxy = obproxy_get(p, NULL);
 
+		/* Use port number specified if no SRV record was found */
+		if (!r->us.sin_port && r->portno)
+			r->us.sin_port = htons(r->portno);
+
 		/* Find address to hostname */
-		if (create_addr(p, r->hostname, &r->us.sin_addr)) {
+		if (create_addr(p, r->hostname, &r->us)) {
 			/* we have what we hope is a temporary network error,
 			 * probably DNS.  We need to reschedule a registration try */
 			sip_destroy(p);
@@ -9265,13 +9276,15 @@
 			r->regattempts++;
 			return 0;
 		}
+
 		/* Copy back Call-ID in case create_addr changed it */
 		ast_string_field_set(r, callid, p->callid);
-		if (r->portno) {
+		if (!r->dnsmgr && r->portno) {
 			p->sa.sin_port = htons(r->portno);
 			p->recv.sin_port = htons(r->portno);
-		} else 	/* Set registry port to the port set from the peer definition/srv or default */
+		} else {	/* Set registry port to the port set from the peer definition/srv or default */
 			r->portno = ntohs(p->sa.sin_port);
+		}
 		ast_set_flag(&p->flags[0], SIP_OUTGOING);	/* Registration is outgoing call */
 		r->call = dialog_ref(p);		/* Save pointer to SIP dialog */
 		p->registry = registry_addref(r);	/* Add pointer to registry in packet */
@@ -9298,6 +9311,7 @@
 		/* Set transport and port so the correct contact is built */
 		p->socket.type = r->transport;
 		p->socket.port = htons(r->portno);
+
 		/*
 		  check which address we should use in our contact header 
 		  based on whether the remote host is on the external or
@@ -20068,13 +20082,11 @@
 		}
 	}
 
-	if (srvlookup) {
-		if (ast_get_ip_or_srv(&peer->addr, srvlookup, 
-								global_srvlookup ?  
-									((peer->socket.type & SIP_TRANSPORT_UDP) ? "_sip._udp" :
-									 (peer->socket.type & SIP_TRANSPORT_TCP) ? "_sip._tcp" :
-									 "_sip._tls")
-									: NULL)) {
+	if (srvlookup && peer->dnsmgr == NULL) {
+		char transport[MAXHOSTNAMELEN];
+		snprintf(transport, sizeof(transport), "_sip._%s", get_transport(peer->socket.type));
+
+		if (ast_dnsmgr_lookup(srvlookup, &peer->addr, &peer->dnsmgr, global_srvlookup ? transport : NULL)) {
 			unref_peer(peer);
 			return NULL;
 		}

Modified: trunk/channels/chan_zap.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_zap.c?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/channels/chan_zap.c (original)
+++ trunk/channels/chan_zap.c Tue Apr  1 12:53:08 2008
@@ -14203,8 +14203,6 @@
 	int y, i;
 #endif
 
-	ast_log(LOG_WARNING, "The use of PSTN interfaces with Asterisk has been deprecated.  Zaptel trunk has been removed.\n");
-
 #ifdef HAVE_PRI
 	memset(pris, 0, sizeof(pris));
 	for (y = 0; y < NUM_SPANS; y++) {

Modified: trunk/include/asterisk/dnsmgr.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/dnsmgr.h?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/include/asterisk/dnsmgr.h (original)
+++ trunk/include/asterisk/dnsmgr.h Tue Apr  1 12:53:08 2008
@@ -28,6 +28,7 @@
 #endif
 
 #include "asterisk/network.h"
+#include "asterisk/srv.h"
 
 /*!
  * \brief A DNS manager entry
@@ -50,7 +51,7 @@
  *
  * \return a DNS manager entry
  */
-struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct in_addr *result);
+struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct sockaddr_in *result, const char *service);
 
 /*!
  * \brief Free a DNS manager entry
@@ -75,7 +76,7 @@
  * \retval 0 success
  * \retval non-zero failure
  */
-int ast_dnsmgr_lookup(const char *name, struct in_addr *result, struct ast_dnsmgr_entry **dnsmgr);
+int ast_dnsmgr_lookup(const char *name, struct sockaddr_in *result, struct ast_dnsmgr_entry **dnsmgr, const char *service);
 
 /*!
  * \brief Force a refresh of a dnsmgr entry

Modified: trunk/include/asterisk/slinfactory.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/slinfactory.h?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/include/asterisk/slinfactory.h (original)
+++ trunk/include/asterisk/slinfactory.h Tue Apr  1 12:53:08 2008
@@ -28,12 +28,10 @@
 extern "C" {
 #endif
 
-#define AST_SLINFACTORY_MAX_HOLD 1280
-
 struct ast_slinfactory {
 	AST_LIST_HEAD_NOLOCK(, ast_frame) queue; /*!< A list of unaltered frames */
 	struct ast_trans_pvt *trans;             /*!< Translation path that converts fed frames into signed linear */
-	short hold[AST_SLINFACTORY_MAX_HOLD];    /*!< Hold for audio that no longer belongs to a frame (ie: if only some samples were taken from a frame) */
+	short hold[1280];                        /*!< Hold for audio that no longer belongs to a frame (ie: if only some samples were taken from a frame) */
 	short *offset;                           /*!< Offset into the hold where audio begins */
 	size_t holdlen;                          /*!< Number of samples currently in the hold */
 	unsigned int size;                       /*!< Number of samples currently in the factory */

Modified: trunk/main/dnsmgr.c
URL: http://svn.digium.com/view/asterisk/trunk/main/dnsmgr.c?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/main/dnsmgr.c (original)
+++ trunk/main/dnsmgr.c Tue Apr  1 12:53:08 2008
@@ -43,16 +43,19 @@
 #include "asterisk/sched.h"
 #include "asterisk/cli.h"
 #include "asterisk/manager.h"
+#include "asterisk/acl.h"
 
 static struct sched_context *sched;
 static int refresh_sched = -1;
 static pthread_t refresh_thread = AST_PTHREADT_NULL;
 
 struct ast_dnsmgr_entry {
-	/*! where we will store the resulting address */
-	struct in_addr *result;
-	/*! the last result, used to check if address has changed */
-	struct in_addr last;
+	/*! where we will store the resulting IP address and port number */
+	struct sockaddr_in *result;
+	/*! the last result, used to check if address/port has changed */
+	struct sockaddr_in last;
+	/*! SRV record to lookup, if provided. Composed of service, protocol, and domain name: _Service._Proto.Name */
+	char *service;
 	/*! Set to 1 if the entry changes */
 	int changed:1;
 	ast_mutex_t lock;
@@ -82,17 +85,22 @@
 	.verbose = 0,
 };
 
-struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct in_addr *result)
+struct ast_dnsmgr_entry *ast_dnsmgr_get(const char *name, struct sockaddr_in *result, const char *service)
 {
 	struct ast_dnsmgr_entry *entry;
-
-	if (!result || ast_strlen_zero(name) || !(entry = ast_calloc(1, sizeof(*entry) + strlen(name))))
+	int total_size = sizeof(*entry) + strlen(name) + (service ? strlen(service) + 1 : 0);
+
+	if (!result || ast_strlen_zero(name) || !(entry = ast_calloc(1, total_size)))
 		return NULL;
 
 	entry->result = result;
 	ast_mutex_init(&entry->lock);
 	strcpy(entry->name, name);
 	memcpy(&entry->last, result, sizeof(entry->last));
+	if (service) {
+		entry->service = ((char *) entry) + sizeof(*entry) + strlen(name);
+		strcpy(entry->service, service);
+	}
 
 	AST_RWLIST_WRLOCK(&entry_list);
 	AST_RWLIST_INSERT_HEAD(&entry_list, entry, list);
@@ -115,34 +123,30 @@
 	ast_free(entry);
 }
 
-int ast_dnsmgr_lookup(const char *name, struct in_addr *result, struct ast_dnsmgr_entry **dnsmgr)
-{
-	struct ast_hostent ahp;
-	struct hostent *hp;
-
+int ast_dnsmgr_lookup(const char *name, struct sockaddr_in *result, struct ast_dnsmgr_entry **dnsmgr, const char *service)
+{
 	if (ast_strlen_zero(name) || !result || !dnsmgr)
 		return -1;
 
 	if (*dnsmgr && !strcasecmp((*dnsmgr)->name, name))
 		return 0;
 
-	ast_verb(4, "doing dnsmgr_lookup for '%s'\n", name);
-
 	/* if it's actually an IP address and not a name,
 	   there's no need for a managed lookup */
-	if (inet_aton(name, result))
+	if (inet_aton(name, &result->sin_addr))
 		return 0;
 
+	ast_verb(4, "doing dnsmgr_lookup for '%s'\n", name);
+
 	/* do a lookup now but add a manager so it will automagically get updated in the background */
-	if ((hp = ast_gethostbyname(name, &ahp)))
-		memcpy(result, hp->h_addr, sizeof(result));
+	ast_get_ip_or_srv(result, name, service);
 	
 	/* if dnsmgr is not enable don't bother adding an entry */
 	if (!enabled)
 		return 0;
 	
 	ast_verb(3, "adding dns manager for '%s'\n", name);
-	*dnsmgr = ast_dnsmgr_get(name, result);
+	*dnsmgr = ast_dnsmgr_get(name, result, service);
 	return !*dnsmgr;
 }
 
@@ -151,31 +155,26 @@
  */
 static int dnsmgr_refresh(struct ast_dnsmgr_entry *entry, int verbose)
 {
-	struct ast_hostent ahp;
-	struct hostent *hp;
 	char iabuf[INET_ADDRSTRLEN];
 	char iabuf2[INET_ADDRSTRLEN];
-	struct in_addr tmp;
+	struct sockaddr_in tmp;
 	int changed = 0;
         
 	ast_mutex_lock(&entry->lock);
 	if (verbose)
 		ast_verb(3, "refreshing '%s'\n", entry->name);
 
-	if ((hp = ast_gethostbyname(entry->name, &ahp))) {
-		/* check to see if it has changed, do callback if requested (where de callback is defined ????) */
-		memcpy(&tmp, hp->h_addr, sizeof(tmp));
-		if (tmp.s_addr != entry->last.s_addr) {
-			ast_copy_string(iabuf, ast_inet_ntoa(entry->last), sizeof(iabuf));
-			ast_copy_string(iabuf2, ast_inet_ntoa(tmp), sizeof(iabuf2));
-			ast_log(LOG_NOTICE, "host '%s' changed from %s to %s\n", 
-				entry->name, iabuf, iabuf2);
-			memcpy(entry->result, hp->h_addr, sizeof(entry->result));
-			memcpy(&entry->last, hp->h_addr, sizeof(entry->last));
-			changed = entry->changed = 1;
-		} 
-		
-	}
+	ast_get_ip_or_srv(&tmp, entry->name, entry->service);
+	if (inaddrcmp(&tmp, &entry->last)) {
+		ast_copy_string(iabuf, ast_inet_ntoa(entry->last.sin_addr), sizeof(iabuf));
+		ast_copy_string(iabuf2, ast_inet_ntoa(tmp.sin_addr), sizeof(iabuf2));
+		ast_log(LOG_NOTICE, "dnssrv: host '%s' changed from %s:%d to %s:%d\n", 
+			entry->name, iabuf, ntohs(entry->last.sin_port), iabuf2, ntohs(tmp.sin_port));
+		*entry->result = tmp;
+		entry->last = tmp;
+		changed = entry->changed = 1;
+	}
+
 	ast_mutex_unlock(&entry->lock);
 	return changed;
 }

Modified: trunk/main/slinfactory.c
URL: http://svn.digium.com/view/asterisk/trunk/main/slinfactory.c?view=diff&rev=112207&r1=112206&r2=112207
==============================================================================
--- trunk/main/slinfactory.c (original)
+++ trunk/main/slinfactory.c Tue Apr  1 12:53:08 2008
@@ -172,9 +172,6 @@
 				memcpy(offset, frame_data, ineed * sizeof(*offset));
 				sofar += ineed;
 				frame_data += ineed;
-				if (remain > (AST_SLINFACTORY_MAX_HOLD - sf->holdlen)) {
-					remain = AST_SLINFACTORY_MAX_HOLD - sf->holdlen;
-				}
 				memcpy(sf->hold, frame_data, remain * sizeof(*offset));
 				sf->holdlen = remain;
 			}




More information about the asterisk-commits mailing list