From 3cf09f40f749c8889de7d2b1aadf05d122ccba4f Mon Sep 17 00:00:00 2001 From: Sean Bright Date: Mon, 27 Feb 2012 16:31:24 +0000 Subject: [PATCH] Convert netsock.h over to use ast_sockaddrs rather than sockaddr_in and update chan_iax2 to pass in the correct types. chan_iax2 is the only consumer for the various ast_netsock_* functions in trunk at this point, so this feels like a safe change to make. git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@357005 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- channels/chan_iax2.c | 55 +++++++++++++++++++------------------- include/asterisk/netsock.h | 7 ++--- main/netsock.c | 48 +++++++++++++++------------------ 3 files changed, 52 insertions(+), 58 deletions(-) diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 543726c314..24f49d8bf4 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -12266,19 +12266,17 @@ static int get_auth_methods(const char *value) /*! \brief Check if address can be used as packet source. \return 0 address available, 1 address unavailable, -1 error */ -static int check_srcaddr(struct sockaddr *sa, socklen_t salen) +static int check_srcaddr(struct ast_sockaddr *addr) { int sd; - int res; - sd = socket(AF_INET, SOCK_DGRAM, 0); + sd = socket(ast_sockaddr_is_ipv4(addr) ? AF_INET : AF_INET6, SOCK_DGRAM, 0); if (sd < 0) { ast_log(LOG_ERROR, "Socket: %s\n", strerror(errno)); return -1; } - res = bind(sd, sa, salen); - if (res < 0) { + if (ast_bind(sd, addr) < 0) { ast_debug(1, "Can't bind: %s\n", strerror(errno)); close(sd); return 1; @@ -12293,19 +12291,18 @@ static int check_srcaddr(struct sockaddr *sa, socklen_t salen) not found. */ static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr) { - struct sockaddr_in sin; - struct ast_sockaddr sin_tmp; + struct ast_sockaddr addr; int nonlocal = 1; int port = IAX_DEFAULT_PORTNO; int sockfd = defaultsockfd; char *tmp; - char *addr; + char *host; char *portstr; if (!(tmp = ast_strdupa(srcaddr))) return -1; - addr = strsep(&tmp, ":"); + host = strsep(&tmp, ":"); portstr = tmp; if (portstr) { @@ -12314,27 +12311,25 @@ static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr) port = IAX_DEFAULT_PORTNO; } - sin_tmp.ss.ss_family = AF_INET; - if (!ast_get_ip(&sin_tmp, addr)) { + addr.ss.ss_family = AF_INET; + + if (!ast_get_ip(&addr, host)) { struct ast_netsock *sock; - int res; - ast_sockaddr_to_sin(&sin_tmp, &sin); - sin.sin_port = 0; - sin.sin_family = AF_INET; - res = check_srcaddr((struct sockaddr *) &sin, sizeof(sin)); - if (res == 0) { + if (check_srcaddr(&addr) == 0) { /* ip address valid. */ - sin.sin_port = htons(port); - if (!(sock = ast_netsock_find(netsock, &sin))) - sock = ast_netsock_find(outsock, &sin); + ast_sockaddr_set_port(&addr, port); + + if (!(sock = ast_netsock_find(netsock, &addr))) + sock = ast_netsock_find(outsock, &addr); if (sock) { sockfd = ast_netsock_sockfd(sock); nonlocal = 0; } else { /* INADDR_ANY matches anyway! */ - sin.sin_addr.s_addr = INADDR_ANY; - if (ast_netsock_find(netsock, &sin)) { + ast_sockaddr_parse(&addr, "0.0.0.0", 0); + ast_sockaddr_set_port(&addr, port); + if (ast_netsock_find(netsock, &addr)) { sock = ast_netsock_bind(outsock, io, srcaddr, port, qos.tos, qos.cos, socket_read, NULL); if (sock) { sockfd = ast_netsock_sockfd(sock); @@ -12351,13 +12346,17 @@ static int peer_set_srcaddr(struct iax2_peer *peer, const char *srcaddr) peer->sockfd = sockfd; if (nonlocal == 1) { - ast_log(LOG_WARNING, "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", - srcaddr, peer->name); + ast_log(LOG_WARNING, + "Non-local or unbound address specified (%s) in sourceaddress for '%s', reverting to default\n", + srcaddr, + peer->name); + return -1; + } else if (nonlocal == 2) { + ast_log(LOG_WARNING, + "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", + srcaddr, + peer->name); return -1; - } else if (nonlocal == 2) { - ast_log(LOG_WARNING, "Unable to bind to sourceaddress '%s' for '%s', reverting to default\n", - srcaddr, peer->name); - return -1; } else { ast_debug(1, "Using sourceaddress %s for '%s'\n", srcaddr, peer->name); return 0; diff --git a/include/asterisk/netsock.h b/include/asterisk/netsock.h index 01c877b91d..f85bd381a9 100644 --- a/include/asterisk/netsock.h +++ b/include/asterisk/netsock.h @@ -30,6 +30,7 @@ extern "C" { #include "asterisk/network.h" #include "asterisk/io.h" +#include "asterisk/netsock2.h" struct ast_netsock; @@ -43,12 +44,12 @@ struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_co const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data); struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, - struct sockaddr_in *bindaddr, int tos, int cos, ast_io_cb callback, void *data); + struct ast_sockaddr *bindaddr, int tos, int cos, ast_io_cb callback, void *data); int ast_netsock_release(struct ast_netsock_list *list); struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, - struct sockaddr_in *sa); + struct ast_sockaddr *addr); /*! * \deprecated Use ast_seq_qos in netsock2.h which properly handles IPv4 and IPv6 @@ -58,7 +59,7 @@ int ast_netsock_set_qos(int sockfd, int tos, int cos, const char *desc); int ast_netsock_sockfd(const struct ast_netsock *ns); -const struct sockaddr_in *ast_netsock_boundaddr(const struct ast_netsock *ns); +const struct ast_sockaddr *ast_netsock_boundaddr(const struct ast_netsock *ns); void *ast_netsock_data(const struct ast_netsock *ns); diff --git a/main/netsock.c b/main/netsock.c index d178fbed49..334617da6b 100644 --- a/main/netsock.c +++ b/main/netsock.c @@ -48,7 +48,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") struct ast_netsock { ASTOBJ_COMPONENTS(struct ast_netsock); - struct sockaddr_in bindaddr; + struct ast_sockaddr bindaddr; int sockfd; int *ioref; struct io_context *ioc; @@ -89,22 +89,22 @@ int ast_netsock_release(struct ast_netsock_list *list) return 0; } -struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, - struct sockaddr_in *sa) +struct ast_netsock *ast_netsock_find(struct ast_netsock_list *list, struct ast_sockaddr *addr) { struct ast_netsock *sock = NULL; ASTOBJ_CONTAINER_TRAVERSE(list, !sock, { ASTOBJ_RDLOCK(iterator); - if (!inaddrcmp(&iterator->bindaddr, sa)) + if (!ast_sockaddr_cmp(&iterator->bindaddr, addr)) { sock = iterator; + } ASTOBJ_UNLOCK(iterator); }); return sock; } -struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct sockaddr_in *bindaddr, int tos, int cos, ast_io_cb callback, void *data) +struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct io_context *ioc, struct ast_sockaddr *bindaddr, int tos, int cos, ast_io_cb callback, void *data) { int netsocket = -1; int *ioref; @@ -120,10 +120,13 @@ struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct i return NULL; } if (setsockopt(netsocket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseFlag, sizeof reuseFlag) < 0) { - ast_log(LOG_WARNING, "Error setting SO_REUSEADDR on sockfd '%d'\n", netsocket); + ast_log(LOG_WARNING, "Error setting SO_REUSEADDR on sockfd '%d'\n", netsocket); } - if (bind(netsocket,(struct sockaddr *)bindaddr, sizeof(struct sockaddr_in))) { - ast_log(LOG_ERROR, "Unable to bind to %s port %d: %s\n", ast_inet_ntoa(bindaddr->sin_addr), ntohs(bindaddr->sin_port), strerror(errno)); + if (ast_bind(netsocket, bindaddr)) { + ast_log(LOG_ERROR, + "Unable to bind to %s: %s\n", + ast_sockaddr_stringify(bindaddr), + strerror(errno)); close(netsocket); return NULL; } @@ -161,26 +164,17 @@ int ast_netsock_set_qos(int sockfd, int tos, int cos, const char *desc) struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_context *ioc, const char *bindinfo, int defaultport, int tos, int cos, ast_io_cb callback, void *data) { - struct sockaddr_in sin; - char *tmp; - char *host; - char *port; - int portno; - - memset(&sin, 0, sizeof(sin)); - sin.sin_family = AF_INET; - sin.sin_port = htons(defaultport); - tmp = ast_strdupa(bindinfo); - - host = strsep(&tmp, ":"); - port = tmp; + struct ast_sockaddr addr; - if (port && ((portno = atoi(port)) > 0)) - sin.sin_port = htons(portno); + if (ast_sockaddr_parse(&addr, bindinfo, 0)) { + if (!ast_sockaddr_port(&addr)) { + ast_sockaddr_set_port(&addr, defaultport); + } - inet_aton(host, &sin.sin_addr); + return ast_netsock_bindaddr(list, ioc, &addr, tos, cos, callback, data); + } - return ast_netsock_bindaddr(list, ioc, &sin, tos, cos, callback, data); + return NULL; } int ast_netsock_sockfd(const struct ast_netsock *ns) @@ -188,9 +182,9 @@ int ast_netsock_sockfd(const struct ast_netsock *ns) return ns ? ns-> sockfd : -1; } -const struct sockaddr_in *ast_netsock_boundaddr(const struct ast_netsock *ns) +const struct ast_sockaddr *ast_netsock_boundaddr(const struct ast_netsock *ns) { - return &(ns->bindaddr); + return &ns->bindaddr; } void *ast_netsock_data(const struct ast_netsock *ns)