[asterisk-commits] oej: branch oej/pgtips-srv-and-outbound-stuff-1.8 r386419 - in /team/oej/pgti...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Apr 24 08:08:35 CDT 2013


Author: oej
Date: Wed Apr 24 08:08:31 2013
New Revision: 386419

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=386419
Log:
Phase 1: Defining a SIP peer 

The SIP peer will use the first address it finds according to the supported address families
by searching through the list of SRV records.

The Peer ACL matching still doesn't work.

Modified:
    team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c
    team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h
    team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/dns.h
    team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/srv.h
    team/oej/pgtips-srv-and-outbound-stuff-1.8/main/acl.c
    team/oej/pgtips-srv-and-outbound-stuff-1.8/main/dnsmgr.c
    team/oej/pgtips-srv-and-outbound-stuff-1.8/main/enum.c
    team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/chan_sip.c Wed Apr 24 08:08:31 2013
@@ -5004,10 +5004,17 @@
 		ast_variables_destroy(peer->chanvars);
 		peer->chanvars = NULL;
 	}
+
+	if (peer->srvcontext) {
+		ast_srv_context_free_list(peer->srvcontext);
+		ast_free(peer->srvcontext);
+		peer->srvcontext = NULL;
+	}
 	
 	register_peer_exten(peer, FALSE);
 	ast_free_ha(peer->ha);
 	ast_free_ha(peer->directmediaha);
