diff options
author | Mark Michelson <mmichelson@digium.com> | 2010-07-08 22:08:07 +0000 |
---|---|---|
committer | Mark Michelson <mmichelson@digium.com> | 2010-07-08 22:08:07 +0000 |
commit | cd4ebd336f6fdd1fe5d2ad57f06654a9678d88d4 (patch) | |
tree | c05335b563c3f7cb9a3edbf3e101d8e1b80e0be4 /main/tcptls.c | |
parent | 816f26c16ce6cf03cf97b7d0e7af64837283e79d (diff) |
Add IPv6 to Asterisk.
This adds a generic API for accommodating IPv6 and IPv4 addresses
within Asterisk. While many files have been updated to make use of the
API, chan_sip and the RTP code are the files which actually support
IPv6 addresses at the time of this commit. The way has been paved for
easier upgrading for other files in the near future, though.
Big thanks go to Simon Perrault, Marc Blanchet, and Jean-Philippe Dionne
for their hard work on this.
(closes issue #17565)
Reported by: russell
Patches:
asteriskv6-test-report.pdf uploaded by russell (license 2)
Review: https://reviewboard.asterisk.org/r/743
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@274783 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/tcptls.c')
-rw-r--r-- | main/tcptls.c | 58 |
1 files changed, 28 insertions, 30 deletions
diff --git a/main/tcptls.c b/main/tcptls.c index 8c95502e7..b505f2a01 100644 --- a/main/tcptls.c +++ b/main/tcptls.c @@ -235,8 +235,7 @@ void *ast_tcptls_server_root(void *data) { struct ast_tcptls_session_args *desc = data; int fd; - struct sockaddr_in sin; - socklen_t sinlen; + struct ast_sockaddr addr; struct ast_tcptls_session_instance *tcptls_session; pthread_t launched; @@ -248,8 +247,7 @@ void *ast_tcptls_server_root(void *data) i = ast_wait_for_input(desc->accept_fd, desc->poll_timeout); if (i <= 0) continue; - sinlen = sizeof(sin); - fd = accept(desc->accept_fd, (struct sockaddr *) &sin, &sinlen); + fd = ast_accept(desc->accept_fd, &addr); if (fd < 0) { if ((errno != EAGAIN) && (errno != EINTR)) ast_log(LOG_WARNING, "Accept failed: %s\n", strerror(errno)); @@ -268,7 +266,7 @@ void *ast_tcptls_server_root(void *data) fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); tcptls_session->fd = fd; tcptls_session->parent = desc; - memcpy(&tcptls_session->remote_address, &sin, sizeof(tcptls_session->remote_address)); + ast_sockaddr_copy(&tcptls_session->remote_address, &addr); tcptls_session->client = 0; @@ -373,10 +371,10 @@ struct ast_tcptls_session_instance *ast_tcptls_client_start(struct ast_tcptls_se goto client_start_error; } - if (connect(desc->accept_fd, (const struct sockaddr *) &desc->remote_address, sizeof(desc->remote_address))) { - ast_log(LOG_ERROR, "Unable to connect %s to %s:%d: %s\n", + if (ast_connect(desc->accept_fd, &desc->remote_address)) { + ast_log(LOG_ERROR, "Unable to connect %s to %s: %s\n", desc->name, - ast_inet_ntoa(desc->remote_address.sin_addr), ntohs(desc->remote_address.sin_port), + ast_sockaddr_stringify(&desc->remote_address), strerror(errno)); goto client_start_error; } @@ -407,17 +405,18 @@ struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_s struct ast_tcptls_session_instance *tcptls_session = NULL; /* Do nothing if nothing has changed */ - if (!memcmp(&desc->old_address, &desc->remote_address, sizeof(desc->old_address))) { + if (!ast_sockaddr_cmp(&desc->old_address, &desc->remote_address)) { ast_debug(1, "Nothing changed in %s\n", desc->name); return NULL; } - desc->old_address = desc->remote_address; + ast_sockaddr_copy(&desc->old_address, &desc->remote_address); if (desc->accept_fd != -1) close(desc->accept_fd); - desc->accept_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->remote_address) ? + AF_INET6 : AF_INET, SOCK_STREAM, IPPROTO_TCP); if (desc->accept_fd < 0) { ast_log(LOG_WARNING, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno)); @@ -426,12 +425,12 @@ struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_s /* if a local address was specified, bind to it so the connection will originate from the desired address */ - if (desc->local_address.sin_family != 0) { + if (!ast_sockaddr_isnull(&desc->local_address)) { setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); - if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) { - ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n", - desc->name, - ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port), + if (ast_bind(desc->accept_fd, &desc->local_address)) { + ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n", + desc->name, + ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } @@ -445,7 +444,8 @@ struct ast_tcptls_session_instance *ast_tcptls_client_create(struct ast_tcptls_s tcptls_session->fd = desc->accept_fd; tcptls_session->parent = desc; tcptls_session->parent->worker_fn = NULL; - memcpy(&tcptls_session->remote_address, &desc->remote_address, sizeof(tcptls_session->remote_address)); + ast_sockaddr_copy(&tcptls_session->remote_address, + &desc->remote_address); return tcptls_session; @@ -463,12 +463,12 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc) int x = 1; /* Do nothing if nothing has changed */ - if (!memcmp(&desc->old_address, &desc->local_address, sizeof(desc->old_address))) { + if (!ast_sockaddr_cmp(&desc->old_address, &desc->local_address)) { ast_debug(1, "Nothing changed in %s\n", desc->name); return; } - desc->old_address = desc->local_address; + ast_sockaddr_copy(&desc->old_address, &desc->local_address); /* Shutdown a running server if there is one */ if (desc->master != AST_PTHREADT_NULL) { @@ -481,22 +481,23 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc) close(desc->accept_fd); /* If there's no new server, stop here */ - if (desc->local_address.sin_family == 0) { + if (ast_sockaddr_isnull(&desc->local_address)) { ast_debug(2, "Server disabled: %s\n", desc->name); return; } - desc->accept_fd = socket(AF_INET, SOCK_STREAM, 0); + desc->accept_fd = socket(ast_sockaddr_is_ipv6(&desc->local_address) ? + AF_INET6 : AF_INET, SOCK_STREAM, 0); if (desc->accept_fd < 0) { ast_log(LOG_ERROR, "Unable to allocate socket for %s: %s\n", desc->name, strerror(errno)); return; } setsockopt(desc->accept_fd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof(x)); - if (bind(desc->accept_fd, (struct sockaddr *) &desc->local_address, sizeof(desc->local_address))) { - ast_log(LOG_ERROR, "Unable to bind %s to %s:%d: %s\n", + if (ast_bind(desc->accept_fd, &desc->local_address)) { + ast_log(LOG_ERROR, "Unable to bind %s to %s: %s\n", desc->name, - ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port), + ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } @@ -507,9 +508,9 @@ void ast_tcptls_server_start(struct ast_tcptls_session_args *desc) flags = fcntl(desc->accept_fd, F_GETFL); fcntl(desc->accept_fd, F_SETFL, flags | O_NONBLOCK); if (ast_pthread_create_background(&desc->master, NULL, desc->accept_fn, desc)) { - ast_log(LOG_ERROR, "Unable to launch thread for %s on %s:%d: %s\n", + ast_log(LOG_ERROR, "Unable to launch thread for %s on %s: %s\n", desc->name, - ast_inet_ntoa(desc->local_address.sin_addr), ntohs(desc->local_address.sin_port), + ast_sockaddr_stringify(&desc->local_address), strerror(errno)); goto error; } @@ -537,7 +538,6 @@ int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_ { if (!strcasecmp(varname, "tlsenable") || !strcasecmp(varname, "sslenable")) { tls_cfg->enabled = ast_true(value) ? 1 : 0; - tls_desc->local_address.sin_family = AF_INET; } else if (!strcasecmp(varname, "tlscertfile") || !strcasecmp(varname, "sslcert") || !strcasecmp(varname, "tlscert")) { ast_free(tls_cfg->certfile); tls_cfg->certfile = ast_strdup(value); @@ -558,10 +558,8 @@ int ast_tls_read_conf(struct ast_tls_config *tls_cfg, struct ast_tcptls_session_ } else if (!strcasecmp(varname, "tlsdontverifyserver")) { ast_set2_flag(&tls_cfg->flags, ast_true(value), AST_SSL_DONT_VERIFY_SERVER); } else if (!strcasecmp(varname, "tlsbindaddr") || !strcasecmp(varname, "sslbindaddr")) { - if (ast_parse_arg(value, PARSE_INADDR, &tls_desc->local_address)) + if (ast_parse_arg(value, PARSE_ADDR, &tls_desc->local_address)) ast_log(LOG_WARNING, "Invalid %s '%s'\n", varname, value); - } else if (!strcasecmp(varname, "tlsbindport") || !strcasecmp(varname, "sslbindport")) { - tls_desc->local_address.sin_port = htons(atoi(value)); } else if (!strcasecmp(varname, "tlsclientmethod") || !strcasecmp(varname, "sslclientmethod")) { if (!strcasecmp(value, "tlsv1")) { ast_set_flag(&tls_cfg->flags, AST_SSL_TLSV1_CLIENT); |