diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-05 20:08:11 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-05 20:08:11 +0000 |
commit | 5c51a7ca52beb6958fda45f0de480f6ac1769ec6 (patch) | |
tree | 55bc26e011712115ecdfcb01588f9f65f6397462 | |
parent | 6c501a71ae50fa8f788bbc46511e8c4071e5f897 (diff) | |
download | busybox-w32-5c51a7ca52beb6958fda45f0de480f6ac1769ec6.tar.gz busybox-w32-5c51a7ca52beb6958fda45f0de480f6ac1769ec6.tar.bz2 busybox-w32-5c51a7ca52beb6958fda45f0de480f6ac1769ec6.zip |
nc: make connecting to IPv4 from IPv6-enabled hosts easier
(was requiring -s <local addr>)
-rw-r--r-- | include/libbb.h | 9 | ||||
-rw-r--r-- | libbb/xconnect.c | 32 | ||||
-rw-r--r-- | networking/nc_bloaty.c | 21 |
3 files changed, 38 insertions, 24 deletions
diff --git a/include/libbb.h b/include/libbb.h index 013633716..dd0f5c1cc 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
@@ -304,9 +304,12 @@ enum { | |||
304 | } | 304 | } |
305 | ) | 305 | ) |
306 | }; | 306 | }; |
307 | /* Create stream socket, and allocated suitable lsa | 307 | /* Create stream socket, and allocate suitable lsa. |
308 | * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6)) */ | 308 | * (lsa of correct size and lsa->sa.sa_family (AF_INET/AF_INET6)) |
309 | int xsocket_type(len_and_sockaddr **lsap, int sock_type); | 309 | * af == AF_UNSPEC will result in trying to create IPv6, and |
310 | * if kernel doesn't support it, IPv4. | ||
311 | */ | ||
312 | int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int af,) int sock_type); | ||
310 | int xsocket_stream(len_and_sockaddr **lsap); | 313 | int xsocket_stream(len_and_sockaddr **lsap); |
311 | /* Create server socket bound to bindaddr:port. bindaddr can be NULL, | 314 | /* Create server socket bound to bindaddr:port. bindaddr can be NULL, |
312 | * numeric IP ("N.N.N.N") or numeric IPv6 address, | 315 | * numeric IP ("N.N.N.N") or numeric IPv6 address, |
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index e7d510678..b90aa9add 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -208,23 +208,31 @@ len_and_sockaddr* xdotted2sockaddr(const char *host, int port) | |||
208 | return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); | 208 | return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR); |
209 | } | 209 | } |
210 | 210 | ||
211 | int xsocket_type(len_and_sockaddr **lsap, int sock_type) | 211 | int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int family,) int sock_type) |
212 | { | 212 | { |
213 | SKIP_FEATURE_IPV6(enum { family = AF_INET };) | ||
213 | len_and_sockaddr *lsa; | 214 | len_and_sockaddr *lsa; |
214 | int fd; | 215 | int fd; |
215 | int len = sizeof(struct sockaddr_in); | 216 | int len; |
216 | int family = AF_INET; | ||
217 | 217 | ||
218 | #if ENABLE_FEATURE_IPV6 | 218 | #if ENABLE_FEATURE_IPV6 |
219 | fd = socket(AF_INET6, sock_type, 0); | 219 | if (family == AF_UNSPEC) { |
220 | if (fd >= 0) { | 220 | fd = socket(AF_INET6, sock_type, 0); |
221 | len = sizeof(struct sockaddr_in6); | 221 | if (fd >= 0) { |
222 | family = AF_INET6; | 222 | family = AF_INET6; |
223 | } else | 223 | goto done; |
224 | } | ||
225 | family = AF_INET; | ||
226 | } | ||
224 | #endif | 227 | #endif |
225 | { | 228 | fd = xsocket(family, sock_type, 0); |
226 | fd = xsocket(AF_INET, sock_type, 0); | 229 | len = sizeof(struct sockaddr_in); |
230 | #if ENABLE_FEATURE_IPV6 | ||
231 | if (family == AF_INET6) { | ||
232 | done: | ||
233 | len = sizeof(struct sockaddr_in6); | ||
227 | } | 234 | } |
235 | #endif | ||
228 | lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len); | 236 | lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len); |
229 | lsa->len = len; | 237 | lsa->len = len; |
230 | lsa->sa.sa_family = family; | 238 | lsa->sa.sa_family = family; |
@@ -234,7 +242,7 @@ int xsocket_type(len_and_sockaddr **lsap, int sock_type) | |||
234 | 242 | ||
235 | int xsocket_stream(len_and_sockaddr **lsap) | 243 | int xsocket_stream(len_and_sockaddr **lsap) |
236 | { | 244 | { |
237 | return xsocket_type(lsap, SOCK_STREAM); | 245 | return xsocket_type(lsap, USE_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM); |
238 | } | 246 | } |
239 | 247 | ||
240 | static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) | 248 | static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) |
@@ -247,7 +255,7 @@ static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) | |||
247 | /* user specified bind addr dictates family */ | 255 | /* user specified bind addr dictates family */ |
248 | fd = xsocket(lsa->sa.sa_family, sock_type, 0); | 256 | fd = xsocket(lsa->sa.sa_family, sock_type, 0); |
249 | } else { | 257 | } else { |
250 | fd = xsocket_type(&lsa, sock_type); | 258 | fd = xsocket_type(&lsa, USE_FEATURE_IPV6(AF_UNSPEC,) sock_type); |
251 | set_nport(lsa, htons(port)); | 259 | set_nport(lsa, htons(port)); |
252 | } | 260 | } |
253 | setsockopt_reuseaddr(fd); | 261 | setsockopt_reuseaddr(fd); |
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index 5096e3227..a318c8126 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -751,6 +751,13 @@ int nc_main(int argc, char **argv) | |||
751 | /* We manage our fd's so that they are never 0,1,2 */ | 751 | /* We manage our fd's so that they are never 0,1,2 */ |
752 | /*bb_sanitize_stdio(); - not needed */ | 752 | /*bb_sanitize_stdio(); - not needed */ |
753 | 753 | ||
754 | if (argv[0]) { | ||
755 | themaddr = xhost2sockaddr(argv[0], | ||
756 | argv[1] | ||
757 | ? bb_lookup_port(argv[1], o_udpmode ? "udp" : "tcp", 0) | ||
758 | : 0); | ||
759 | } | ||
760 | |||
754 | /* create & bind network socket */ | 761 | /* create & bind network socket */ |
755 | x = (o_udpmode ? SOCK_DGRAM : SOCK_STREAM); | 762 | x = (o_udpmode ? SOCK_DGRAM : SOCK_STREAM); |
756 | if (option_mask32 & OPT_s) { /* local address */ | 763 | if (option_mask32 & OPT_s) { /* local address */ |
@@ -758,7 +765,11 @@ int nc_main(int argc, char **argv) | |||
758 | ouraddr = xhost2sockaddr(str_s, o_lport); | 765 | ouraddr = xhost2sockaddr(str_s, o_lport); |
759 | x = xsocket(ouraddr->sa.sa_family, x, 0); | 766 | x = xsocket(ouraddr->sa.sa_family, x, 0); |
760 | } else { | 767 | } else { |
761 | x = xsocket_type(&ouraddr, x); | 768 | /* We try IPv6, then IPv4, unless addr family is |
769 | * implicitly set by way of remote addr/port spec */ | ||
770 | x = xsocket_type(&ouraddr, | ||
771 | USE_FEATURE_IPV6((themaddr ? themaddr->sa.sa_family : AF_UNSPEC),) | ||
772 | x); | ||
762 | if (o_lport) | 773 | if (o_lport) |
763 | set_nport(ouraddr, htons(o_lport)); | 774 | set_nport(ouraddr, htons(o_lport)); |
764 | } | 775 | } |
@@ -789,14 +800,6 @@ int nc_main(int argc, char **argv) | |||
789 | xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd); | 800 | xmove_fd(xopen(str_o, O_WRONLY|O_CREAT|O_TRUNC), ofd); |
790 | #endif | 801 | #endif |
791 | 802 | ||
792 | if (argv[0]) { | ||
793 | themaddr = xhost2sockaddr(argv[0], | ||
794 | argv[1] | ||
795 | ? bb_lookup_port(argv[1], o_udpmode ? "udp" : "tcp", 0) | ||
796 | : 0); | ||
797 | ///what if sa_family won't match?? | ||
798 | } | ||
799 | |||
800 | if (o_listen) { | 803 | if (o_listen) { |
801 | dolisten(); | 804 | dolisten(); |
802 | /* dolisten does its own connect reporting */ | 805 | /* dolisten does its own connect reporting */ |