diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-25 13:16:53 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2009-04-25 13:16:53 +0000 |
commit | f6b4685691ebe00f28e4f9148a1a255e87b8d312 (patch) | |
tree | f9445de4ac97a635d2fc8a9deeb29a892a0e81ba | |
parent | 9ac3dc764a78b51fe8fdcd1b4682850de098733b (diff) | |
download | busybox-w32-f6b4685691ebe00f28e4f9148a1a255e87b8d312.tar.gz busybox-w32-f6b4685691ebe00f28e4f9148a1a255e87b8d312.tar.bz2 busybox-w32-f6b4685691ebe00f28e4f9148a1a255e87b8d312.zip |
add FEATURE_UNIX_LOCAL. By Ingo van Lil (inguin AT gmx.de)
-rw-r--r-- | libbb/xconnect.c | 24 | ||||
-rw-r--r-- | networking/Config.in | 7 | ||||
-rw-r--r-- | networking/nc.c | 38 | ||||
-rw-r--r-- | networking/nc_bloaty.c | 16 |
4 files changed, 59 insertions, 26 deletions
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index f853e9593..85f93b639 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include <netinet/in.h> | 10 | #include <netinet/in.h> |
11 | #include <net/if.h> | 11 | #include <net/if.h> |
12 | #include <sys/un.h> | ||
12 | #include "libbb.h" | 13 | #include "libbb.h" |
13 | 14 | ||
14 | void FAST_FUNC setsockopt_reuseaddr(int fd) | 15 | void FAST_FUNC setsockopt_reuseaddr(int fd) |
@@ -160,13 +161,26 @@ IF_FEATURE_IPV6(sa_family_t af,) | |||
160 | int ai_flags) | 161 | int ai_flags) |
161 | { | 162 | { |
162 | int rc; | 163 | int rc; |
163 | len_and_sockaddr *r = NULL; | 164 | len_and_sockaddr *r; |
164 | struct addrinfo *result = NULL; | 165 | struct addrinfo *result = NULL; |
165 | struct addrinfo *used_res; | 166 | struct addrinfo *used_res; |
166 | const char *org_host = host; /* only for error msg */ | 167 | const char *org_host = host; /* only for error msg */ |
167 | const char *cp; | 168 | const char *cp; |
168 | struct addrinfo hint; | 169 | struct addrinfo hint; |
169 | 170 | ||
171 | if (ENABLE_FEATURE_UNIX_LOCAL && strncmp(host, "local:", 6) == 0) { | ||
172 | struct sockaddr_un *sun; | ||
173 | |||
174 | r = xzalloc(LSA_LEN_SIZE + sizeof(struct sockaddr_un)); | ||
175 | r->len = sizeof(struct sockaddr_un); | ||
176 | r->u.sa.sa_family = AF_UNIX; | ||
177 | sun = (struct sockaddr_un *)&r->u.sa; | ||
178 | safe_strncpy(sun->sun_path, host + 6, sizeof(sun->sun_path)); | ||
179 | return r; | ||
180 | } | ||
181 | |||
182 | r = NULL; | ||
183 | |||
170 | /* Ugly parsing of host:addr */ | 184 | /* Ugly parsing of host:addr */ |
171 | if (ENABLE_FEATURE_IPV6 && host[0] == '[') { | 185 | if (ENABLE_FEATURE_IPV6 && host[0] == '[') { |
172 | /* Even uglier parsing of [xx]:nn */ | 186 | /* Even uglier parsing of [xx]:nn */ |
@@ -188,6 +202,7 @@ IF_FEATURE_IPV6(sa_family_t af,) | |||
188 | } | 202 | } |
189 | if (cp) { /* points to ":" or "]:" */ | 203 | if (cp) { /* points to ":" or "]:" */ |
190 | int sz = cp - host + 1; | 204 | int sz = cp - host + 1; |
205 | |||
191 | host = safe_strncpy(alloca(sz), host, sz); | 206 | host = safe_strncpy(alloca(sz), host, sz); |
192 | if (ENABLE_FEATURE_IPV6 && *cp != ':') { | 207 | if (ENABLE_FEATURE_IPV6 && *cp != ':') { |
193 | cp++; /* skip ']' */ | 208 | cp++; /* skip ']' */ |
@@ -371,6 +386,13 @@ static char* FAST_FUNC sockaddr2str(const struct sockaddr *sa, int flags) | |||
371 | int rc; | 386 | int rc; |
372 | socklen_t salen; | 387 | socklen_t salen; |
373 | 388 | ||
389 | if (ENABLE_FEATURE_UNIX_LOCAL && sa->sa_family == AF_UNIX) { | ||
390 | struct sockaddr_un *sun = (struct sockaddr_un *)sa; | ||
391 | return xasprintf("local:%.*s", | ||
392 | (int) sizeof(sun->sun_path), | ||
393 | sun->sun_path); | ||
394 | } | ||
395 | |||
374 | salen = LSA_SIZEOF_SA; | 396 | salen = LSA_SIZEOF_SA; |
375 | #if ENABLE_FEATURE_IPV6 | 397 | #if ENABLE_FEATURE_IPV6 |
376 | if (sa->sa_family == AF_INET) | 398 | if (sa->sa_family == AF_INET) |
diff --git a/networking/Config.in b/networking/Config.in index 392afcf89..62a21f738 100644 --- a/networking/Config.in +++ b/networking/Config.in | |||
@@ -12,6 +12,13 @@ config FEATURE_IPV6 | |||
12 | Enable IPv6 support in busybox. | 12 | Enable IPv6 support in busybox. |
13 | This adds IPv6 support in the networking applets. | 13 | This adds IPv6 support in the networking applets. |
14 | 14 | ||
15 | config FEATURE_UNIX_LOCAL | ||
16 | bool "Enable Unix domain socket support" | ||
17 | default n | ||
18 | help | ||
19 | Enable Unix domain socket support in all busybox networking | ||
20 | applets. | ||
21 | |||
15 | config FEATURE_PREFER_IPV4_ADDRESS | 22 | config FEATURE_PREFER_IPV4_ADDRESS |
16 | bool "Prefer IPv4 addresses from DNS queries" | 23 | bool "Prefer IPv4 addresses from DNS queries" |
17 | default y | 24 | default y |
diff --git a/networking/nc.c b/networking/nc.c index e64c998bc..9c3f116d2 100644 --- a/networking/nc.c +++ b/networking/nc.c | |||
@@ -34,7 +34,6 @@ int nc_main(int argc, char **argv) | |||
34 | IF_NOT_NC_EXTRA (const) unsigned delay = 0; | 34 | IF_NOT_NC_EXTRA (const) unsigned delay = 0; |
35 | IF_NOT_NC_EXTRA (const int execparam = 0;) | 35 | IF_NOT_NC_EXTRA (const int execparam = 0;) |
36 | IF_NC_EXTRA (char **execparam = NULL;) | 36 | IF_NC_EXTRA (char **execparam = NULL;) |
37 | len_and_sockaddr *lsa; | ||
38 | fd_set readfds, testfds; | 37 | fd_set readfds, testfds; |
39 | int opt; /* must be signed (getopt returns -1) */ | 38 | int opt; /* must be signed (getopt returns -1) */ |
40 | 39 | ||
@@ -44,17 +43,17 @@ int nc_main(int argc, char **argv) | |||
44 | while ((opt = getopt(argc, argv, | 43 | while ((opt = getopt(argc, argv, |
45 | "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 | 44 | "" IF_NC_SERVER("lp:") IF_NC_EXTRA("w:i:f:e:") )) > 0 |
46 | ) { | 45 | ) { |
47 | if (ENABLE_NC_SERVER && opt=='l') | 46 | if (ENABLE_NC_SERVER && opt == 'l') |
48 | IF_NC_SERVER(do_listen++); | 47 | IF_NC_SERVER(do_listen++); |
49 | else if (ENABLE_NC_SERVER && opt=='p') | 48 | else if (ENABLE_NC_SERVER && opt == 'p') |
50 | IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); | 49 | IF_NC_SERVER(lport = bb_lookup_port(optarg, "tcp", 0)); |
51 | else if (ENABLE_NC_EXTRA && opt=='w') | 50 | else if (ENABLE_NC_EXTRA && opt == 'w') |
52 | IF_NC_EXTRA( wsecs = xatou(optarg)); | 51 | IF_NC_EXTRA( wsecs = xatou(optarg)); |
53 | else if (ENABLE_NC_EXTRA && opt=='i') | 52 | else if (ENABLE_NC_EXTRA && opt == 'i') |
54 | IF_NC_EXTRA( delay = xatou(optarg)); | 53 | IF_NC_EXTRA( delay = xatou(optarg)); |
55 | else if (ENABLE_NC_EXTRA && opt=='f') | 54 | else if (ENABLE_NC_EXTRA && opt == 'f') |
56 | IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); | 55 | IF_NC_EXTRA( cfd = xopen(optarg, O_RDWR)); |
57 | else if (ENABLE_NC_EXTRA && opt=='e' && optind <= argc) { | 56 | else if (ENABLE_NC_EXTRA && opt == 'e' && optind <= argc) { |
58 | /* We cannot just 'break'. We should let getopt finish. | 57 | /* We cannot just 'break'. We should let getopt finish. |
59 | ** Or else we won't be able to find where | 58 | ** Or else we won't be able to find where |
60 | ** 'host' and 'port' params are | 59 | ** 'host' and 'port' params are |
@@ -80,9 +79,12 @@ int nc_main(int argc, char **argv) | |||
80 | argc -= optind; | 79 | argc -= optind; |
81 | // -l and -f don't mix | 80 | // -l and -f don't mix |
82 | if (do_listen && cfd) bb_show_usage(); | 81 | if (do_listen && cfd) bb_show_usage(); |
83 | // Listen or file modes need zero arguments, client mode needs 2 | 82 | // File mode needs need zero arguments, listen mode needs zero or one, |
84 | if (do_listen || cfd) { | 83 | // client mode needs one or two |
84 | if (cfd) { | ||
85 | if (argc) bb_show_usage(); | 85 | if (argc) bb_show_usage(); |
86 | } else if (do_listen) { | ||
87 | if (argc > 1) bb_show_usage(); | ||
86 | } else { | 88 | } else { |
87 | if (!argc || argc > 2) bb_show_usage(); | 89 | if (!argc || argc > 2) bb_show_usage(); |
88 | } | 90 | } |
@@ -99,24 +101,20 @@ int nc_main(int argc, char **argv) | |||
99 | 101 | ||
100 | if (!cfd) { | 102 | if (!cfd) { |
101 | if (do_listen) { | 103 | if (do_listen) { |
102 | /* create_and_bind_stream_or_die(NULL, lport) | 104 | sfd = create_and_bind_stream_or_die(argv[0], lport); |
103 | * would've work wonderfully, but we need | ||
104 | * to know lsa */ | ||
105 | sfd = xsocket_stream(&lsa); | ||
106 | if (lport) | ||
107 | set_nport(lsa, htons(lport)); | ||
108 | setsockopt_reuseaddr(sfd); | ||
109 | xbind(sfd, &lsa->u.sa, lsa->len); | ||
110 | xlisten(sfd, do_listen); /* can be > 1 */ | 105 | xlisten(sfd, do_listen); /* can be > 1 */ |
106 | #if 0 /* nc-1.10 does not do this (without -v) */ | ||
111 | /* If we didn't specify a port number, | 107 | /* If we didn't specify a port number, |
112 | * query and print it after listen() */ | 108 | * query and print it after listen() */ |
113 | if (!lport) { | 109 | if (!lport) { |
114 | getsockname(sfd, &lsa->u.sa, &lsa->len); | 110 | len_and_sockaddr lsa; |
115 | lport = get_nport(&lsa->u.sa); | 111 | lsa.len = LSA_SIZEOF_SA; |
112 | getsockname(sfd, &lsa.u.sa, &lsa.len); | ||
113 | lport = get_nport(&lsa.u.sa); | ||
116 | fdprintf(2, "%d\n", ntohs(lport)); | 114 | fdprintf(2, "%d\n", ntohs(lport)); |
117 | } | 115 | } |
116 | #endif | ||
118 | close_on_exec_on(sfd); | 117 | close_on_exec_on(sfd); |
119 | free(lsa); | ||
120 | accept_again: | 118 | accept_again: |
121 | cfd = accept(sfd, NULL, 0); | 119 | cfd = accept(sfd, NULL, 0); |
122 | if (cfd < 0) | 120 | if (cfd < 0) |
diff --git a/networking/nc_bloaty.c b/networking/nc_bloaty.c index efe831ec3..9aaeec100 100644 --- a/networking/nc_bloaty.c +++ b/networking/nc_bloaty.c | |||
@@ -377,9 +377,7 @@ create new one, and bind() it. TODO */ | |||
377 | socklen_t x = sizeof(optbuf); | 377 | socklen_t x = sizeof(optbuf); |
378 | 378 | ||
379 | rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); | 379 | rr = getsockopt(netfd, IPPROTO_IP, IP_OPTIONS, optbuf, &x); |
380 | if (rr < 0) | 380 | if (rr >= 0 && x) { /* we've got options, lessee em... */ |
381 | bb_perror_msg("getsockopt failed"); | ||
382 | else if (x) { /* we've got options, lessee em... */ | ||
383 | bin2hex(bigbuf_net, optbuf, x); | 381 | bin2hex(bigbuf_net, optbuf, x); |
384 | bigbuf_net[2*x] = '\0'; | 382 | bigbuf_net[2*x] = '\0'; |
385 | fprintf(stderr, "IP options: %s\n", bigbuf_net); | 383 | fprintf(stderr, "IP options: %s\n", bigbuf_net); |
@@ -603,7 +601,10 @@ Debug("got %d from the net, errno %d", rr, errno); | |||
603 | mobygrams are kinda fun and exercise the reassembler. */ | 601 | mobygrams are kinda fun and exercise the reassembler. */ |
604 | if (rr <= 0) { /* at end, or fukt, or ... */ | 602 | if (rr <= 0) { /* at end, or fukt, or ... */ |
605 | FD_CLR(STDIN_FILENO, &ding1); /* disable and close stdin */ | 603 | FD_CLR(STDIN_FILENO, &ding1); /* disable and close stdin */ |
606 | close(0); | 604 | close(STDIN_FILENO); |
605 | // Does it make sense to shutdown(net_fd, SHUT_WR) | ||
606 | // to let other side know that we won't write anything anymore? | ||
607 | // (and what about keeping compat if we do that?) | ||
607 | } else { | 608 | } else { |
608 | rzleft = rr; | 609 | rzleft = rr; |
609 | zp = bigbuf_in; | 610 | zp = bigbuf_in; |
@@ -768,7 +769,12 @@ int nc_main(int argc, char **argv) | |||
768 | setsockopt_reuseaddr(netfd); | 769 | setsockopt_reuseaddr(netfd); |
769 | if (o_udpmode) | 770 | if (o_udpmode) |
770 | socket_want_pktinfo(netfd); | 771 | socket_want_pktinfo(netfd); |
771 | xbind(netfd, &ouraddr->u.sa, ouraddr->len); | 772 | if (!ENABLE_FEATURE_UNIX_LOCAL |
773 | || o_listen | ||
774 | || ouraddr->u.sa.sa_family != AF_UNIX | ||
775 | ) { | ||
776 | xbind(netfd, &ouraddr->u.sa, ouraddr->len); | ||
777 | } | ||
772 | #if 0 | 778 | #if 0 |
773 | setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); | 779 | setsockopt(netfd, SOL_SOCKET, SO_RCVBUF, &o_rcvbuf, sizeof o_rcvbuf); |
774 | setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); | 780 | setsockopt(netfd, SOL_SOCKET, SO_SNDBUF, &o_sndbuf, sizeof o_sndbuf); |