From 42823d597a9029ac497edda9102f61283630635b Mon Sep 17 00:00:00 2001 From: Denis Vlasenko Date: Sun, 4 Feb 2007 02:39:08 +0000 Subject: [PATCH] add x to IPv6 functions which can die --- include/libbb.h | 8 ++++---- libbb/xconnect.c | 41 +++++++++++++++++++++-------------------- networking/arping.c | 2 +- networking/dnsd.c | 2 +- networking/ftpgetput.c | 2 +- networking/nslookup.c | 2 +- networking/ping.c | 8 ++++---- networking/tftp.c | 2 +- networking/wget.c | 4 ++-- sysklogd/syslogd.c | 2 +- 10 files changed, 37 insertions(+), 36 deletions(-) diff --git a/include/libbb.h b/include/libbb.h index 44bd6e09d..dd23c704d 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -317,13 +317,13 @@ int xconnect_stream(const len_and_sockaddr *lsa); * Currently will return IPv4 or IPv6 sockaddrs only * (depending on host), but in theory nothing prevents e.g. * UNIX socket address being returned, IPX sockaddr etc... */ -len_and_sockaddr* host2sockaddr(const char *host, int port); +len_and_sockaddr* xhost2sockaddr(const char *host, int port); #if ENABLE_FEATURE_IPV6 /* Same, useful if you want to force family (e.g. IPv6) */ -len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af); +len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af); #else -/* [we evaluate af: think about "host_and_af2sockaddr(..., af++)"] */ -#define host_and_af2sockaddr(host, port, af) ((void)(af), host2sockaddr((host), (port))) +/* [we evaluate af: think about "xhost_and_af2sockaddr(..., af++)"] */ +#define xhost_and_af2sockaddr(host, port, af) ((void)(af), xhost2sockaddr((host), (port))) #endif /* Assign sin[6]_port member if the socket is of corresponding type, * otherwise no-op. Useful for ftp. diff --git a/libbb/xconnect.c b/libbb/xconnect.c index 2b35baab7..e5bdaac38 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c @@ -111,16 +111,19 @@ void set_nport(len_and_sockaddr *lsa, unsigned port) /* What? UNIX socket? IPX?? :) */ } +/* We hijack this constant to mean something else */ +/* It doesn't hurt because we will remove this bit anyway */ +#define DIE_ON_ERROR AI_CANONNAME + /* host: "1.2.3.4[:port]", "www.google.com[:port]" - * port: if neither of above specifies port # - */ + * port: if neither of above specifies port # */ static len_and_sockaddr* str2sockaddr( const char *host, int port, USE_FEATURE_IPV6(sa_family_t af,) int ai_flags) { int rc; - len_and_sockaddr *r; // = NULL; + len_and_sockaddr *r = NULL; struct addrinfo *result = NULL; const char *org_host = host; /* only for error msg */ const char *cp; @@ -158,14 +161,18 @@ USE_FEATURE_IPV6(sa_family_t af,) /* Needed. Or else we will get each address thrice (or more) * for each possible socket type (tcp,udp,raw...): */ hint.ai_socktype = SOCK_STREAM; - hint.ai_flags = ai_flags; + hint.ai_flags = ai_flags & ~DIE_ON_ERROR; rc = getaddrinfo(host, NULL, &hint, &result); - if (rc || !result) - bb_error_msg_and_die("bad address '%s'", org_host); + if (rc || !result) { + if (ai_flags & DIE_ON_ERROR) + bb_error_msg_and_die("bad address '%s'", org_host); + goto ret; + } r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); r->len = result->ai_addrlen; memcpy(&r->sa, result->ai_addr, result->ai_addrlen); set_nport(r, htons(port)); + ret: freeaddrinfo(result); return r; } @@ -174,20 +181,20 @@ USE_FEATURE_IPV6(sa_family_t af,) #endif #if ENABLE_FEATURE_IPV6 -len_and_sockaddr* host_and_af2sockaddr(const char *host, int port, sa_family_t af) +len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t af) { - return str2sockaddr(host, port, af, 0); + return str2sockaddr(host, port, af, DIE_ON_ERROR); } #endif -len_and_sockaddr* host2sockaddr(const char *host, int port) +len_and_sockaddr* xhost2sockaddr(const char *host, int port) { - return str2sockaddr(host, port, AF_UNSPEC, 0); + return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR); } -static len_and_sockaddr* dotted2sockaddr(const char *host, int port) +static len_and_sockaddr* xdotted2sockaddr(const char *host, int port) { - return str2sockaddr(host, port, AF_UNSPEC, NI_NUMERICHOST); + return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); } int xsocket_stream(len_and_sockaddr **lsap) @@ -220,10 +227,7 @@ int create_and_bind_stream_or_die(const char *bindaddr, int port) len_and_sockaddr *lsa; if (bindaddr && bindaddr[0]) { - lsa = dotted2sockaddr(bindaddr, port); - /* currently NULL check is in str2sockaddr */ - //if (!lsa) - // bb_error_msg_and_die("bad address '%s'", bindaddr); + lsa = xdotted2sockaddr(bindaddr, port); /* user specified bind addr dictates family */ fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); } else { @@ -241,10 +245,7 @@ int create_and_connect_stream_or_die(const char *peer, int port) int fd; len_and_sockaddr *lsa; - lsa = host2sockaddr(peer, port); - /* currently NULL check is in str2sockaddr */ - //if (!lsa) - // bb_error_msg_and_die("bad address '%s'", peer); + lsa = xhost2sockaddr(peer, port); fd = xsocket(lsa->sa.sa_family, SOCK_STREAM, 0); setsockopt_reuseaddr(fd); xconnect(fd, &lsa->sa, lsa->len); diff --git a/networking/arping.c b/networking/arping.c index 20c782f55..d71ac4930 100644 --- a/networking/arping.c +++ b/networking/arping.c @@ -307,7 +307,7 @@ int arping_main(int argc, char **argv) if (!inet_aton(target, &dst)) { len_and_sockaddr *lsa; - lsa = host_and_af2sockaddr(target, 0, AF_INET); + lsa = xhost_and_af2sockaddr(target, 0, AF_INET); memcpy(&dst, &lsa->sin.sin_addr.s_addr, 4); if (ENABLE_FEATURE_CLEAN_UP) free(lsa); diff --git a/networking/dnsd.c b/networking/dnsd.c index 6d1335e67..78722d6f6 100644 --- a/networking/dnsd.c +++ b/networking/dnsd.c @@ -377,7 +377,7 @@ int dnsd_main(int argc, char **argv) signal(SIGURG, SIG_IGN); #endif - lsa = host2sockaddr(listen_interface, port); + lsa = xhost2sockaddr(listen_interface, port); udps = xsocket(lsa->sa.sa_family, SOCK_DGRAM, 0); xbind(udps, &lsa->sa, lsa->len); // xlisten(udps, 50); - ?!! DGRAM sockets are never listened on I think? diff --git a/networking/ftpgetput.c b/networking/ftpgetput.c index dad1c9947..9b0510df9 100644 --- a/networking/ftpgetput.c +++ b/networking/ftpgetput.c @@ -346,7 +346,7 @@ int ftpgetput_main(int argc, char **argv) /* We want to do exactly _one_ DNS lookup, since some * sites (i.e. ftp.us.debian.org) use round-robin DNS * and we want to connect to only one IP... */ - server->lsa = host2sockaddr(argv[0], bb_lookup_port(port, "tcp", 21)); + server->lsa = xhost2sockaddr(argv[0], bb_lookup_port(port, "tcp", 21)); if (verbose_flag) { printf("Connecting to %s (%s)\n", argv[0], xmalloc_sockaddr2dotted(&server->lsa->sa, server->lsa->len)); diff --git a/networking/nslookup.c b/networking/nslookup.c index 14c05b3e6..8076aff98 100644 --- a/networking/nslookup.c +++ b/networking/nslookup.c @@ -49,7 +49,7 @@ static int print_host(const char *hostname, const char *header) { - /* We can't use host2sockaddr() - we want to get ALL addresses, + /* We can't use xhost2sockaddr() - we want to get ALL addresses, * not just one */ struct addrinfo *result = NULL; diff --git a/networking/ping.c b/networking/ping.c index d0e6f3ad1..e76584341 100644 --- a/networking/ping.c +++ b/networking/ping.c @@ -211,9 +211,9 @@ int ping_main(int argc, char **argv) bb_show_usage(); #if ENABLE_PING6 - lsa = host_and_af2sockaddr(hostname, 0, af); + lsa = xhost_and_af2sockaddr(hostname, 0, af); #else - lsa = host_and_af2sockaddr(hostname, 0, AF_INET); + lsa = xhost_and_af2sockaddr(hostname, 0, AF_INET); #endif /* Set timer _after_ DNS resolution */ signal(SIGALRM, noresp); @@ -743,9 +743,9 @@ int ping_main(int argc, char **argv) af = AF_INET; if (option_mask32 & OPT_IPV6) af = AF_INET6; - lsa = host_and_af2sockaddr(hostname, 0, af); + lsa = xhost_and_af2sockaddr(hostname, 0, af); #else - lsa = host_and_af2sockaddr(hostname, 0, AF_INET); + lsa = xhost_and_af2sockaddr(hostname, 0, AF_INET); #endif dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len); #if ENABLE_PING6 diff --git a/networking/tftp.c b/networking/tftp.c index a6d85a5c4..9083257ab 100644 --- a/networking/tftp.c +++ b/networking/tftp.c @@ -488,7 +488,7 @@ int tftp_main(int argc, char **argv) } port = bb_lookup_port(argv[optind + 1], "udp", 69); - peer_lsa = host2sockaddr(argv[optind], port); + peer_lsa = xhost2sockaddr(argv[optind], port); #if ENABLE_DEBUG_TFTP fprintf(stderr, "using server \"%s\", " diff --git a/networking/wget.c b/networking/wget.c index e1a4bab0d..e649ccdda 100644 --- a/networking/wget.c +++ b/networking/wget.c @@ -234,7 +234,7 @@ int wget_main(int argc, char **argv) /* We want to do exactly _one_ DNS lookup, since some * sites (i.e. ftp.us.debian.org) use round-robin DNS * and we want to connect to only one IP... */ - lsa = host2sockaddr(server.host, server.port); + lsa = xhost2sockaddr(server.host, server.port); if (!(opt & WGET_OPT_QUIET)) { fprintf(stderr, "Connecting to %s (%s)\n", server.host, xmalloc_sockaddr2dotted(&lsa->sa, lsa->len)); @@ -354,7 +354,7 @@ int wget_main(int argc, char **argv) server.port = target.port; } free(lsa); - lsa = host2sockaddr(server.host, server.port); + lsa = xhost2sockaddr(server.host, server.port); break; } } diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c index 86bfdc5df..97ddf09b5 100644 --- a/sysklogd/syslogd.c +++ b/sysklogd/syslogd.c @@ -566,7 +566,7 @@ int syslogd_main(int argc, char **argv) #endif #if ENABLE_FEATURE_REMOTE_LOG if (option_mask32 & OPT_remotelog) { // -R - remoteAddr = host2sockaddr(opt_R, 514); + remoteAddr = xhost2sockaddr(opt_R, 514); } //if (option_mask32 & OPT_locallog) // -L #endif