[asterisk-commits] seanbright: trunk r357610 - in /trunk: CHANGES res/res_agi.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Feb 29 14:31:54 CST 2012


Author: seanbright
Date: Wed Feb 29 14:31:48 2012
New Revision: 357610

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=357610
Log:
Add IPv6 support to FastAGI.

Review: https://reviewboard.asterisk.org/r/1774/
Reviewed by: Simon Perreault, Mark Michelson

Modified:
    trunk/CHANGES
    trunk/res/res_agi.c

Modified: trunk/CHANGES
URL: http://svnview.digium.com/svn/asterisk/trunk/CHANGES?view=diff&rev=357610&r1=357609&r2=357610
==============================================================================
--- trunk/CHANGES (original)
+++ trunk/CHANGES Wed Feb 29 14:31:48 2012
@@ -205,6 +205,9 @@
  * A new channel variable, AGIEXITONHANGUP, has been added which allows
    Asterisk to behave like it did in Asterisk 1.4 and earlier where the
    AGI application would exit immediately after a channel hangup is detected.
+ * IPv6 addresses are now supported when using FastAGI (agi://).  Hostnames
+   are resolved and each address is attempted in turn until one succeeds or
+   all fail.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.8 to Asterisk 10 -------------------

Modified: trunk/res/res_agi.c
URL: http://svnview.digium.com/svn/asterisk/trunk/res/res_agi.c?view=diff&rev=357610&r1=357609&r2=357610
==============================================================================
--- trunk/res/res_agi.c (original)
+++ trunk/res/res_agi.c Wed Feb 29 14:31:48 2012
@@ -65,6 +65,7 @@
 #include "asterisk/xmldoc.h"
 #include "asterisk/srv.h"
 #include "asterisk/test.h"
+#include "asterisk/netsock2.h"
 
 #define AST_API_MODULE
 #include "asterisk/agi.h"
@@ -1445,15 +1446,15 @@
 	FastAGI defaults to port 4573 */
 static enum agi_result launch_netscript(char *agiurl, char *argv[], int *fds)
 {
-	int s, flags, res, port = AGI_PORT;
+	int s = 0, flags, res;
 	struct pollfd pfds[1];
-	char *host, *c, *script;
-	struct sockaddr_in addr_in;
-	struct hostent *hp;
-	struct ast_hostent ahp;
+	char *host, *script;
+	int num_addrs = 0, i = 0;
+	struct ast_sockaddr *addrs;
 
 	/* agiurl is "agi://host.domain[:port][/script/name]" */
 	host = ast_strdupa(agiurl + 6);	/* Remove agi:// */
+
 	/* Strip off any script name */
 	if ((script = strchr(host, '/'))) {
 		*script++ = '\0';
@@ -1461,35 +1462,48 @@
 		script = "";
 	}
 
-	if ((c = strchr(host, ':'))) {
-		*c++ = '\0';
-		port = atoi(c);
-	}
-	if (!(hp = ast_gethostbyname(host, &ahp))) {
+	if (!(num_addrs = ast_sockaddr_resolve(&addrs, host, 0, AST_AF_UNSPEC))) {
 		ast_log(LOG_WARNING, "Unable to locate host '%s'\n", host);
 		return AGI_RESULT_FAILURE;
 	}
-	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-		ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
-		return AGI_RESULT_FAILURE;
-	}
-	if ((flags = fcntl(s, F_GETFL)) < 0) {
-		ast_log(LOG_WARNING, "Fcntl(F_GETFL) failed: %s\n", strerror(errno));
-		close(s);
-		return AGI_RESULT_FAILURE;
-	}
-	if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
-		ast_log(LOG_WARNING, "Fnctl(F_SETFL) failed: %s\n", strerror(errno));
-		close(s);
-		return AGI_RESULT_FAILURE;
-	}
-	memset(&addr_in, 0, sizeof(addr_in));
-	addr_in.sin_family = AF_INET;
-	addr_in.sin_port = htons(port);
-	memcpy(&addr_in.sin_addr, hp->h_addr, sizeof(addr_in.sin_addr));
-	if (connect(s, (struct sockaddr *)&addr_in, sizeof(addr_in)) && (errno != EINPROGRESS)) {
-		ast_log(LOG_WARNING, "Connect failed with unexpected error: %s\n", strerror(errno));
-		close(s);
+
+	for (i = 0; i < num_addrs; i++) {
+		if (!ast_sockaddr_port(&addrs[i])) {
+			ast_sockaddr_set_port(&addrs[i], AGI_PORT);
+		}
+
+		if ((s = socket(addrs[i].ss.ss_family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+			ast_log(LOG_WARNING, "Unable to create socket: %s\n", strerror(errno));
+			continue;
+		}
+
+		if ((flags = fcntl(s, F_GETFL)) < 0) {
+			ast_log(LOG_WARNING, "fcntl(F_GETFL) failed: %s\n", strerror(errno));
+			close(s);
+			continue;
+		}
+
+		if (fcntl(s, F_SETFL, flags | O_NONBLOCK) < 0) {
+			ast_log(LOG_WARNING, "fnctl(F_SETFL) failed: %s\n", strerror(errno));
+			close(s);
+			continue;
+		}
+
+		if (ast_connect(s, &addrs[i]) && (errno != EINPROGRESS)) {
+			ast_log(LOG_WARNING, "Connection to %s failed with unexpected error: %s\n",
+				ast_sockaddr_stringify(&addrs[i]),
+				strerror(errno));
+			close(s);
+			continue;
+		}
+
+		break;
+	}
+
+	ast_free(addrs);
+
+	if (i == num_addrs) {
+		ast_log(LOG_WARNING, "Couldn't connect to any host.  FastAGI failed.\n");
 		return AGI_RESULT_FAILURE;
 	}
 




More information about the asterisk-commits mailing list