diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-07 15:56:47 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-10-07 15:56:47 +0200 |
commit | ec1ea16337623824e3e71bb5dc0e011259664d7e (patch) | |
tree | 61cde58288c1f247a572eac2571c7d2969bb5df4 | |
parent | 561639a68c6a5468eaa95912592f9d01ba9dcbdd (diff) | |
download | busybox-w32-ec1ea16337623824e3e71bb5dc0e011259664d7e.tar.gz busybox-w32-ec1ea16337623824e3e71bb5dc0e011259664d7e.tar.bz2 busybox-w32-ec1ea16337623824e3e71bb5dc0e011259664d7e.zip |
tcpsvd: don't keep shared fd open if fd limit is reached. closes 9331
Also, much improved help text.
function old new delta
packed_usage 30652 30851 +199
tcpudpsvd_main 1782 1784 +2
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/tcpudp.c | 69 |
1 files changed, 46 insertions, 23 deletions
diff --git a/networking/tcpudp.c b/networking/tcpudp.c index fbd1f1c45..b27cf3ea9 100644 --- a/networking/tcpudp.c +++ b/networking/tcpudp.c | |||
@@ -34,37 +34,56 @@ | |||
34 | /* with not-implemented options: */ | 34 | /* with not-implemented options: */ |
35 | /* //usage: "[-hpEvv] [-c N] [-C N[:MSG]] [-b N] [-u USER] [-l NAME] [-i DIR|-x CDB] [-t SEC] IP PORT PROG" */ | 35 | /* //usage: "[-hpEvv] [-c N] [-C N[:MSG]] [-b N] [-u USER] [-l NAME] [-i DIR|-x CDB] [-t SEC] IP PORT PROG" */ |
36 | //usage:#define tcpsvd_full_usage "\n\n" | 36 | //usage:#define tcpsvd_full_usage "\n\n" |
37 | //usage: "Create TCP socket, bind to IP:PORT and listen\n" | 37 | //usage: "Create TCP socket, bind to IP:PORT and listen for incoming connections.\n" |
38 | //usage: "for incoming connection. Run PROG for each connection.\n" | 38 | //usage: "Run PROG for each connection.\n" |
39 | //usage: "\n IP IP to listen on, 0 = all" | 39 | //usage: "\n IP PORT IP:PORT to listen on" |
40 | //usage: "\n PORT Port to listen on" | ||
41 | //usage: "\n PROG ARGS Program to run" | 40 | //usage: "\n PROG ARGS Program to run" |
42 | //usage: "\n -l NAME Local hostname (else looks up local hostname in DNS)" | ||
43 | //usage: "\n -u USER[:GRP] Change to user/group after bind" | 41 | //usage: "\n -u USER[:GRP] Change to user/group after bind" |
44 | //usage: "\n -c N Handle up to N connections simultaneously" | 42 | //usage: "\n -c N Up to N connections simultaneously (default 30)" |
45 | //usage: "\n -b N Allow a backlog of approximately N TCP SYNs" | 43 | //usage: "\n -b N Allow backlog of approximately N TCP SYNs (default 20)" |
46 | //usage: "\n -C N[:MSG] Allow only up to N connections from the same IP" | 44 | //usage: "\n -C N[:MSG] Allow only up to N connections from the same IP:" |
47 | //usage: "\n New connections from this IP address are closed" | 45 | //usage: "\n new connections from this IP address are closed" |
48 | //usage: "\n immediately. MSG is written to the peer before close" | 46 | //usage: "\n immediately, MSG is written to the peer before close" |
47 | //usage: "\n -E Don't set up environment" | ||
49 | //usage: "\n -h Look up peer's hostname" | 48 | //usage: "\n -h Look up peer's hostname" |
50 | //usage: "\n -E Don't set up environment variables" | 49 | //usage: "\n -l NAME Local hostname (else look up local hostname in DNS)" |
51 | //usage: "\n -v Verbose" | 50 | //usage: "\n -v Verbose" |
51 | //usage: "\n" | ||
52 | //usage: "\nEnvironment if no -E:" | ||
53 | //usage: "\nPROTO='TCP'" | ||
54 | //usage: "\nTCPREMOTEADDR='ip:port'" IF_FEATURE_IPV6(" ('[ip]:port' for IPv6)") | ||
55 | //usage: "\nTCPLOCALADDR='ip:port'" | ||
56 | //usage: "\nTCPORIGDSTADDR='ip:port' of destination before firewall" | ||
57 | //usage: "\n Useful for REDIRECTed-to-local connections:" | ||
58 | //usage: "\n iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080" | ||
59 | //usage: "\nTCPCONCURRENCY=num_of_connects_from_this_ip" | ||
60 | //usage: "\nIf -h:" | ||
61 | //usage: "\nTCPLOCALHOST='hostname' (-l NAME is used if specified)" | ||
62 | //usage: "\nTCPREMOTEHOST='hostname'" | ||
63 | |||
52 | //usage: | 64 | //usage: |
53 | //usage:#define udpsvd_trivial_usage | 65 | //usage:#define udpsvd_trivial_usage |
54 | //usage: "[-hEv] [-c N] [-u USER] [-l NAME] IP PORT PROG" | 66 | //usage: "[-hEv] [-c N] [-u USER] [-l NAME] IP PORT PROG" |
55 | //usage:#define udpsvd_full_usage "\n\n" | 67 | //usage:#define udpsvd_full_usage "\n\n" |
56 | //usage: "Create UDP socket, bind to IP:PORT and wait\n" | 68 | //usage: "Create UDP socket, bind to IP:PORT and wait for incoming packets.\n" |
57 | //usage: "for incoming packets. Run PROG for each packet,\n" | 69 | //usage: "Run PROG for each packet, redirecting all further packets with same\n" |
58 | //usage: "redirecting all further packets with same peer ip:port to it.\n" | 70 | //usage: "peer ip:port to it.\n" |
59 | //usage: "\n IP IP to listen on, 0 = all" | 71 | //usage: "\n IP PORT IP:PORT to listen on" |
60 | //usage: "\n PORT Port to listen on" | ||
61 | //usage: "\n PROG ARGS Program to run" | 72 | //usage: "\n PROG ARGS Program to run" |
62 | //usage: "\n -l NAME Local hostname (else looks up local hostname in DNS)" | ||
63 | //usage: "\n -u USER[:GRP] Change to user/group after bind" | 73 | //usage: "\n -u USER[:GRP] Change to user/group after bind" |
64 | //usage: "\n -c N Handle up to N connections simultaneously" | 74 | //usage: "\n -c N Up to N connections simultaneously (default 30)" |
75 | //usage: "\n -E Don't set up environment" | ||
65 | //usage: "\n -h Look up peer's hostname" | 76 | //usage: "\n -h Look up peer's hostname" |
66 | //usage: "\n -E Don't set up environment variables" | 77 | //usage: "\n -l NAME Local hostname (else look up local hostname in DNS)" |
67 | //usage: "\n -v Verbose" | 78 | //usage: "\n -v Verbose" |
79 | //usage: "\n" | ||
80 | //usage: "\nEnvironment if no -E:" | ||
81 | //usage: "\nPROTO='UDP'" | ||
82 | //usage: "\nUDPREMOTEADDR='ip:port'" IF_FEATURE_IPV6(" ('[ip]:port' for IPv6)") | ||
83 | //usage: "\nUDPLOCALADDR='ip:port'" | ||
84 | //usage: "\nIf -h:" | ||
85 | //usage: "\nUDPLOCALHOST='hostname' (-l NAME is used if specified)" | ||
86 | //usage: "\nUDPREMOTEHOST='hostname'" | ||
68 | 87 | ||
69 | #include "libbb.h" | 88 | #include "libbb.h" |
70 | #include "common_bufsiz.h" | 89 | #include "common_bufsiz.h" |
@@ -240,7 +259,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv) | |||
240 | ); | 259 | ); |
241 | #else | 260 | #else |
242 | /* "+": stop on first non-option */ | 261 | /* "+": stop on first non-option */ |
243 | opts = getopt32(argv, "+c:C:i:x:u:l:Eb:hpt:v", | 262 | opts = getopt32(argv, "+c:+C:i:x:u:l:Eb:hpt:v", |
244 | &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname, | 263 | &cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname, |
245 | &backlog, &str_t, &verbose | 264 | &backlog, &str_t, &verbose |
246 | ); | 265 | ); |
@@ -349,16 +368,20 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv) | |||
349 | again: | 368 | again: |
350 | hccp = NULL; | 369 | hccp = NULL; |
351 | 370 | ||
371 | again1: | ||
372 | close(0); | ||
373 | /* It's important to close(0) _before_ wait loop: | ||
374 | * fd#0 can be a shared connection fd. | ||
375 | * If kept open by us, peer can't detect PROG closing it. | ||
376 | */ | ||
352 | while (cnum >= cmax) | 377 | while (cnum >= cmax) |
353 | wait_for_any_sig(); /* expecting SIGCHLD */ | 378 | wait_for_any_sig(); /* expecting SIGCHLD */ |
354 | 379 | ||
355 | /* Accept a connection to fd #0 */ | ||
356 | again1: | ||
357 | close(0); | ||
358 | again2: | 380 | again2: |
359 | sig_unblock(SIGCHLD); | 381 | sig_unblock(SIGCHLD); |
360 | local.len = remote.len = sa_len; | 382 | local.len = remote.len = sa_len; |
361 | if (tcp) { | 383 | if (tcp) { |
384 | /* Accept a connection to fd #0 */ | ||
362 | conn = accept(sock, &remote.u.sa, &remote.len); | 385 | conn = accept(sock, &remote.u.sa, &remote.len); |
363 | } else { | 386 | } else { |
364 | /* In case recv_from_to won't be able to recover local addr. | 387 | /* In case recv_from_to won't be able to recover local addr. |