From 3162a8e558bfadf5f9f6e073e78cd07706747e70 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Fri, 29 Oct 2010 20:46:06 +0000 Subject: Enable IPv6 for the built-in HTTP server. Review: https://reviewboard.asterisk.org/r/986 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@293273 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/http.c | 105 ++++++++++++++++++++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 45 deletions(-) (limited to 'main/http.c') diff --git a/main/http.c b/main/http.c index a99d3b759..db019991c 100644 --- a/main/http.c +++ b/main/http.c @@ -41,7 +41,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include #include "asterisk/paths.h" /* use ast_config_AST_DATA_DIR */ -#include "asterisk/network.h" #include "asterisk/cli.h" #include "asterisk/tcptls.h" #include "asterisk/http.h" @@ -53,8 +52,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/manager.h" #include "asterisk/_private.h" #include "asterisk/astobj2.h" +#include "asterisk/netsock2.h" #define MAX_PREFIX 80 +#define DEFAULT_PORT 8088 +#define DEFAULT_TLS_PORT 8089 /* See http.h for more information about the SSL implementation */ #if defined(HAVE_OPENSSL) && (defined(HAVE_FUNOPEN) || defined(HAVE_FOPENCOOKIE)) @@ -984,13 +986,12 @@ static int __ast_http_load(int reload) struct ast_variable *v; int enabled=0; int newenablestatic=0; - struct hostent *hp; - struct ast_hostent ahp; char newprefix[MAX_PREFIX] = ""; struct http_uri_redirect *redirect; struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 }; - struct sockaddr_in tmp = {0,}; - struct sockaddr_in tmp2 = {0,}; + uint32_t bindport = DEFAULT_PORT; + struct ast_sockaddr *addrs = NULL; + int num_addrs = 0; cfg = ast_config_load2("http.conf", "http", config_flags); if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEUNCHANGED || cfg == CONFIG_STATUS_FILEINVALID) { @@ -998,14 +999,6 @@ static int __ast_http_load(int reload) } /* default values */ - tmp.sin_family = AF_INET; - tmp.sin_port = htons(8088); - ast_sockaddr_from_sin(&http_desc.local_address, &tmp); - - tmp2.sin_family = AF_INET; - tmp2.sin_port = htons(8089); - ast_sockaddr_from_sin(&https_desc.local_address, &tmp2); - http_tls_cfg.enabled = 0; if (http_tls_cfg.certfile) { ast_free(http_tls_cfg.certfile); @@ -1042,17 +1035,14 @@ static int __ast_http_load(int reload) } else if (!strcasecmp(v->name, "enablestatic")) { newenablestatic = ast_true(v->value); } else if (!strcasecmp(v->name, "bindport")) { - ast_sockaddr_set_port(&http_desc.local_address, - atoi(v->value)); + if (ast_parse_arg(v->value, PARSE_UINT32 | PARSE_IN_RANGE | PARSE_DEFAULT, &bindport, DEFAULT_PORT, 0, 65535)) { + ast_log(LOG_WARNING, "Invalid port %s specified. Using default port %"PRId32, v->value, DEFAULT_PORT); + } } else if (!strcasecmp(v->name, "bindaddr")) { - if ((hp = ast_gethostbyname(v->value, &ahp))) { - ast_sockaddr_to_sin(&http_desc.local_address, - &tmp); - memcpy(&tmp.sin_addr, hp->h_addr, sizeof(tmp.sin_addr)); - ast_sockaddr_from_sin(&http_desc.local_address, - &tmp); + if (!(num_addrs = ast_sockaddr_resolve(&addrs, v->value, 0, AST_AF_UNSPEC))) { + ast_log(LOG_WARNING, "Invalid bind address %s\n", v->value); } else { - ast_log(LOG_WARNING, "Invalid bind address '%s'\n", v->value); + ast_log(LOG_WARNING, "Got %d addresses\n", num_addrs); } } else if (!strcasecmp(v->name, "prefix")) { if (!ast_strlen_zero(v->value)) { @@ -1070,24 +1060,53 @@ static int __ast_http_load(int reload) ast_config_destroy(cfg); } - /* if the https addres has not been set, default is the same as non secure http */ - ast_sockaddr_to_sin(&http_desc.local_address, &tmp); - ast_sockaddr_to_sin(&https_desc.local_address, &tmp2); - if (!tmp2.sin_addr.s_addr) { - tmp2.sin_addr = tmp.sin_addr; - ast_sockaddr_from_sin(&https_desc.local_address, &tmp2); - } - if (!enabled) { - ast_sockaddr_setnull(&http_desc.local_address); - ast_sockaddr_setnull(&https_desc.local_address); - } + if (strcmp(prefix, newprefix)) { ast_copy_string(prefix, newprefix, sizeof(prefix)); } enablestatic = newenablestatic; - ast_tcptls_server_start(&http_desc); - if (ast_ssl_setup(https_desc.tls_cfg)) { - ast_tcptls_server_start(&https_desc); + + if (num_addrs && enabled) { + int i; + for (i = 0; i < num_addrs; ++i) { + ast_sockaddr_copy(&http_desc.local_address, &addrs[i]); + if (!ast_sockaddr_port(&http_desc.local_address)) { + ast_sockaddr_set_port(&http_desc.local_address, bindport); + } + ast_tcptls_server_start(&http_desc); + if (http_desc.accept_fd == -1) { + ast_log(LOG_WARNING, "Failed to start HTTP server for address %s\n", ast_sockaddr_stringify(&addrs[i])); + ast_sockaddr_setnull(&http_desc.local_address); + } else { + ast_verb(1, "Bound HTTP server to address %s\n", ast_sockaddr_stringify(&addrs[i])); + break; + } + } + /* When no specific TLS bindaddr is specified, we just use + * the non-TLS bindaddress here. + */ + if (ast_sockaddr_isnull(&https_desc.local_address) && http_desc.accept_fd != -1) { + ast_sockaddr_copy(&https_desc.local_address, &https_desc.local_address); + /* Of course, we can't use the same port though. + * Since no bind address was specified, we just use the + * default TLS port + */ + ast_sockaddr_set_port(&https_desc.local_address, DEFAULT_TLS_PORT); + } + } + + if (enabled && !ast_sockaddr_isnull(&https_desc.local_address)) { + /* We can get here either because a TLS-specific address was specified + * or because we copied the non-TLS address here. In the case where + * we read an explicit address from the config, there may have been + * no port specified, so we'll just use the default TLS port. + */ + if (!ast_sockaddr_port(&https_desc.local_address)) { + ast_sockaddr_set_port(&https_desc.local_address, DEFAULT_TLS_PORT); + } + if (ast_ssl_setup(https_desc.tls_cfg)) { + ast_tcptls_server_start(&https_desc); + } } return 0; @@ -1097,7 +1116,6 @@ static char *handle_show_http(struct ast_cli_entry *e, int cmd, struct ast_cli_a { struct ast_http_uri *urih; struct http_uri_redirect *redirect; - struct sockaddr_in tmp; switch (cmd) { case CLI_INIT: @@ -1115,17 +1133,14 @@ static char *handle_show_http(struct ast_cli_entry *e, int cmd, struct ast_cli_a } ast_cli(a->fd, "HTTP Server Status:\n"); ast_cli(a->fd, "Prefix: %s\n", prefix); - ast_sockaddr_to_sin(&http_desc.old_address, &tmp); - if (!tmp.sin_family) { + if (ast_sockaddr_isnull(&http_desc.old_address)) { ast_cli(a->fd, "Server Disabled\n\n"); } else { - ast_cli(a->fd, "Server Enabled and Bound to %s:%d\n\n", - ast_inet_ntoa(tmp.sin_addr), ntohs(tmp.sin_port)); + ast_cli(a->fd, "Server Enabled and Bound to %s\n\n", + ast_sockaddr_stringify(&http_desc.old_address)); if (http_tls_cfg.enabled) { - ast_sockaddr_to_sin(&https_desc.old_address, &tmp); - ast_cli(a->fd, "HTTPS Server Enabled and Bound to %s:%d\n\n", - ast_inet_ntoa(tmp.sin_addr), - ntohs(tmp.sin_port)); + ast_cli(a->fd, "HTTPS Server Enabled and Bound to %s\n\n", + ast_sockaddr_stringify(&https_desc.old_address)); } } -- cgit v1.2.3