aboutsummaryrefslogtreecommitdiff
path: root/libbb
diff options
context:
space:
mode:
Diffstat (limited to 'libbb')
-rw-r--r--libbb/xconnect.c41
1 files changed, 36 insertions, 5 deletions
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(
161IF_FEATURE_IPV6(sa_family_t af,) 161IF_FEATURE_IPV6(sa_family_t af,)
162 int ai_flags) 162 int ai_flags)
163{ 163{
164IF_NOT_FEATURE_IPV6(sa_family_t af = AF_INET;)
164 int rc; 165 int rc;
165 len_and_sockaddr *r; 166 len_and_sockaddr *r;
166 struct addrinfo *result = NULL; 167 struct addrinfo *result = NULL;
@@ -221,12 +222,40 @@ IF_FEATURE_IPV6(sa_family_t af,)
221 skip: ; 222 skip: ;
222 } 223 }
223 224
225 /* Next two if blocks allow to skip getaddrinfo()
226 * in case host is a numeric IP(v6) address,
227 * getaddrinfo() initializes DNS resolution machinery,
228 * scans network config and such - tens of syscalls.
229 */
230 /* If we were not asked specifically for IPv6,
231 * check whether this is a numeric IPv4 */
232 IF_FEATURE_IPV6(if(af != AF_INET6)) {
233 struct in_addr in4;
234 if (inet_aton(host, &in4) != 0) {
235 r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_in));
236 r->len = sizeof(struct sockaddr_in);
237 r->u.sa.sa_family = AF_INET;
238 r->u.sin.sin_addr = in4;
239 goto set_port;
240 }
241 }
242#if ENABLE_FEATURE_IPV6
243 /* If we were not asked specifically for IPv4,
244 * check whether this is a numeric IPv6 */
245 if (af != AF_INET) {
246 struct in6_addr in6;
247 if (inet_pton(AF_INET6, host, &in6) > 0) {
248 r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_in6));
249 r->len = sizeof(struct sockaddr_in6);
250 r->u.sa.sa_family = AF_INET6;
251 r->u.sin6.sin6_addr = in6;
252 goto set_port;
253 }
254 }
255#endif
256
224 memset(&hint, 0 , sizeof(hint)); 257 memset(&hint, 0 , sizeof(hint));
225#if !ENABLE_FEATURE_IPV6
226 hint.ai_family = AF_INET; /* do not try to find IPv6 */
227#else
228 hint.ai_family = af; 258 hint.ai_family = af;
229#endif
230 /* Needed. Or else we will get each address thrice (or more) 259 /* Needed. Or else we will get each address thrice (or more)
231 * for each possible socket type (tcp,udp,raw...): */ 260 * for each possible socket type (tcp,udp,raw...): */
232 hint.ai_socktype = SOCK_STREAM; 261 hint.ai_socktype = SOCK_STREAM;
@@ -250,9 +279,11 @@ IF_FEATURE_IPV6(sa_family_t af,)
250 } 279 }
251 } 280 }
252#endif 281#endif
253 r = xmalloc(offsetof(len_and_sockaddr, u.sa) + used_res->ai_addrlen); 282 r = xmalloc(LSA_LEN_SIZE + used_res->ai_addrlen);
254 r->len = used_res->ai_addrlen; 283 r->len = used_res->ai_addrlen;
255 memcpy(&r->u.sa, used_res->ai_addr, used_res->ai_addrlen); 284 memcpy(&r->u.sa, used_res->ai_addr, used_res->ai_addrlen);
285
286 IF_FEATURE_IPV6(set_port:)
256 set_nport(r, htons(port)); 287 set_nport(r, htons(port));
257 ret: 288 ret:
258 freeaddrinfo(result); 289 freeaddrinfo(result);