+	ast_free_ha(peer->srventries);		/* ACL based on IP addresses in SRV list for domain */
 	if (peer->selfdestruct)
 		ast_atomic_fetchadd_int(&apeerobjs, -1);
 	else if (!ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS) && peer->is_realtime) {
@@ -5847,18 +5854,47 @@
 		 * an A record lookup should be used instead of SRV.
 		 */
 		if (!hostport.port && sip_cfg.srvlookup) {
+			struct srv_context *srvcon = ast_srv_context_new();
+
 			snprintf(service, sizeof(service), "_%s._%s.%s", 
 				 get_srv_service(dialog->socket.type),
 				 get_srv_protocol(dialog->socket.type), peername);
-			if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno,
-						   service)) > 0) {
+
+			/* Get the srv list */
+			if ((srv_ret = ast_get_srv_list(srvcon, NULL, service)) > 0) {
+				int rec = 1;
+				unsigned short port, prio, weight;
+				const char *srvhost;
+
+				ast_debug(3, "   ==> DNS lookup of %s returned %d entries. First %s \n", service, ast_srv_get_record_count(srvcon), hostn);
 				hostn = host;
-			}
-		}
-
-		if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) {
-			ast_log(LOG_WARNING, "No such host: %s\n", peername);
-			return -1;
+				for (rec = 0; rec < ast_srv_get_record_count(srvcon); rec++) {
+					if(ast_srv_get_nth_record(srvcon, rec, &srvhost, &port, &prio, &weight)) {
+						ast_log(LOG_WARNING, "No more SRV records for: %s\n", peername);
+						return -1;
+					}
+					ast_copy_string(host, srvhost, sizeof(host));
+					hostn = host;
+					tportno = (int) port;
+					ast_debug(3, "   ==> Trying SRV entry %d (prio %d weight %d): %s\n", rec, prio, weight, hostn);
+					if (!ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) {
+						/* We found a host to try on */
+						break;
+					}
+		
+				}
+
+				ast_debug(3, "   ==> Settling with SRV entry %d:   %s\n", rec, hostn);
+
+			}
+			ast_srv_context_free_list(srvcon);
+			ast_free(srvcon);
+		} else {
+
+			if (ast_sockaddr_resolve_first_transport(&dialog->sa, hostn, 0, dialog->socket.type ? dialog->socket.type : SIP_TRANSPORT_UDP)) {
+				ast_log(LOG_WARNING, "No such host: %s\n", peername);
+				return -1;
+			}
 		}
 
 		if (srv_ret > 0) {
@@ -18183,6 +18219,7 @@
 		ast_cli(fd, "  DTMFmode     : %s\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
 		ast_cli(fd, "  Timer T1     : %d\n", peer->timer_t1);
 		ast_cli(fd, "  Timer B      : %d\n", peer->timer_b);
+		ast_cli(fd, "  Domain       : %s\n", ast_strlen_zero(peer->srvdomain) ? "N/A" : peer->srvdomain);
 		ast_cli(fd, "  ToHost       : %s\n", peer->tohost);
 		ast_cli(fd, "  Addr->IP     : %s\n", ast_sockaddr_stringify(&peer->addr));
 		ast_cli(fd, "  Defaddr->IP  : %s\n", ast_sockaddr_stringify(&peer->defaddr));
@@ -18291,6 +18328,7 @@
 
 		/* - is enumerated */
 		astman_append(s, "SIP-DTMFmode: %s\r\n", dtmfmode2str(ast_test_flag(&peer->flags[0], SIP_DTMF)));
+		astman_append(s, "SipDomain: %s\r\n", ast_strlen_zero(peer->srvdomain) ? "" : peer->srvdomain);
 		astman_append(s, "ToHost: %s\r\n", peer->tohost);
 		astman_append(s, "Address-IP: %s\r\nAddress-Port: %d\r\n", ast_sockaddr_stringify_addr(&peer->addr), ast_sockaddr_port(&peer->addr));
 		astman_append(s, "Default-addr-IP: %s\r\nDefault-addr-port: %d\r\n", ast_sockaddr_stringify_addr(&peer->defaddr), ast_sockaddr_port(&peer->defaddr));
@@ -27985,6 +28023,8 @@
 	static int deprecation_warning = 1;
 	int alt_fullcontact = alt ? 1 : 0, headercount = 0;
 	struct ast_str *fullcontact = ast_str_alloca(512);
+
+	ast_debug(2, "==> Starting to build peer  %s \n", name);
 
 	if (!realtime || ast_test_flag(&global_flags[1], SIP_PAGE2_RTCACHEFRIENDS)) {
 		/* Note we do NOT use find_peer here, to avoid realtime recursion */
@@ -28516,29 +28556,127 @@
 		}
 	}
 
+	ast_debug(3, " ==> SRV check begins for %s \n", name);
+
+	if(sip_cfg.srvlookup && srvlookup && peer->portinuri == 0 && !ast_sockaddr_parse(NULL, srvlookup, PARSE_PORT_IGNORE)) {
+		/* We have no port, and not an IP address so hostname can be used as domain */
+		ast_string_field_set(peer, srvdomain, srvlookup);	/* Save the domain for future lookups */
+		ast_debug(3, " ==> Host name %s needs SRV lookup \n", srvlookup);
+	} else {
+		ast_debug(3, " ==> Host name %s does not need SRV lookup \n", srvlookup);
+	}
+
+
 	if (srvlookup && peer->dnsmgr == NULL) {
 		char transport[MAXHOSTNAMELEN];
 		char _srvlookup[MAXHOSTNAMELEN];
+		char host[MAXHOSTNAMELEN];
 		char *params;
+		int tportno;
+		int gotsrv = FALSE;
 
 		ast_copy_string(_srvlookup, srvlookup, sizeof(_srvlookup));
 		if ((params = strchr(_srvlookup, ';'))) {
 			*params++ = '\0';
 		}
 
-		snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
+		ast_debug(2, "==> Going to get SRV records for %s \n", _srvlookup);
 
 		peer->addr.ss.ss_family = get_address_family_filter(peer->socket.type); /* Filter address family */
-		if (ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL,
-					on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"))) {
-			ast_log(LOG_ERROR, "srvlookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
-			unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref");
-			unref_peer(peer, "getting rid of a peer pointer");
-			return NULL;
-		}
-		if (!peer->dnsmgr) {
-			/* dnsmgr refresh disabeld, release reference */
-			unref_peer(peer, "dnsmgr disabled, unref peer");
+
+		/* If we don't have an IP address or a port number configured,
+		   check if we can get a DNS SRV list */
+		if (!ast_strlen_zero(peer->srvdomain)) {
+			if (peer->srvcontext) {
+				ast_srv_context_free_list(peer->srvcontext);
+				free(peer->srvcontext);
+			}
+			peer->srvcontext = ast_srv_context_new();
+			if (peer->srvcontext == NULL) {
+				ast_log(LOG_ERROR, "Couldn't allocate DNS SRV memory for peer %s\n", peer->name);
+			} else {
+				snprintf(transport, sizeof(transport), "_%s._%s.%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type), _srvlookup);
+				gotsrv = ast_get_srv_list(peer->srvcontext, NULL, transport);
+			}
+
+		}
+
+		/* If we have a DNS SRV list, go through it to find a candidate that works with our address family 
+		 * We don't use the DNSmanager for SRV records.
+		 */
+		if (gotsrv > 0) {
+				int rec = 0;
+				unsigned short prio, weight;
+				const char *hostname;
+
+				ast_debug(3, "   ==> DNS SRV lookup of %s returned %d entries. \n", transport, ast_srv_get_record_count(peer->srvcontext));
+				/* Try all candidates until we find one that fits our address family 
+  				 * Note that the SRV code lists the candidates in order of weight and priority.
+				 */
+				do {
+					rec++;
+					if(ast_srv_get_nth_record(peer->srvcontext, rec, &hostname, &tportno, &prio, &weight)) {
+						ast_log(LOG_WARNING, "No more hosts: %s\n", peer->srvdomain);
+						unref_peer(peer, "SRV lookup failed, getting rid of peer ref");
+						return NULL;
+					}
+					ast_debug(3, "   ==> Trying SRV entry %d (prio %d weight %d): %s\n", rec, prio, weight, hostname);
+				} while (ast_sockaddr_resolve_first_transport(&peer->addr, hostname, 0, peer->socket.type));
+
+				/* Set the port number */
+				ast_sockaddr_set_port(&peer->addr, tportno);
+
+				ast_debug(3, "   ==> Settling on SRV entry %d (prio %d weight %d): %s\n", rec - 1, prio, weight, hostname);
+
+				/* Now loop again and fill the ACL 
+				 */
+				if (peer->srventries) {
+					ast_free_ha(peer->srventries);
+				}
+				for (rec = 1; rec <= ast_srv_get_record_count(peer->srvcontext); rec++) {
+					int res;
+					struct ast_sockaddr ip;
+					/* Get host name */
+					res = ast_srv_get_nth_record(peer->srvcontext, rec, &hostname, &tportno, &prio, &weight);
+					if (res) {
+						res = ast_sockaddr_resolve_first_transport(&ip, hostname, 0, peer->socket.type);
+					}
+					if (res) {
+						int ha_error;
+						peer->srventries = ast_append_ha("p", ast_sockaddr_stringify_addr(&ip), peer->srventries, &res);
+					}
+					if (res) {
+						ast_log(LOG_ERROR, "Bad or unresolved host/IP entry in configuration for peer %s, cannot add to contact ACL\n", peer->name);
+					} else {
+						ast_debug(3, " ==> Adding IP to peer %s srv list: %s \n", name, ast_sockaddr_stringify_addr(&ip));
+					}
+				}
+
+		} else {
+			int res;
+			/* Lookup A/AAAA records - possibly with DNSmanager */
+			if (gotsrv == 0) {
+				ast_debug(3, "==> Looking up A/AAAA DNS records for %s \n", _srvlookup);
+				/* If gotserv is negative we've already tried with SRV  - now look for A /AAAA records */
+				res = ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, NULL, on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"));
+			} else {
+				ast_debug(3, "==> Looking up SRV or A/AAAA DNS records for %s \n", _srvlookup);
+				/* If gotserv is negative we've already tried with SRV */
+				snprintf(transport, sizeof(transport), "_%s._%s", get_srv_service(peer->socket.type), get_srv_protocol(peer->socket.type));
+				res = ast_dnsmgr_lookup_cb(_srvlookup, &peer->addr, &peer->dnsmgr, sip_cfg.srvlookup && !peer->portinuri ? transport : NULL,
+                                        on_dns_update_peer, ref_peer(peer, "Store peer on dnsmgr"));
+			}
+			if (res) {
+				ast_log(LOG_ERROR, "DNS SRV or A/AAAA lookup failed for host: %s, on peer %s, removing peer\n", _srvlookup, peer->name);
+				unref_peer(peer, "dnsmgr lookup failed, getting rid of peer dnsmgr ref");
+				unref_peer(peer, "getting rid of a peer pointer");
+				return NULL;
+			}
+			ast_debug(2, "==> Got DNS records for %s \n", _srvlookup);
+			if (!peer->dnsmgr) {
+				/* dnsmgr refresh disabled, release reference */
+				unref_peer(peer, "dnsmgr disabled, unref peer");
+			}
 		}
 
 		ast_string_field_set(peer, tohost, srvlookup);
@@ -28555,6 +28693,7 @@
 		/* force a refresh here on reload if dnsmgr already exists and host is set. */
 		ast_dnsmgr_refresh(peer->dnsmgr);
 	}
+	ast_debug(2, "==> Done with DNS and SRV records for %s \n", srvlookup);
 
 	if (port && !realtime && peer->host_dynamic) {
 		ast_sockaddr_set_port(&peer->defaddr, port);
@@ -28575,6 +28714,7 @@
 	if (!peer->socket.port) {
 		peer->socket.port = htons(((peer->socket.type & SIP_TRANSPORT_TLS) ? STANDARD_TLS_PORT : STANDARD_SIP_PORT));
 	}
+	ast_debug(3, "==> building peer %s =======\n", peer->name );
 
 	if (!sip_cfg.ignore_regexpire && peer->host_dynamic && realtime) {
 		time_t nowtime = time(NULL);
@@ -28592,6 +28732,7 @@
 		ref_peer(peer, "schedule qualify");
 		sip_poke_peer(peer, 0);
 	}
+	ast_debug(3, "==> building peer %s =======\n", peer->name );
 
 	if (ast_test_flag(&peer->flags[1], SIP_PAGE2_ALLOWSUBSCRIBE)) {
 		sip_cfg.allowsubscribe = TRUE;	/* No global ban any more */
@@ -28611,6 +28752,7 @@
 		 * way, then we will get events when app_voicemail gets loaded. */
 		sip_send_mwi_to_peer(peer, 1);
 	}
+	ast_debug(3, "==> building peer %s =======\n", peer->name );
 
 	peer->the_mark = 0;
 
@@ -28623,6 +28765,7 @@
 			ast_free(reg_string);
 		}
 	}
+	ast_debug(3, "==> Done building peer %s =======\n", peer->name );
 	return peer;
 }
 

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/channels/sip/include/sip.h Wed Apr 24 08:08:31 2013
@@ -1211,6 +1211,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(srvdomain);    /*!<  SIP Domain for SRV lookups */
 		AST_STRING_FIELD(unsolicited_mailbox);  /*!< Mailbox to store received unsolicited MWI NOTIFY messages information in */
 		);
 	struct sip_socket socket;       /*!< Socket used for this peer */
@@ -1258,6 +1259,7 @@
 	struct sip_proxy *outboundproxy;/*!< Outbound proxy for this peer */
 	struct ast_dnsmgr_entry *dnsmgr;/*!<  DNS refresh manager for peer */
 	struct ast_sockaddr addr;        /*!<  IP address of peer */
+	struct srv_context *srvcontext;	/*!< DNS SRV lookup chain for failover */
 	unsigned int portinuri:1;       /*!< Whether the port should be included in the URI */
 	struct sip_pvt *call;           /*!<  Call pointer */
 	int pokeexpire;                 /*!<  Qualification: When to expire poke (qualify= checking) */
@@ -1269,6 +1271,7 @@
 	struct ast_ha *ha;              /*!<  Access control list */
 	struct ast_ha *contactha;       /*!<  Restrict what IPs are allowed in the Contact header (for registration) */
 	struct ast_ha *directmediaha;   /*!<  Restrict what IPs are allowed to interchange direct media with */
+	struct ast_ha *srventries;      /*!<  DNS Srv entries at time of peer creation  */
 	struct ast_variable *chanvars;  /*!<  Variables to set for channel created by user */
 	struct sip_pvt *mwipvt;         /*!<  Subscription for MWI */
 	struct sip_st_cfg stimer;       /*!<  SIP Session-Timers */

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/dns.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/dns.h?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/dns.h (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/dns.h Wed Apr 24 08:08:31 2013
@@ -34,6 +34,6 @@
 		services does not work, Asterisk may lock while waiting for response.
 */
 int ast_search_dns(void *context, const char *dname, int class, int type,
-	 int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer));
+	 int (*callback)(void *context, unsigned char *answer, int len, unsigned char *fullanswer, unsigned int ttl));
 
 #endif /* _ASTERISK_DNS_H */

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/srv.h
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/srv.h?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/srv.h (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/include/asterisk/srv.h Wed Apr 24 08:08:31 2013
@@ -34,6 +34,13 @@
 /*!\brief An opaque type, for lookup usage */
 struct srv_context;
 
+/*! \brief Allocate a new SRV context 
+*/
+struct srv_context *ast_srv_context_new(void);
+
+/*! \brief Free all entries in the context, but not the context itself */
+void ast_srv_context_free_list(struct srv_context *context);
+
 /*!\brief Retrieve set of SRV lookups, in order
  * \param[in] context A pointer in which to hold the result
  * \param[in] service The service name to look up
@@ -50,8 +57,6 @@
  */
 void ast_srv_cleanup(struct srv_context **context);
 
-/*! \brief Free all entries in the context, but not the context itself */
-void ast_srv_context_free_list(struct srv_context *context);
 
 /*! Lookup entry in SRV records Returns 1 if found, 0 if not found, -1 on hangup 
 	Only do SRV record lookup if you get a domain without a port. If you get a port #, it's a DNS host name.
@@ -110,4 +115,5 @@
  * \brief Print out the complete data in the SRV list
  */
 void ast_srv_debug_print(struct srv_context *context);
+
 #endif /* _ASTERISK_SRV_H */

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/main/acl.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/main/acl.c?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/main/acl.c (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/main/acl.c Wed Apr 24 08:08:31 2013
@@ -603,11 +603,13 @@
 
 	if (service) {
 		snprintf(srv, sizeof(srv), "%s.%s", service, hostname);
+		ast_debug(3, "==> Looking up %s \n", srv);
 		if ((srv_ret = ast_get_srv(NULL, host, sizeof(host), &tportno, srv)) > 0) {
 			hostname = host;
 		}
 	}
 
+	ast_debug(3, "==> Resolving %s \n", hostname);
 	if (resolve_first(addr, hostname, PARSE_PORT_FORBID, addr->ss.ss_family) != 0) {
 		return -1;
 	}

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/main/dnsmgr.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/main/dnsmgr.c?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/main/dnsmgr.c (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/main/dnsmgr.c Wed Apr 24 08:08:31 2013
@@ -152,11 +152,14 @@
 	/* Lookup address family filter. */
 	family = result->ss.ss_family;
 
+	ast_debug(3, "===> Doing dns magic on %s \n", name);
+
 	/*
 	 * If it's actually an IP address and not a name, there's no
 	 * need for a managed lookup.
 	 */
 	if (ast_sockaddr_parse(result, name, PARSE_PORT_FORBID)) {
+		ast_debug(3, "   ==> Not a name, it's an address. Done with %s\n", name);
 		return 0;
 	}
 

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/main/enum.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/main/enum.c?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/main/enum.c (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/main/enum.c Wed Apr 24 08:08:31 2013
@@ -142,7 +142,7 @@
 };
 
 /*! \brief Callback for TXT record lookup, /ol version */
-static int txt_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
+static int txt_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer, unsigned int ttl)
 {
 	struct txt_context *c = context;
 	unsigned int i;
@@ -247,7 +247,7 @@
 };
 
 /*! \brief Callback for EBL record lookup */
-static int ebl_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
+static int ebl_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer, unsigned int ttl)
 {
 	struct ebl_context *c = context;
 	unsigned int i;
@@ -596,7 +596,7 @@
 #define ENUMLOOKUP_OPTIONS_DIRECT	8
 
 /*! \brief Callback from ENUM lookup function */
-static int enum_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer)
+static int enum_callback(void *context, unsigned char *answer, int len, unsigned char *fullanswer, unsigned int ttl)
 {
 	struct enum_context *c = context;
 	void *p = NULL;

Modified: team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c
URL: http://svnview.digium.com/svn/asterisk/team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c?view=diff&rev=386419&r1=386418&r2=386419
==============================================================================
--- team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c (original)
+++ team/oej/pgtips-srv-and-outbound-stuff-1.8/main/srv.c Wed Apr 24 08:08:31 2013
@@ -77,6 +77,14 @@
 	AST_LIST_HEAD_NOLOCK(srv_entries, srv_entry) entries;
 };
 
+struct srv_context *ast_srv_context_new()
+{
+	struct srv_context *new = ast_calloc(1, sizeof(struct srv_context));
+	AST_LIST_HEAD_INIT_NOLOCK(&new->entries);
+
+	return new;
+}
+
 static int parse_srv(unsigned char *answer, int len, unsigned char *msg, struct srv_entry **result, struct timeval *ttl_expire)
 {
 	struct srv {
@@ -99,6 +107,7 @@
 		ast_log(LOG_WARNING, "Failed to expand hostname\n");
 		return -1;
 	}
+	ast_debug(3, "     ===> Parsed Hostname %s \n", repl);
 
 	/* the magic value "." for the target domain means that this service
 	   is *NOT* available at the domain we searched */
@@ -129,7 +138,7 @@
 {
 	struct srv_context *c = (struct srv_context *) context;
 	struct srv_entry *entry = NULL;
-	struct srv_entry *current;
+	struct srv_entry *current = NULL;
 	struct timeval expiry  = {0,};
 
 	ast_debug(3, " ==> Callback received \n");
@@ -137,6 +146,11 @@
 	expiry.tv_sec =  (long) ttl;
 	expiry = ast_tvadd(expiry, ast_tvnow());
 
+	if (c == NULL) {
+		ast_debug(3, "   ==> Callback with no context ?? \n");
+		return -1;
+	}
+
 	if (parse_srv(answer, len, fullanswer, &entry, &expiry))
 		return -1;
 
@@ -144,12 +158,14 @@
 		c->have_weights = 1;
 
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&c->entries, current, list) {
+		ast_debug(3, "         ===> Looking at you, %s \n", current->host);
 		/* insert this entry just before the first existing
-		   entry with a higher priority */
+	   	entry with a higher priority */
 		if (current->priority <= entry->priority)
 			continue;
 
 		AST_LIST_INSERT_BEFORE_CURRENT(entry, list);
+		c->num_records++;
 		entry = NULL;
 		break;
 	}
@@ -224,8 +240,10 @@
 {
 	struct srv_entry *cur;
 
+	ast_debug(3, "    ===> Searching for %s \n", service);
+
 	if (*context == NULL) {
-		if (!(*context = ast_calloc(1, sizeof(struct srv_context)))) {
+		if (!(*context = ast_srv_context_new())) {
 			return -1;
 		}
 		AST_LIST_HEAD_INIT_NOLOCK(&(*context)->entries);
@@ -243,9 +261,6 @@
 		(*context)->prev = AST_LIST_FIRST(&(*context)->entries);
 		*host = (*context)->prev->host;
 		*port = (*context)->prev->port;
-		AST_LIST_TRAVERSE(&(*context)->entries, cur, list) {
-			++((*context)->num_records);
-		}
 		return 0;
 	}
 
@@ -309,8 +324,15 @@
 	ast_debug(3, "==> Searching in DNS for %s \n", service);
 	ret = ast_search_dns(context, service, C_IN, T_SRV, srv_callback);
 
-	if (ret > 0 && context->have_weights) {
-		process_weights(context);
+	if (ret > 0) {
+		struct srv_entry *cur;
+
+		if(context->have_weights) {
+			process_weights(context);
+		}
+		AST_LIST_TRAVERSE(&context->entries, cur, list) {
+			++(context->num_records);
+		}
 	}
 
 	if (chan) {
@@ -322,7 +344,7 @@
 
 
 
-	if (option_debug > 3) {
+	if (ret > 0 && option_debug > 3) {
 		ast_srv_debug_print(context);
 	}
 
@@ -407,7 +429,12 @@
 	if (context == NULL) {
 		return;
 	}
-
+	if (AST_LIST_EMPTY(&context->entries)) {
+		return;
+	}
+	
+
+	ast_debug(0, "  => Number of DNS SRV entries %d \n", context->num_records);
 	AST_LIST_TRAVERSE(&context->entries, entry, list) {
 		ast_strftime(exptime, sizeof(exptime), "%Y-%m-%d %H:%M:%S.%3q %Z", ast_localtime(&entry->ttl_expire, &myt, NULL));
 		ast_debug(0, "DNS SRV Entry %-2.2d : P %-2.2d W %-4.4d Hostname %s Port %d Expire %s\n", i, entry->priority, entry->weight, entry->host, entry->port, exptime);




More information about the asterisk-commits mailing list