diff options
author | delphij <delphij@FreeBSD.org> | 2015-07-15 19:21:26 +0000 |
---|---|---|
committer | delphij <delphij@FreeBSD.org> | 2015-07-15 19:21:26 +0000 |
commit | 2a25cee78ab1d37e7d2bc40ae675646974d99f56 (patch) | |
tree | b0302ac4be59e104f4e1e54014561a1389397192 /contrib/ntp/libntp/ntp_rfc2553.c | |
parent | a0741a75537b2e0514472ac3b28afc55a7846c30 (diff) | |
download | FreeBSD-src-2a25cee78ab1d37e7d2bc40ae675646974d99f56.zip FreeBSD-src-2a25cee78ab1d37e7d2bc40ae675646974d99f56.tar.gz |
MFC r280849,280915-280916,281015-281016,282097,282408,282415,283542,
284864,285169-285170,285435:
ntp 4.2.8p3.
Relnotes: yes
Approved by: re (?)
Diffstat (limited to 'contrib/ntp/libntp/ntp_rfc2553.c')
-rw-r--r-- | contrib/ntp/libntp/ntp_rfc2553.c | 177 |
1 files changed, 155 insertions, 22 deletions
diff --git a/contrib/ntp/libntp/ntp_rfc2553.c b/contrib/ntp/libntp/ntp_rfc2553.c index 017ef83..f267999 100644 --- a/contrib/ntp/libntp/ntp_rfc2553.c +++ b/contrib/ntp/libntp/ntp_rfc2553.c @@ -69,7 +69,9 @@ #include <sys/types.h> #include <ctype.h> +#ifdef HAVE_SYS_SOCKET_H #include <sys/socket.h> +#endif #include <isc/net.h> #ifdef HAVE_NETINET_IN_H #include <netinet/in.h> @@ -78,8 +80,152 @@ #include "ntpd.h" #include "ntp_malloc.h" -#include "ntp_stdlib.h" #include "ntp_string.h" +#include "ntp_debug.h" + + +/* + * copy_addrinfo() - copy a single addrinfo to malloc()'d block. + * copy_addrinfo_list() - copy an addrinfo list to malloc()'d block. + * + * Copies an addrinfo list and its associated data to a contiguous block + * of storage from emalloc(). Callback routines invoked via + * getaddrinfo_sometime() have access to the resulting addrinfo list + * only until they return. This routine provides an easy way to make a + * persistent copy. Although the list provided to gai_sometime_callback + * routines is similarly contiguous, to keep this code usable in any + * context where we might want to duplicate an addrinfo list, it does + * not require the input list be contiguous. + * + * The returned list head pointer is passed to free() to release the + * entire list. + * + * In keeping with the rest of the NTP distribution, sockaddr_u is used + * in preference to struct sockaddr_storage, which is a member of the + * former union and so compatible. + * + * The rest of ntp_rfc2553.c is conditioned on ISC_PLATFORM_HAVEIPV6 + * not being defined, copy_addrinfo_*() are exceptions. + */ +struct addrinfo * copy_addrinfo_common(const struct addrinfo *, int +#ifdef EREALLOC_CALLSITE + , + const char *, int +#endif + ); + + +struct addrinfo * +copy_addrinfo_impl( + const struct addrinfo * src +#ifdef EREALLOC_CALLSITE + , + const char * caller_file, + int caller_line +#endif + ) +{ + return copy_addrinfo_common(src, TRUE +#ifdef EREALLOC_CALLSITE + , + caller_file, caller_line +#endif + ); +} + + +struct addrinfo * +copy_addrinfo_list_impl( + const struct addrinfo * src +#ifdef EREALLOC_CALLSITE + , + const char * caller_file, + int caller_line +#endif + ) +{ + return copy_addrinfo_common(src, FALSE +#ifdef EREALLOC_CALLSITE + , + caller_file, caller_line +#endif + ); +} + + +struct addrinfo * +copy_addrinfo_common( + const struct addrinfo * src, + int just_one +#ifdef EREALLOC_CALLSITE + , + const char * caller_file, + int caller_line +#endif + ) +{ + const struct addrinfo * ai_src; + const struct addrinfo * ai_nxt; + struct addrinfo * ai_cpy; + struct addrinfo * dst; + sockaddr_u * psau; + char * pcanon; + u_int elements; + size_t octets; + size_t canons_octets; + size_t str_octets; + + elements = 0; + canons_octets = 0; + + for (ai_src = src; NULL != ai_src; ai_src = ai_nxt) { + if (just_one) + ai_nxt = NULL; + else + ai_nxt = ai_src->ai_next; + ++elements; + if (NULL != ai_src->ai_canonname) + canons_octets += 1 + strlen(ai_src->ai_canonname); + } + + octets = elements * (sizeof(*ai_cpy) + sizeof(*psau)); + octets += canons_octets; + + dst = erealloczsite(NULL, octets, 0, TRUE, caller_file, + caller_line); + ai_cpy = dst; + psau = (void *)(ai_cpy + elements); + pcanon = (void *)(psau + elements); + + for (ai_src = src; NULL != ai_src; ai_src = ai_nxt) { + if (just_one) + ai_nxt = NULL; + else + ai_nxt = ai_src->ai_next; + *ai_cpy = *ai_src; + REQUIRE(ai_src->ai_addrlen <= sizeof(sockaddr_u)); + memcpy(psau, ai_src->ai_addr, ai_src->ai_addrlen); + ai_cpy->ai_addr = &psau->sa; + ++psau; + if (NULL != ai_cpy->ai_canonname) { + ai_cpy->ai_canonname = pcanon; + str_octets = 1 + strlen(ai_src->ai_canonname); + memcpy(pcanon, ai_src->ai_canonname, str_octets); + pcanon += str_octets; + } + if (NULL != ai_cpy->ai_next) { + if (just_one) + ai_cpy->ai_next = NULL; + else + ai_cpy->ai_next = ai_cpy + 1; + } + ++ai_cpy; + } + NTP_ENSURE(pcanon == ((char *)dst + octets)); + + return dst; +} + #ifndef ISC_PLATFORM_HAVEIPV6 @@ -127,8 +273,8 @@ DNSlookup_name( } #endif -static int do_nodename P((const char *nodename, struct addrinfo *ai, - const struct addrinfo *hints)); +static int do_nodename (const char *nodename, struct addrinfo *ai, + const struct addrinfo *hints); int getaddrinfo (const char *nodename, const char *servname, @@ -288,7 +434,6 @@ getnameinfo (const struct sockaddr *sa, u_int salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { struct hostent *hp; - int namelen; if (sa->sa_family != AF_INET) return (EAI_FAMILY); @@ -301,16 +446,8 @@ getnameinfo (const struct sockaddr *sa, u_int salen, char *host, else return (EAI_FAIL); } - if (host != NULL && hostlen > 0) { - /* - * Don't exceed buffer - */ - namelen = min(strlen(hp->h_name), hostlen - 1); - if (namelen > 0) { - strncpy(host, hp->h_name, namelen); - host[namelen] = '\0'; - } - } + if (host != NULL && hostlen > 0) + strlcpy(host, hp->h_name, hostlen); return (0); } @@ -362,7 +499,7 @@ do_nodename( sockin6->sin6_addr = in6addr_any; */ } -#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR +#ifdef ISC_PLATFORM_HAVESALEN ai->ai_addr->sa_len = SOCKLEN(ai->ai_addr); #endif @@ -428,15 +565,11 @@ do_nodename( sockin = (struct sockaddr_in *)ai->ai_addr; memcpy(&sockin->sin_addr, hp->h_addr, hp->h_length); ai->ai_addr->sa_family = hp->h_addrtype; -#ifdef HAVE_SA_LEN_IN_STRUCT_SOCKADDR +#ifdef ISC_PLATFORM_HAVESALEN ai->ai_addr->sa_len = sizeof(struct sockaddr); #endif - if (hints != NULL && hints->ai_flags & AI_CANONNAME) { - ai->ai_canonname = malloc(strlen(hp->h_name) + 1); - if (ai->ai_canonname == NULL) - return (EAI_MEMORY); - strcpy(ai->ai_canonname, hp->h_name); - } + if (hints != NULL && (hints->ai_flags & AI_CANONNAME)) + ai->ai_canonname = estrdup(hp->h_name); return (0); } |