diff options
author | Peter Wemm <peter@FreeBSD.org> | 2018-10-08 08:24:14 +0000 |
---|---|---|
committer | Peter Wemm <peter@FreeBSD.org> | 2018-10-08 08:24:14 +0000 |
commit | f7eb533f85d0941dbf6edb3081f065e4c010b8cc (patch) | |
tree | a9a3ba945deee0800d3818a48c45323608935019 /network_io/unix/sockaddr.c | |
parent | df84d2567179e9d8867957c089683d753016bd75 (diff) |
Diffstat (limited to 'network_io/unix/sockaddr.c')
-rw-r--r-- | network_io/unix/sockaddr.c | 95 |
1 files changed, 84 insertions, 11 deletions
diff --git a/network_io/unix/sockaddr.c b/network_io/unix/sockaddr.c index e6d7e0be93d81..a375f72ece3b0 100644 --- a/network_io/unix/sockaddr.c +++ b/network_io/unix/sockaddr.c @@ -167,6 +167,14 @@ void apr_sockaddr_vars_set(apr_sockaddr_t *addr, int family, apr_port_t port) addr->ipaddr_len = sizeof(struct in6_addr); } #endif +#if APR_HAVE_SOCKADDR_UN + else if (family == APR_UNIX) { + addr->salen = sizeof(struct sockaddr_un); + addr->addr_str_len = sizeof(addr->sa.unx.sun_path);; + addr->ipaddr_ptr = &(addr->sa.unx.sun_path); + addr->ipaddr_len = addr->addr_str_len; + } +#endif } APR_DECLARE(apr_status_t) apr_socket_addr_get(apr_sockaddr_t **sa, @@ -269,19 +277,13 @@ APR_DECLARE(apr_status_t) apr_parse_addr_port(char **addr, return APR_EINVAL; } addrlen = scope_delim - str - 1; - *scope_id = apr_palloc(p, end_bracket - scope_delim); - memcpy(*scope_id, scope_delim + 1, end_bracket - scope_delim - 1); - (*scope_id)[end_bracket - scope_delim - 1] = '\0'; + *scope_id = apr_pstrmemdup(p, scope_delim + 1, end_bracket - scope_delim - 1); } else { addrlen = addrlen - 2; /* minus 2 for '[' and ']' */ } - *addr = apr_palloc(p, addrlen + 1); - memcpy(*addr, - str + 1, - addrlen); - (*addr)[addrlen] = '\0'; + *addr = apr_pstrmemdup(p, str + 1, addrlen); if (apr_inet_pton(AF_INET6, *addr, &ipaddr) != 1) { *addr = NULL; *scope_id = NULL; @@ -295,9 +297,7 @@ APR_DECLARE(apr_status_t) apr_parse_addr_port(char **addr, /* XXX If '%' is not a valid char in a DNS name, we *could* check * for bogus scope ids first. */ - *addr = apr_palloc(p, addrlen + 1); - memcpy(*addr, str, addrlen); - (*addr)[addrlen] = '\0'; + *addr = apr_pstrmemdup(p, str, addrlen); } return APR_SUCCESS; } @@ -622,6 +622,33 @@ APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa, } #endif } + if (family == APR_UNSPEC && hostname && *hostname == '/') { + family = APR_UNIX; + } + if (family == APR_UNIX) { +#if APR_HAVE_SOCKADDR_UN + if (hostname && *hostname == '/') { + *sa = apr_pcalloc(p, sizeof(apr_sockaddr_t)); + (*sa)->pool = p; + apr_cpystrn((*sa)->sa.unx.sun_path, hostname, + sizeof((*sa)->sa.unx.sun_path)); + (*sa)->hostname = apr_pstrdup(p, hostname); + (*sa)->family = APR_UNIX; + (*sa)->sa.unx.sun_family = APR_UNIX; + (*sa)->salen = sizeof(struct sockaddr_un); + (*sa)->addr_str_len = sizeof((*sa)->sa.unx.sun_path); + (*sa)->ipaddr_ptr = &((*sa)->sa.unx.sun_path); + (*sa)->ipaddr_len = (*sa)->addr_str_len; + + return APR_SUCCESS; + } + else +#endif + { + *sa = NULL; + return APR_ENOTIMPL; + } + } #if !APR_HAVE_IPV6 /* What may happen is that APR is not IPv6-enabled, but we're still * going to call getaddrinfo(), so we have to tell the OS we only @@ -636,6 +663,42 @@ APR_DECLARE(apr_status_t) apr_sockaddr_info_get(apr_sockaddr_t **sa, return find_addresses(sa, hostname, family, port, flags, p); } +APR_DECLARE(apr_status_t) apr_sockaddr_info_copy(apr_sockaddr_t **dst, + const apr_sockaddr_t *src, + apr_pool_t *p) +{ + apr_sockaddr_t *d; + const apr_sockaddr_t *s; + + for (*dst = d = NULL, s = src; s; s = s->next) { + if (!d) { + *dst = d = apr_pmemdup(p, s, sizeof *s); + } + else { + d = d->next = apr_pmemdup(p, s, sizeof *s); + } + if (s->hostname) { + if (s == src || s->hostname != src->hostname) { + d->hostname = apr_pstrdup(p, s->hostname); + } + else { + d->hostname = (*dst)->hostname; + } + } + if (s->servname) { + if (s == src || s->servname != src->servname) { + d->servname = apr_pstrdup(p, s->servname); + } + else { + d->servname = (*dst)->servname; + } + } + d->pool = p; + apr_sockaddr_vars_set(d, s->family, s->port); + } + return APR_SUCCESS; +} + APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname, apr_sockaddr_t *sockaddr, apr_int32_t flags) @@ -674,6 +737,12 @@ APR_DECLARE(apr_status_t) apr_getnameinfo(char **hostname, tmphostname, sizeof(tmphostname), NULL, 0, flags != 0 ? flags : NI_NAMEREQD); } +#if APR_HAVE_SOCKADDR_UN + else if (sockaddr->family == APR_UNIX) { + *hostname = sockaddr->hostname; + return APR_SUCCESS; + } +#endif else #endif rc = getnameinfo((const struct sockaddr *)&sockaddr->sa, sockaddr->salen, @@ -985,6 +1054,10 @@ static apr_status_t parse_ip(apr_ipsubnet_t *ipsub, const char *ipstr, int netwo static int looks_like_ip(const char *ipstr) { + if (strlen(ipstr) == 0) { + return 0; + } + if (strchr(ipstr, ':')) { /* definitely not a hostname; assume it is intended to be an IPv6 address */ return 1; |