diff options
author | Michael L. Young <elgueromexicano@gmail.com> | 2013-10-04 21:41:58 +0000 |
---|---|---|
committer | Michael L. Young <elgueromexicano@gmail.com> | 2013-10-04 21:41:58 +0000 |
commit | 2af53640c88464bb338753120945159e8e1a9cb9 (patch) | |
tree | 65951c78f0d8b20bb58808b5fa12444b4de38154 /main | |
parent | 21902bf9647823049358cdf386150d4b9b15e75e (diff) |
Add IPv6 Support To chan_iax2
This patch adds IPv6 support to chan_iax2. Yay!
(closes issue ASTERISK-22025)
Patches:
iax2-ipv6-v5-reviewboard.diff by Michael L. Young (license 5026)
Review: https://reviewboard.asterisk.org/r/2660/
........
Merged revisions 400567 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@400568 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r-- | main/acl.c | 63 | ||||
-rw-r--r-- | main/netsock.c | 8 | ||||
-rw-r--r-- | main/netsock2.c | 31 |
3 files changed, 35 insertions, 67 deletions
diff --git a/main/acl.c b/main/acl.c index 148cb0825..a4567beda 100644 --- a/main/acl.c +++ b/main/acl.c @@ -349,63 +349,6 @@ struct ast_acl_list *ast_duplicate_acl_list(struct ast_acl_list *original) /*! * \brief - * Isolate a 32-bit section of an IPv6 address - * - * An IPv6 address can be divided into 4 32-bit chunks. This gives - * easy access to one of these chunks. - * - * \param sin6 A pointer to a struct sockaddr_in6 - * \param index Which 32-bit chunk to operate on. Must be in the range 0-3. - */ -#define V6_WORD(sin6, index) ((uint32_t *)&((sin6)->sin6_addr))[(index)] - -/*! - * \brief - * Apply a netmask to an address and store the result in a separate structure. - * - * When dealing with IPv6 addresses, one cannot apply a netmask with a simple - * logical and operation. Furthermore, the incoming address may be an IPv4 address - * and need to be mapped properly before attempting to apply a rule. - * - * \param addr The IP address to apply the mask to. - * \param netmask The netmask configured in the host access rule. - * \param result The resultant address after applying the netmask to the given address - * \retval 0 Successfully applied netmask - * \retval -1 Failed to apply netmask - */ -static int apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask, - struct ast_sockaddr *result) -{ - int res = 0; - - if (ast_sockaddr_is_ipv4(addr)) { - struct sockaddr_in result4 = { 0, }; - struct sockaddr_in *addr4 = (struct sockaddr_in *) &addr->ss; - struct sockaddr_in *mask4 = (struct sockaddr_in *) &netmask->ss; - result4.sin_family = AF_INET; - result4.sin_addr.s_addr = addr4->sin_addr.s_addr & mask4->sin_addr.s_addr; - ast_sockaddr_from_sin(result, &result4); - } else if (ast_sockaddr_is_ipv6(addr)) { - struct sockaddr_in6 result6 = { 0, }; - struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &addr->ss; - struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *) &netmask->ss; - int i; - result6.sin6_family = AF_INET6; - for (i = 0; i < 4; ++i) { - V6_WORD(&result6, i) = V6_WORD(addr6, i) & V6_WORD(mask6, i); - } - memcpy(&result->ss, &result6, sizeof(result6)); - result->len = sizeof(result6); - } else { - /* Unsupported address scheme */ - res = -1; - } - - return res; -} - -/*! - * \brief * Parse a netmask in CIDR notation * * \details @@ -468,8 +411,6 @@ static int parse_cidr_mask(struct ast_sockaddr *addr, int is_v4, const char *mas return 0; } - - void ast_append_acl(const char *sense, const char *stuff, struct ast_acl_list **path, int *error, int *named_acl_flag) { struct ast_acl *acl = NULL; @@ -693,7 +634,7 @@ struct ast_ha *ast_append_ha(const char *sense, const char *stuff, struct ast_ha return ret; } - if (apply_netmask(&ha->addr, &ha->netmask, &ha->addr)) { + if (ast_sockaddr_apply_netmask(&ha->addr, &ha->netmask, &ha->addr)) { /* This shouldn't happen because ast_sockaddr_parse would * have failed much earlier on an unsupported address scheme */ @@ -805,7 +746,7 @@ enum ast_acl_sense ast_apply_ha(const struct ast_ha *ha, const struct ast_sockad /* For each rule, if this address and the netmask = the net address apply the current rule */ - if (apply_netmask(addr_to_use, ¤t_ha->netmask, &result)) { + if (ast_sockaddr_apply_netmask(addr_to_use, ¤t_ha->netmask, &result)) { /* Unlikely to happen since we know the address to be IPv4 or IPv6 */ continue; } diff --git a/main/netsock.c b/main/netsock.c index 598bc4b70..18bf561f1 100644 --- a/main/netsock.c +++ b/main/netsock.c @@ -117,7 +117,7 @@ struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct i const int reuseFlag = 1; /* Make a UDP socket */ - netsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); + netsocket = socket(ast_sockaddr_is_ipv6(bindaddr) ? AST_AF_INET6 : AST_AF_INET, SOCK_DGRAM, IPPROTO_IP); if (netsocket < 0) { ast_log(LOG_ERROR, "Unable to create network socket: %s\n", strerror(errno)); @@ -155,7 +155,7 @@ struct ast_netsock *ast_netsock_bindaddr(struct ast_netsock_list *list, struct i ns->ioc = ioc; ns->sockfd = netsocket; ns->data = data; - memcpy(&ns->bindaddr, bindaddr, sizeof(ns->bindaddr)); + ast_sockaddr_copy(&ns->bindaddr, bindaddr); ASTOBJ_CONTAINER_LINK(list, ns); return ns; @@ -171,10 +171,6 @@ struct ast_netsock *ast_netsock_bind(struct ast_netsock_list *list, struct io_co struct ast_sockaddr addr; if (ast_sockaddr_parse(&addr, bindinfo, 0)) { - if (!ast_sockaddr_is_ipv4(&addr)) { - ast_log(LOG_WARNING, "Only IPv4 addresses are supported at this time.\n"); - return NULL; - } if (!ast_sockaddr_port(&addr)) { ast_sockaddr_set_port(&addr, defaultport); diff --git a/main/netsock2.c b/main/netsock2.c index aa5e17d9e..bee88c2f8 100644 --- a/main/netsock2.c +++ b/main/netsock2.c @@ -297,6 +297,37 @@ cleanup: return res_cnt; } +int ast_sockaddr_apply_netmask(const struct ast_sockaddr *addr, const struct ast_sockaddr *netmask, + struct ast_sockaddr *result) +{ + int res = 0; + + if (ast_sockaddr_is_ipv4(addr)) { + struct sockaddr_in result4 = { 0, }; + struct sockaddr_in *addr4 = (struct sockaddr_in *) &addr->ss; + struct sockaddr_in *mask4 = (struct sockaddr_in *) &netmask->ss; + result4.sin_family = AF_INET; + result4.sin_addr.s_addr = addr4->sin_addr.s_addr & mask4->sin_addr.s_addr; + ast_sockaddr_from_sin(result, &result4); + } else if (ast_sockaddr_is_ipv6(addr)) { + struct sockaddr_in6 result6 = { 0, }; + struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) &addr->ss; + struct sockaddr_in6 *mask6 = (struct sockaddr_in6 *) &netmask->ss; + int i; + result6.sin6_family = AF_INET6; + for (i = 0; i < 4; ++i) { + V6_WORD(&result6, i) = V6_WORD(addr6, i) & V6_WORD(mask6, i); + } + memcpy(&result->ss, &result6, sizeof(result6)); + result->len = sizeof(result6); + } else { + /* Unsupported address scheme */ + res = -1; + } + + return res; +} + int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b) { const struct ast_sockaddr *a_tmp, *b_tmp; |