aboutsummaryrefslogtreecommitdiff
path: root/libbb
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
parent6c501a71ae50fa8f788bbc46511e8c4071e5f897 (diff)
downloadbusybox-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>)
Diffstat (limited to 'libbb')
-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)
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
211int xsocket_type(len_and_sockaddr **lsap, int sock_type) 211int 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
235int xsocket_stream(len_and_sockaddr **lsap) 243int 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
240static int create_and_bind_or_die(const char *bindaddr, int port, int sock_type) 248static 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);