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 */ |
