From ca6c7e42f93eb2b0ce246eafd8b0e4ac27414f6b Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 24 Nov 2009 07:07:42 +0100 Subject: ntp: simplifications; libbb: simpler resolution of numeric hostnames function old new delta str2sockaddr 405 567 +162 ntp_init 310 317 +7 scale_interval 58 59 +1 error_interval 22 23 +1 ntpd_main 3257 3214 -43 ------------------------------------------------------------------------------ (add/remove: 0/0 grow/shrink: 4/1 up/down: 171/-43) Total: 128 bytes Signed-off-by: Denys Vlasenko --- libbb/xconnect.c | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) (limited to 'libbb') diff --git a/libbb/xconnect.c b/libbb/xconnect.c index f018ca9d9..81a2b048f 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -161,6 +161,7 @@ static len_and_sockaddr* str2sockaddr( IF_FEATURE_IPV6(sa_family_t af,) int ai_flags) { +IF_NOT_FEATURE_IPV6(sa_family_t af = AF_INET;) int rc; len_and_sockaddr *r; struct addrinfo *result = NULL; @@ -221,12 +222,40 @@ IF_FEATURE_IPV6(sa_family_t af,) skip: ; } + /* Next two if blocks allow to skip getaddrinfo() + * in case host is a numeric IP(v6) address, + * getaddrinfo() initializes DNS resolution machinery, + * scans network config and such - tens of syscalls. + */ + /* If we were not asked specifically for IPv6, + * check whether this is a numeric IPv4 */ + IF_FEATURE_IPV6(if(af != AF_INET6)) { + struct in_addr in4; + if (inet_aton(host, &in4) != 0) { + r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_in)); + r->len = sizeof(struct sockaddr_in); + r->u.sa.sa_family = AF_INET; + r->u.sin.sin_addr = in4; + goto set_port; + } + } +#if ENABLE_FEATURE_IPV6 + /* If we were not asked specifically for IPv4, + * check whether this is a numeric IPv6 */ + if (af != AF_INET) { + struct in6_addr in6; + if (inet_pton(AF_INET6, host, &in6) > 0) { + r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_in6)); + r->len = sizeof(struct sockaddr_in6); + r->u.sa.sa_family = AF_INET6; + r->u.sin6.sin6_addr = in6; + goto set_port; + } + } +#endif + memset(&hint, 0 , sizeof(hint)); -#if !ENABLE_FEATURE_IPV6 - hint.ai_family = AF_INET; /* do not try to find IPv6 */ -#else hint.ai_family = af; -#endif /* Needed. Or else we will get each address thrice (or more) * for each possible socket type (tcp,udp,raw...): */ hint.ai_socktype = SOCK_STREAM; @@ -250,9 +279,11 @@ IF_FEATURE_IPV6(sa_family_t af,) } } #endif - r = xmalloc(offsetof(len_and_sockaddr, u.sa) + used_res->ai_addrlen); + r = xmalloc(LSA_LEN_SIZE + used_res->ai_addrlen); r->len = used_res->ai_addrlen; memcpy(&r->u.sa, used_res->ai_addr, used_res->ai_addrlen); + + IF_FEATURE_IPV6(set_port:) set_nport(r, htons(port)); ret: freeaddrinfo(result); -- cgit v1.2.3