aboutsummaryrefslogtreecommitdiff
path: root/libbb/xconnect.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-06-05 20:08:11 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-06-05 20:08:11 +0000
commit5c51a7ca52beb6958fda45f0de480f6ac1769ec6 (patch)
tree55bc26e011712115ecdfcb01588f9f65f6397462 /libbb/xconnect.c
parent6c501a71ae50fa8f788bbc46511e8c4071e5f897 (diff)
downloadbusybox-5c51a7ca52beb6958fda45f0de480f6ac1769ec6.tar.gz
nc: make connecting to IPv4 from IPv6-enabled hosts easier
(was requiring -s <local addr>)
Diffstat (limited to 'libbb/xconnect.c')
-rw-r--r--libbb/xconnect.c32
1 files changed, 20 insertions, 12 deletions
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)
return str2sockaddr(host, port, AF_UNSPEC, AI_NUMERICHOST | DIE_ON_ERROR);
}
-int xsocket_type(len_and_sockaddr **lsap, int sock_type)
+int xsocket_type(len_and_sockaddr **lsap, USE_FEATURE_IPV6(int family,) int sock_type)
{
+ SKIP_FEATURE_IPV6(enum { family = AF_INET };)
len_and_sockaddr *lsa;
int fd;
- int len = sizeof(struct sockaddr_in);
- int family = AF_INET;
+ int len;
#if ENABLE_FEATURE_IPV6
- fd = socket(AF_INET6, sock_type, 0);
- if (fd >= 0) {
- len = sizeof(struct sockaddr_in6);
- family = AF_INET6;
- } else
+ if (family == AF_UNSPEC) {
+ fd = socket(AF_INET6, sock_type, 0);
+ if (fd >= 0) {
+ family = AF_INET6;
+ goto done;
+ }
+ family = AF_INET;
+ }
#endif
- {
- fd = xsocket(AF_INET, sock_type, 0);
+ fd = xsocket(family, sock_type, 0);
+ len = sizeof(struct sockaddr_in);
+#if ENABLE_FEATURE_IPV6
+ if (family == AF_INET6) {
+ done:
+ len = sizeof(struct sockaddr_in6);
}
+#endif
lsa = xzalloc(offsetof(len_and_sockaddr, sa) + len);
lsa->len = len;
lsa->sa.sa_family = family;
@@ -234,7 +242,7 @@ int xsocket_type(len_and_sockaddr **lsap, int sock_type)
int xsocket_stream(len_and_sockaddr **lsap)
{
- return xsocket_type(lsap, SOCK_STREAM);
+ return xsocket_type(lsap, USE_FEATURE_IPV6(AF_UNSPEC,) SOCK_STREAM);
}
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)
/* user specified bind addr dictates family */
fd = xsocket(lsa->sa.sa_family, sock_type, 0);
} else {
- fd = xsocket_type(&lsa, sock_type);
+ fd = xsocket_type(&lsa, USE_FEATURE_IPV6(AF_UNSPEC,) sock_type);
set_nport(lsa, htons(port));
}
setsockopt_reuseaddr(fd);