[git commit] tcpsvd: don't keep shared fd open if fd limit is reached. closes 9331

Denys Vlasenko vda.linux at googlemail.com
Fri Oct 7 13:56:47 UTC 2016


commit: https://git.busybox.net/busybox/commit/?id=ec1ea16337623824e3e71bb5dc0e011259664d7e
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

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 at googlemail.com>
---
 networking/tcpudp.c | 69 +++++++++++++++++++++++++++++++++++------------------
 1 file changed, 46 insertions(+), 23 deletions(-)

diff --git a/networking/tcpudp.c b/networking/tcpudp.c
index fbd1f1c..b27cf3e 100644
--- a/networking/tcpudp.c
+++ b/networking/tcpudp.c
@@ -34,37 +34,56 @@
 /* with not-implemented options: */
 /* //usage:    "[-hpEvv] [-c N] [-C N[:MSG]] [-b N] [-u USER] [-l NAME] [-i DIR|-x CDB] [-t SEC] IP PORT PROG" */
 //usage:#define tcpsvd_full_usage "\n\n"
-//usage:       "Create TCP socket, bind to IP:PORT and listen\n"
-//usage:       "for incoming connection. Run PROG for each connection.\n"
-//usage:     "\n	IP		IP to listen on, 0 = all"
-//usage:     "\n	PORT		Port to listen on"
+//usage:       "Create TCP socket, bind to IP:PORT and listen for incoming connections.\n"
+//usage:       "Run PROG for each connection.\n"
+//usage:     "\n	IP PORT		IP:PORT to listen on"
 //usage:     "\n	PROG ARGS	Program to run"
-//usage:     "\n	-l NAME		Local hostname (else looks up local hostname in DNS)"
 //usage:     "\n	-u USER[:GRP]	Change to user/group after bind"
-//usage:     "\n	-c N		Handle up to N connections simultaneously"
-//usage:     "\n	-b N		Allow a backlog of approximately N TCP SYNs"
-//usage:     "\n	-C N[:MSG]	Allow only up to N connections from the same IP"
-//usage:     "\n			New connections from this IP address are closed"
-//usage:     "\n			immediately. MSG is written to the peer before close"
+//usage:     "\n	-c N		Up to N connections simultaneously (default 30)"
+//usage:     "\n	-b N		Allow backlog of approximately N TCP SYNs (default 20)"
+//usage:     "\n	-C N[:MSG]	Allow only up to N connections from the same IP:"
+//usage:     "\n			new connections from this IP address are closed"
+//usage:     "\n			immediately, MSG is written to the peer before close"
+//usage:     "\n	-E		Don't set up environment"
 //usage:     "\n	-h		Look up peer's hostname"
-//usage:     "\n	-E		Don't set up environment variables"
+//usage:     "\n	-l NAME		Local hostname (else look up local hostname in DNS)"
 //usage:     "\n	-v		Verbose"
+//usage:     "\n"
+//usage:     "\nEnvironment if no -E:"
+//usage:     "\nPROTO='TCP'"
+//usage:     "\nTCPREMOTEADDR='ip:port'" IF_FEATURE_IPV6(" ('[ip]:port' for IPv6)")
+//usage:     "\nTCPLOCALADDR='ip:port'"
+//usage:     "\nTCPORIGDSTADDR='ip:port' of destination before firewall"
+//usage:     "\n	Useful for REDIRECTed-to-local connections:"
+//usage:     "\n	iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 8080"
+//usage:     "\nTCPCONCURRENCY=num_of_connects_from_this_ip"
+//usage:     "\nIf -h:"
+//usage:     "\nTCPLOCALHOST='hostname' (-l NAME is used if specified)"
+//usage:     "\nTCPREMOTEHOST='hostname'"
+
 //usage:
 //usage:#define udpsvd_trivial_usage
 //usage:       "[-hEv] [-c N] [-u USER] [-l NAME] IP PORT PROG"
 //usage:#define udpsvd_full_usage "\n\n"
-//usage:       "Create UDP socket, bind to IP:PORT and wait\n"
-//usage:       "for incoming packets. Run PROG for each packet,\n"
-//usage:       "redirecting all further packets with same peer ip:port to it.\n"
-//usage:     "\n	IP		IP to listen on, 0 = all"
-//usage:     "\n	PORT		Port to listen on"
+//usage:       "Create UDP socket, bind to IP:PORT and wait for incoming packets.\n"
+//usage:       "Run PROG for each packet, redirecting all further packets with same\n"
+//usage:       "peer ip:port to it.\n"
+//usage:     "\n	IP PORT		IP:PORT to listen on"
 //usage:     "\n	PROG ARGS	Program to run"
-//usage:     "\n	-l NAME		Local hostname (else looks up local hostname in DNS)"
 //usage:     "\n	-u USER[:GRP]	Change to user/group after bind"
-//usage:     "\n	-c N		Handle up to N connections simultaneously"
+//usage:     "\n	-c N		Up to N connections simultaneously (default 30)"
+//usage:     "\n	-E		Don't set up environment"
 //usage:     "\n	-h		Look up peer's hostname"
-//usage:     "\n	-E		Don't set up environment variables"
+//usage:     "\n	-l NAME		Local hostname (else look up local hostname in DNS)"
 //usage:     "\n	-v		Verbose"
+//usage:     "\n"
+//usage:     "\nEnvironment if no -E:"
+//usage:     "\nPROTO='UDP'"
+//usage:     "\nUDPREMOTEADDR='ip:port'" IF_FEATURE_IPV6(" ('[ip]:port' for IPv6)")
+//usage:     "\nUDPLOCALADDR='ip:port'"
+//usage:     "\nIf -h:"
+//usage:     "\nUDPLOCALHOST='hostname' (-l NAME is used if specified)"
+//usage:     "\nUDPREMOTEHOST='hostname'"
 
 #include "libbb.h"
 #include "common_bufsiz.h"
@@ -240,7 +259,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
 	);
 #else
 	/* "+": stop on first non-option */
-	opts = getopt32(argv, "+c:C:i:x:u:l:Eb:hpt:v",
+	opts = getopt32(argv, "+c:+C:i:x:u:l:Eb:hpt:v",
 		&cmax, &str_C, &instructs, &instructs, &user, &preset_local_hostname,
 		&backlog, &str_t, &verbose
 	);
@@ -349,16 +368,20 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
  again:
 	hccp = NULL;
 
+ again1:
+	close(0);
+	/* It's important to close(0) _before_ wait loop:
+	 * fd#0 can be a shared connection fd.
+	 * If kept open by us, peer can't detect PROG closing it.
+	 */
 	while (cnum >= cmax)
 		wait_for_any_sig(); /* expecting SIGCHLD */
 
-	/* Accept a connection to fd #0 */
- again1:
-	close(0);
  again2:
 	sig_unblock(SIGCHLD);
 	local.len = remote.len = sa_len;
 	if (tcp) {
+		/* Accept a connection to fd #0 */
 		conn = accept(sock, &remote.u.sa, &remote.len);
 	} else {
 		/* In case recv_from_to won't be able to recover local addr.


More information about the busybox-cvs mailing list