Bump to version 1.22.1
[platform/upstream/busybox.git] / networking / tcpudp.c
index 98a2aa8..3df6a98 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (C) 2007 Denys Vlasenko.
  *
- * Licensed under GPLv2, see file LICENSE in this tarball for details.
+ * Licensed under GPLv2, see file LICENSE in this source tree.
  */
 
 /* Based on ipsvd-0.12.1. This tcpsvd accepts all options
  * - don't know how to retrieve ORIGDST for udp.
  */
 
+//usage:#define tcpsvd_trivial_usage
+//usage:       "[-hEv] [-c N] [-C N[:MSG]] [-b N] [-u USER] [-l NAME] IP PORT PROG"
+/* 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:     "\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       -h              Look up peer's hostname"
+//usage:     "\n       -E              Don't set up environment variables"
+//usage:     "\n       -v              Verbose"
+//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:     "\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       -h              Look up peer's hostname"
+//usage:     "\n       -E              Don't set up environment variables"
+//usage:     "\n       -v              Verbose"
+
 #include "libbb.h"
+
 /* Wants <limits.h> etc, thus included after libbb.h: */
+#ifdef __linux__
 #include <linux/types.h> /* for __be32 etc */
 #include <linux/netfilter_ipv4.h>
+#endif
 
 // TODO: move into this file:
 #include "tcpudp_perhost.h"
@@ -50,7 +90,7 @@ struct globals {
        unsigned cmax;
        char **env_cur;
        char *env_var[1]; /* actually bigger */
-};
+} FIX_ALIASING;
 #define G (*(struct globals*)&bb_common_bufsiz1)
 #define verbose      (G.verbose     )
 #define max_per_host (G.max_per_host)
@@ -85,8 +125,7 @@ static void undo_xsetenv(void)
        char **pp = env_cur = &env_var[0];
        while (*pp) {
                char *var = *pp;
-               bb_unsetenv(var);
-               free(var);
+               bb_unsetenv_and_free(var);
                *pp++ = NULL;
        }
 }
@@ -239,7 +278,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
        client = 0;
        if ((getuid() == 0) && !(opts & OPT_u)) {
                xfunc_exitcode = 100;
-               bb_error_msg_and_die("-U ssluser must be set when running as root");
+               bb_error_msg_and_die(bb_msg_you_must_be_root);
        }
        if (opts & OPT_u)
                if (!uidgid_get(&sslugid, ssluser, 1)) {
@@ -251,14 +290,14 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
        if (!cert) cert = "./cert.pem";
        if (!key) key = cert;
        if (matrixSslOpen() < 0)
-               fatal("cannot initialize ssl");
+               fatal("can't initialize ssl");
        if (matrixSslReadKeys(&keys, cert, key, 0, ca) < 0) {
                if (client)
-                       fatal("cannot read cert, key, or ca file");
-               fatal("cannot read cert or key file");
+                       fatal("can't read cert, key, or ca file");
+               fatal("can't read cert or key file");
        }
        if (matrixSslNewSession(&ssl, keys, 0, SSL_FLAGS_SERVER) < 0)
-               fatal("cannot create ssl session");
+               fatal("can't create ssl session");
 #endif
 
        sig_block(SIGCHLD);
@@ -385,7 +424,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
                 * already bound in parent! This seems to work in Linux.
                 * (otherwise we can move socket to fd #0 only if bind succeeds) */
                close(0);
-               set_nport(localp, htons(local_port));
+               set_nport(&localp->u.sa, htons(local_port));
                xmove_fd(xsocket(localp->u.sa.sa_family, SOCK_DGRAM, 0), 0);
                setsockopt_reuseaddr(0); /* crucial */
                xbind(0, &localp->u.sa, localp->len);
@@ -425,7 +464,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
                        if (opts & OPT_h) {
                                free_me1 = remote_hostname = xmalloc_sockaddr2host_noport(&remote.u.sa);
                                if (!remote_hostname) {
-                                       bb_error_msg("cannot look up hostname for %s", remote_addr);
+                                       bb_error_msg("can't look up hostname for %s", remote_addr);
                                        remote_hostname = remote_addr;
                                }
                        }
@@ -441,7 +480,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
                                if (!local_hostname) {
                                        free_me2 = local_hostname = xmalloc_sockaddr2host_noport(&local.u.sa);
                                        if (!local_hostname)
-                                               bb_error_msg_and_die("cannot look up hostname for %s", local_addr);
+                                               bb_error_msg_and_die("can't look up hostname for %s", local_addr);
                                }
                                /* else: local_hostname is not NULL, but is NOT malloced! */
                        }
@@ -465,6 +504,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
                        /* setup ucspi env */
                        const char *proto = tcp ? "TCP" : "UDP";
 
+#ifdef SO_ORIGINAL_DST
                        /* Extract "original" destination addr:port
                         * from Linux firewall. Useful when you redirect
                         * an outbond connection to local handler, and it needs
@@ -474,6 +514,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
                                xsetenv_plain("TCPORIGDSTADDR", addr);
                                free(addr);
                        }
+#endif
                        xsetenv_plain("PROTO", proto);
                        xsetenv_proto(proto, "LOCALADDR", local_addr);
                        xsetenv_proto(proto, "REMOTEADDR", remote_addr);
@@ -502,10 +543,10 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
 #ifdef SSLSVD
        strcpy(id, utoa(pid));
        ssl_io(0, argv);
+       bb_perror_msg_and_die("can't execute '%s'", argv[0]);
 #else
-       BB_EXECVP(argv[0], argv);
+       BB_EXECVP_or_die(argv);
 #endif
-       bb_perror_msg_and_die("exec '%s'", argv[0]);
 }
 
 /*