summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-09-30 05:40:04 +0000
committerLaurent Bercot <ska@appnovation.com>2023-09-30 05:40:04 +0000
commitbef76b45f480aa41209efdec09fc6bb0bfde7cbe (patch)
treebb3945da0504c569ff325829bf5f895f8e355039
parenta068a3256fab3b77b7d1bc9ce201c954a9b00c94 (diff)
downloads6-networking-bef76b45f480aa41209efdec09fc6bb0bfde7cbe.tar.xz
Great Tcpserver Unification. Prepare for 2.6.0.0.
Signed-off-by: Laurent Bercot <ska@appnovation.com>
-rw-r--r--NEWS2
-rw-r--r--doc/index.html10
-rw-r--r--doc/s6-tcpserver-access.html28
-rw-r--r--doc/s6-tcpserver-socketbinder.html (renamed from doc/s6-tcpserver4-socketbinder.html)40
-rw-r--r--doc/s6-tcpserver.html124
-rw-r--r--doc/s6-tcpserver4.html137
-rw-r--r--doc/s6-tcpserver6-socketbinder.html82
-rw-r--r--doc/s6-tcpserver6.html136
-rw-r--r--doc/s6-tcpserver6d.html112
-rw-r--r--doc/s6-tcpserverd.html (renamed from doc/s6-tcpserver4d.html)48
-rw-r--r--doc/upgrade.html21
-rw-r--r--package/deps.mak24
-rw-r--r--package/info2
-rw-r--r--package/modes12
-rw-r--r--package/targets.mak8
-rw-r--r--src/conn-tools/deps-exe/s6-tcpserver-socketbinder (renamed from src/conn-tools/deps-exe/s6-tcpserver4)0
-rw-r--r--src/conn-tools/deps-exe/s6-tcpserver4d2
-rw-r--r--src/conn-tools/deps-exe/s6-tcpserver62
-rw-r--r--src/conn-tools/deps-exe/s6-tcpserver6-socketbinder2
-rw-r--r--src/conn-tools/deps-exe/s6-tcpserver6d2
-rw-r--r--src/conn-tools/deps-exe/s6-tcpserverd (renamed from src/conn-tools/deps-exe/s6-tcpserver4-socketbinder)0
-rw-r--r--src/conn-tools/s6-tcpserver-access.c18
-rw-r--r--src/conn-tools/s6-tcpserver-socketbinder.c (renamed from src/conn-tools/s6-tcpserver4-socketbinder.c)15
-rw-r--r--src/conn-tools/s6-tcpserver.c18
-rw-r--r--src/conn-tools/s6-tcpserver4.c131
-rw-r--r--src/conn-tools/s6-tcpserver6-socketbinder.c58
-rw-r--r--src/conn-tools/s6-tcpserver6.c131
-rw-r--r--src/conn-tools/s6-tcpserver6d.c374
-rw-r--r--src/conn-tools/s6-tcpserverd.c (renamed from src/conn-tools/s6-tcpserver4d.c)194
29 files changed, 308 insertions, 1425 deletions
diff --git a/NEWS b/NEWS
index f69b6fb..3ce5292 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
Changelog for s6-networking.
-In 2.5.1.4
+In 2.6.0.0
----------
- Bugfixes.
diff --git a/doc/index.html b/doc/index.html
index 37da351..8cd5f2e 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -91,7 +91,7 @@ run-time requirement if you link against its shared version. </li>
<ul>
<li> The current released version of s6-networking is
-<a href="s6-networking-2.5.1.4.tar.gz">2.5.1.4</a>. </li>
+<a href="s6-networking-2.6.0.0.tar.gz">2.6.0.0</a>. </li>
<li> Alternatively, you can checkout a copy of the
<a href="//git.skarnet.org/cgi-bin/cgit.cgi/s6-networking/">s6-networking
git repository</a>:
@@ -143,12 +143,8 @@ relevant page.
<ul>
<li><a href="s6-tcpclient.html">The <tt>s6-tcpclient</tt> program</a></li>
<li><a href="s6-tcpserver.html">The <tt>s6-tcpserver</tt> program</a></li>
-<li><a href="s6-tcpserver4.html">The <tt>s6-tcpserver4</tt> program</a></li>
-<li><a href="s6-tcpserver4-socketbinder.html">The <tt>s6-tcpserver4-socketbinder</tt> program</a></li>
-<li><a href="s6-tcpserver4d.html">The <tt>s6-tcpserver4d</tt> program</a></li>
-<li><a href="s6-tcpserver6.html">The <tt>s6-tcpserver6</tt> program</a></li>
-<li><a href="s6-tcpserver6-socketbinder.html">The <tt>s6-tcpserver6-socketbinder</tt> program</a></li>
-<li><a href="s6-tcpserver6d.html">The <tt>s6-tcpserver6d</tt> program</a></li>
+<li><a href="s6-tcpserver-socketbinder.html">The <tt>s6-tcpserver-socketbinder</tt> program</a></li>
+<li><a href="s6-tcpserverd.html">The <tt>s6-tcpserverd</tt> program</a></li>
</ul>
<h4> UCSPI tools for secure communication (TLS protocol) over TCP </h4>
diff --git a/doc/s6-tcpserver-access.html b/doc/s6-tcpserver-access.html
index 15f4246..4ef3302 100644
--- a/doc/s6-tcpserver-access.html
+++ b/doc/s6-tcpserver-access.html
@@ -35,12 +35,8 @@ just like tcpwrappers' <tt>tcpd</tt> program.
<ul>
<li> s6-tcpserver-access checks it is run under a UCSPI server tool
-such as <a href="s6-tcpserver.html">s6-tcpserver</a>,
- <a href="s6-tcpserver4.html">s6-tcpserver4</a> or
- <a href="s6-tcpserver6.html">s6-tcpserver6</a>, or their
- stripped-down versions
- <a href="s6-tcpserver4d.html">s6-tcpserver4d</a> or
- <a href="s6-tcpserver6d.html">s6-tcpserver6d</a>. </li>
+such as <a href="s6-tcpserver.html">s6-tcpserver</a> or its stripped-down version
+ <a href="s6-tcpserverd.html">s6-tcpserverd</a>. </li>
<li> It checks that the remote end of the connection fits the
accepted criteria defined by the database contained in <em>rulesdir</em>
or <em>rulesfile</em>. If the database tells it to reject the connection,
@@ -59,9 +55,11 @@ its parent:
</p>
<ul>
- <li> PROTO: normally TCP, but could be anything else, like SSL. </li>
+ <li> PROTO: normally TCP, but could be anything else. </li>
+ <li> ${PROTO}LOCALIP: the local address of the socket. </li>
+ <li> ${PROTO}LOCALPORT: the local port of the socket. </li>
<li> ${PROTO}REMOTEIP: the remote address of the socket, i.e. the client's
-IP address. This can be IPv4 or (if the underlying skalibs supports it) IPv6. </li>
+IP address. </li>
<li> ${PROTO}REMOTEPORT: the remote port of the socket. </li>
</ul>
@@ -71,16 +69,14 @@ IP address. This can be IPv4 or (if the underlying skalibs supports it) IPv6. </
</p>
<ul>
- <li> ${PROTO}LOCALIP: set to the local address of the socket. </li>
- <li> ${PROTO}LOCALPORT: set to the local port of the socket. </li>
- <li> ${PROTO}REMOTEINFO: normally unset, but set to the information
-retrieved from ${PROTO}REMOTEIP via the IDENT protocol if the <tt>-r</tt>
-option has been given. </li>
<li> ${PROTO}REMOTEHOST: set to the remote host name obtained from
a DNS lookup. Unset if the <tt>-H</tt> option has been given. </li>
<li> ${PROTO}LOCALHOST: set to the local host name obtained from a
DNS lookup. If the <tt>-l</tt> option has been given, set to
<em>localname</em> instead. </li>
+ <li> ${PROTO}REMOTEINFO: normally unset, but set to the information
+retrieved from ${PROTO}REMOTEIP via the IDENT protocol if the <tt>-r</tt>
+option has been given. </li>
</ul>
<p>
@@ -227,12 +223,6 @@ environment modifications, if any, s6-tcpserver-access execs into
<h2> Notes </h2>
<ul>
- <li> s6-tcpserver-access works with
-<a href="s6-tcpserver4d.html">s6-tcpserver4d</a>, handling IPv4 addresses,
-as well as
-<a href="s6-tcpserver6d.html">s6-tcpserver6d</a>, handling IPv6 addresses.
-It will automatically detect the remote address type and match it against the
-correct subdatabase. </li>
<li> s6-tcpserver-access may perform several DNS queries. For efficiency
purposes, it does as many of them as possible in parallel. However, if asked
to do an IDENT query, it does not parallelize it with DNS queries. Take
diff --git a/doc/s6-tcpserver4-socketbinder.html b/doc/s6-tcpserver-socketbinder.html
index 6bf1c58..8e7135d 100644
--- a/doc/s6-tcpserver4-socketbinder.html
+++ b/doc/s6-tcpserver-socketbinder.html
@@ -3,9 +3,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Language" content="en" />
- <title>s6-networking: the s6-tcpserver4-socketbinder program</title>
- <meta name="Description" content="s6-networking: the s6-tcpserver4-socketbinder program" />
- <meta name="Keywords" content="s6-networking s6-tcpserver4-socketbinder tcpserver ucspi inet ipv4 socket bind listen" />
+ <title>s6-networking: the s6-tcpserver-socketbinder program</title>
+ <meta name="Description" content="s6-networking: the s6-tcpserver-socketbinder program" />
+ <meta name="Keywords" content="s6-networking s6-tcpserver-socketbinder tcpserver ucspi inet ipv4 ipv6 socket bind listen TCP/IP" />
<!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
</head>
<body>
@@ -16,22 +16,22 @@
<a href="//skarnet.org/">skarnet.org</a>
</p>
-<h1> The <tt>s6-tcpserver4-socketbinder</tt> program </h1>
+<h1> The <tt>s6-tcpserver-socketbinder</tt> program </h1>
<p>
-<tt>s6-tcpserver4-socketbinder</tt> binds an INET domain
-socket to an IPv4 address and port, then executes a program.
+<tt>s6-tcpserver-socketbinder</tt> binds an INET domain
+socket to an IPv4 or IPv6 address and port, then executes a program.
</p>
<h2> Interface </h2>
<pre>
- s6-tcpserver4-socketbinder [ -d | -D ] [ -b <em>backlog</em> ] [ -M | -m ] [ -B ] <em>ip</em> <em>port</em> <em>prog...</em>
+ s6-tcpserver-socketbinder [ -d | -D ] [ -b <em>backlog</em> ] [ -M | -m ] [ -B ] <em>ip</em> <em>port</em> <em>prog...</em>
</pre>
<ul>
- <li> s6-tcpserver4-socketbinder creates a TCP socket
-and binds it to IPv4 address <em>ip</em>, port <em>port</em>.
+ <li> s6-tcpserver-socketbinder creates a TCP socket
+and binds it to IP address <em>ip</em>, port <em>port</em>.
It prepares the socket to accept connections by calling
<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">listen()</a>. </li>
<li> It then execs into <em>prog...</em> with the open socket
@@ -48,15 +48,15 @@ and is generally used with server programs. This is the default. </li>
<li> <tt>-D</tt>&nbsp;: disallow instant rebinding to the same path. </li>
<li> <tt>-b&nbsp;<em>backlog</em></tt>&nbsp;: set a maximum of
<em>backlog</em> backlog connections on the socket - extra
-connection attempts will rejected by the kernel. The default is SOMAXCONN,
-i.e. the maximum number allowed by the system. If <em>backlog</em>
+connection attempts will rejected by the kernel. The default is the maximum
+number allowed by the system. If <em>backlog</em>
is 0, then the socket will be created, but it <strong>will not be
listening</strong>. </li>
<li> <tt>-M</tt>&nbsp;: create a TCP socket. This is the default. </li>
<li> <tt>-m</tt>&nbsp;: create a UDP socket. Note
that by default UDP sockets are not connection-mode, and <tt>listen()</tt>
will fail - so you should always give the <tt>-b0</tt> option to
-s6-tcpserver4-socketbinder along with <tt>-m</tt>. </li>
+s6-tcpserver-socketbinder along with <tt>-m</tt>. </li>
<li> <tt>-B</tt>&nbsp;: create a blocking socket. Default is non-blocking. </li>
</ul>
@@ -64,18 +64,22 @@ s6-tcpserver4-socketbinder along with <tt>-m</tt>. </li>
<ul>
<li> The socket is provided <strong>non-blocking by default</strong>. </li>
- <li> s6-tcpserver4-socketbinder is part of a set of basic blocks used to
-build a flexible TCP/IPv4 super-server. It normally should be given a
+ <li> s6-tcpserver-socketbinder is part of a set of basic blocks used to
+build a flexible TCP/IP super-server. It normally should be given a
command line crafted to make it execute into
-<a href="s6-tcpserver4d.html">s6-tcpserver4d</a> to accept connections
+<a href="s6-tcpserverd.html">s6-tcpserverd</a> to accept connections
from clients, or into a program such as
<a href="//skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>
to drop privileges before doing so. </li>
- <li> The <a href="s6-tcpserver4.html">s6-tcpserver4</a> program does
+ <li> The <a href="s6-tcpserver.html">s6-tcpserver</a> program does
exactly this. It implements
-a full TCP/IPv4 super-server by building a command line starting with
-s6-tcpserver4-socketbinder and ending with s6-tcpserver4d followed by the
+a full TCP/IP super-server by building a command line starting with
+s6-tcpserver-socketbinder and ending with s6-tcpserverd followed by the
application program, and executing into it. </li>
+ <li> For s6-tcpserver-socketbinder, <tt>::</tt> means "all IPv6 addresses",
+and <tt>0.0.0.0</tt> means "all IPv4 addresses". It does not provide a way
+to bind a socket to all addresses regardless of protocol; instead, you
+should use two sockets, one for IPv4 and one for IPv6. </li>
</ul>
</body>
diff --git a/doc/s6-tcpserver.html b/doc/s6-tcpserver.html
index 362dbf5..561c00f 100644
--- a/doc/s6-tcpserver.html
+++ b/doc/s6-tcpserver.html
@@ -5,7 +5,7 @@
<meta http-equiv="Content-Language" content="en" />
<title>s6-networking: the s6-tcpserver program</title>
<meta name="Description" content="s6-networking: the s6-tcpserver program" />
- <meta name="Keywords" content="s6-networking s6-tcpserver tcpserver ucspi tcp server super-server" />
+ <meta name="Keywords" content="s6-networking s6-tcpserver tcpserver ucspi tcp server super-server ip ipv4 ipv6 TCP/IP" />
<!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
</head>
<body>
@@ -22,51 +22,119 @@
<tt>s6-tcpserver</tt> is an
<a href="https://cr.yp.to/proto/ucspi.txt">UCSPI tool</a> for
TCP connections, i.e. a super-server. It accepts connections from
-clients, and forks a program to handle each connection.
+clients, and spawns a program to handle each connection.
</p>
<h2> Interface </h2>
<pre>
- s6-tcpserver [ -q | -Q | -v ] [ -4 | -6 ] [ -1 ] [ -c <em>maxconn</em> ] [ -C <em>localmaxconn</em> ] [ -b <em>backlog</em> ] [ -G <em>gidlist</em> ] [ -g <em>gid</em> ] [ -u <em>uid</em> ] [ -U ] <em>ip</em> <em>port</em> <em>prog...</em>
+ s6-tcpserver [ -q | -Q | -v ] [ -1 ] [ -c <em>maxconn</em> ] [ -C <em>localmaxconn</em> ] [ -b <em>backlog</em> ] [ -G <em>gidlist</em> ] [ -g <em>gid</em> ] [ -u <em>uid</em> ] [ -U ] <em>ip</em> <em>port</em> <em>prog...</em>
</pre>
<ul>
- <li> s6-tcpserver executes into
-<a href="s6-tcpserver4.html">s6-tcpserver4</a> or
-<a href="s6-tcpserver6.html">s6-tcpserver6</a> depending on whether
-<em>ip</em> is an IPv4 or IPv6 address. It modifies some of its
-option syntax to match s6-tcpserver4 and s6-tcpserver6's.</li>
- <li> s6-tcpserver4 or s6-tcpserver6 handles the connection itself. </li>
+ <li> s6-tcpserver binds to local IP address <em>ip</em> (which can be
+IPv4 or IPv6), port <em>port</em>. </li>
+ <li> It closes its stdin and stdout. </li>
+ <li> For every TCP connection to this address and port, it spawns a
+<em>prog...</em> child with stdin reading from the network socket and
+stdout writing to it. </li>
+ <li> Depending on the verbosity level, it logs what it does to stderr. </li>
+ <li> It runs until killed by a signal. Depending on the received
+signal, it may kill its children before exiting. </li>
+</ul>
+
+<h2> Environment variables </h2>
+
+<p>
+ For each connection, an instance of <em>prog...</em> is spawned with
+the following variables set:
+</p>
+
+<ul>
+ <li> PROTO: always set to TCP </li>
+ <li> TCPLOCALIP: set to the server's address </li>
+ <li> TCPLOCALPORT: set to the server's port </li>
+ <li> TCPREMOTEIP: set to the client's address </li>
+ <li> TCPREMOTEPORT: set to the client's port </li>
+ <li> TCPCONNNUM: set to the number of connections originating from
+the same IP address </li>
</ul>
<h2> Options </h2>
<ul>
- <li> <tt>-q</tt>&nbsp;: be quiet. This is converted into <tt>-v&nbsp;0</tt>
-for s6-tcpserver4 or s6-tcpserver6. </li>
- <li> <tt>-Q</tt>&nbsp;: be normally quiet. This is converted into <tt>-v&nbsp;1</tt>
-for s6-tcpserver4 or s6-tcpserver6. This is the default. </li>
- <li> <tt>-v</tt>&nbsp;: be verbose. This is converted into <tt>-v&nbsp;2</tt>
-for s6-tcpserver4 or s6-tcpserver6. </li>
- <li> <tt>-4</tt>&nbsp;: IPv4 only. Interpret <em>ip</em> as IPv4; if it is
-invalid, exit 100. </li>
- <li> <tt>-6</tt>&nbsp;: IPv6 only. Interpret <em>ip</em> as IPv6; if it is
-invalid, exit 100. If neither the <tt>-4</tt> nor the <tt>-6</tt> option is
-given, s6-tcpserver will parse <em>ip</em> to determine its family. </li>
- <li> Every other option is passed verbatim to s6-tcpserver4 or s6-tcpserver6. </li>
+ <li> <tt>-q</tt>&nbsp;: be quiet. Only print fatal error messages to stderr. </li>
+ <li> <tt>-Q</tt>&nbsp;: be normally quiet. Print warnings and fatal
+error messages to stderr. This is the default. </li>
+ <li> <tt>-v</tt>&nbsp;: be verbose. Additionally to fatal errors and
+warnings, also print status and connection information for every client. </li>
+ <li> <tt>-1</tt>&nbsp;: write <em>port</em> to stdout, before
+closing it, right after binding and listening to the network socket.
+If stdout is suitably redirected, this can be used by monitoring
+programs to check when the server is ready to accept connections. </li>
+ <li> <tt>-c&nbsp;<em>maxconn</em></tt>&nbsp;: accept at most
+<em>maxconn</em> concurrent connections. Default is 40. It is
+impossible to set it higher than 1000. </li>
+ <li> <tt>-C&nbsp;<em>localmaxconn</em></tt>&nbsp;: accept at most
+<em>localmaxconn</em> connections from the same IP address.
+Default is 40. It is impossible to set it higher than <em>maxconn</em>. </li>
+ <li> <tt>-b&nbsp;<em>backlog</em></tt>&nbsp;: set a maximum of
+<em>backlog</em> backlog connections on the socket. Extra
+connection attempts will rejected by the kernel. </li>
+ <li> <tt>-G&nbsp;<em>gidlist</em></tt>&nbsp;: change s6-tcpserver's
+supplementary group list to <em>gidlist</em> after binding the socket.
+This is only valid when run as root. <em>gidlist</em> must be a
+comma-separated list of numerical group IDs. </li>
+ <li> <tt>-g&nbsp;<em>gid</em></tt>&nbsp;: change s6-tcpserver's group id
+to <em>gid</em> after binding the socket. This is only valid when run
+as root. </li>
+ <li> <tt>-u&nbsp;<em>uid</em></tt>&nbsp;: change s6-tcpserver's user id
+to <em>uid</em> after binding the socket. This is only valid when run
+as root. </li>
+ <li> <tt>-U</tt>&nbsp;: change s6-tcpserver's user id, group id and
+supplementary group list
+according to the values of the UID, GID and GIDLIST environment variables
+after binding the socket. This is only valid when run as root.
+This can be used with the
+<a href="//skarnet.org/software/s6/s6-envuidgid.html">s6-envuidgid</a>
+program to easily script a service that binds to a privileged socket
+then drops its privileges to those of a named non-root account. </li>
+</ul>
+
+<h2> Signals </h2>
+
+<ul>
+ <li> SIGTERM: exit. </li>
+ <li> SIGHUP: send a SIGTERM and a SIGCONT to all children. </li>
+ <li> SIGQUIT: send a SIGTERM and a SIGCONT to all children, then exit. </li>
+ <li> SIGABRT: send a SIGKILL to all children, then exit. </li>
</ul>
<h2> Notes </h2>
<ul>
- <li> s6-tcpserver executes either into s6-tcpserver4, which only serves
-IPv4, or into s6-tcpserver6, which only serves IPv6. It will not bind to every
-available IP address of the machine whether they are v4 or v6; on the
-other hand, it can bind to every available IPv4 address (if <em>ip</em>
-is <tt>0.0.0.0</tt>) or to every available IPv6 address (if <em>ip</em>
-is <tt>::</tt>). Two instances of s6-tcpserver can cover every
-available address. </li>
+ <li> Unlike its ancestor
+<a href="https://cr.yp.to/ucspi-tcp/tcpserver.html">tcpserver</a>,
+s6-tcpserver performs just the bare minimum: the point is to have a
+very small and very fast process to serve connections with the least
+possible overhead. Features such as access control and DNS resolution are
+provided via the <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>
+program. </li>
+ <li> s6-tcpserver is actually a wrapper that rewrites itself into a
+command line running
+ <ul>
+ <li> <a href="s6-tcpserver-socketbinder.html">s6-tcpserver-socketbinder</a>,
+that binds the socket and listens to it </li>
+ <li> <a href="//skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>,
+that drops privileges </li>
+ <li> <a href="s6-tcpserverd.html">s6-tcpserverd</a>, the long-lived process
+that actually accepts the connections. So if you see in your <tt>ps</tt> output
+that the name of the process is <tt>s6-tcpserverd</tt>, that's why. </li>
+ </ul>
+ <li> s6-tcpserver treats IPv4 and IPv6 separately. If you want to listen on
+<em>all</em> the addresses of a machine no matter whether v4 or v6, then you
+need to run <em>two</em> s6-tcpserver processes: one on <tt>0.0.0.0</tt> and
+and one on <tt>::</tt>. </li>
</ul>
</body>
diff --git a/doc/s6-tcpserver4.html b/doc/s6-tcpserver4.html
deleted file mode 100644
index bc1bd5e..0000000
--- a/doc/s6-tcpserver4.html
+++ /dev/null
@@ -1,137 +0,0 @@
-<html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Language" content="en" />
- <title>s6-networking: the s6-tcpserver4 program</title>
- <meta name="Description" content="s6-networking: the s6-tcpserver4 program" />
- <meta name="Keywords" content="s6-networking s6-tcpserver4 tcpserver ucspi tcp server super-server ipv4" />
- <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
- </head>
-<body>
-
-<p>
-<a href="index.html">s6-networking</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>s6-tcpserver4</tt> program </h1>
-
-<p>
-<tt>s6-tcpserver4</tt> is a super-server for IPv4 TCP
-connections. It accepts connections from clients, and forks a
-program to handle each connection.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
- s6-tcpserver4 [ -1 ] [ -v <em>verbosity</em> ] [ -c <em>maxconn</em> ] [ -C <em>localmaxconn</em> ] [ -b <em>backlog</em> ] [ -G <em>gidlist</em> ] [ -g <em>gid</em> ] [ -u <em>uid</em> ] [ -U ] <em>ip</em> <em>port</em> <em>prog...</em>
-</pre>
-
-<ul>
- <li> s6-tcpserver4 binds to local IPv4 address <em>ip</em>,
-port <em>port</em>. </li>
- <li> It closes its stdin and stdout. </li>
- <li> For every TCP connection to this address and port, it
-forks. The child sets some environment variables, then
-executes <em>prog...</em> with stdin reading from the network
-socket and stdout writing to it. </li>
- <li> Depending on the verbosity level, it logs what it does to stderr. </li>
- <li> It runs until killed by a signal. Depending on the received
-signal, it may kill its children before exiting. </li>
- <li> s6-tcpserver4 actually doesn't do any of this itself. It is
-a wrapper, rewriting the command line and executing into a chain
-of programs that perform those duties. </li>
-</ul>
-
-<h2> Environment variables </h2>
-
-<p>
- For each connection, an instance of <em>prog...</em> is spawned with
-the following variables set:
-</p>
-
-<ul>
- <li> PROTO: always set to TCP </li>
- <li> TCPREMOTEIP: set to the originating address </li>
- <li> TCPREMOTEPORT: set to the originating port </li>
- <li> TCPCONNNUM: set to the number of connections originating from
-the same IP address </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-1</tt>&nbsp;: write <em>port</em> to stdout, before
-closing it, right after binding and listening to the network socket.
-If stdout is suitably redirected, this can be used by monitoring
-programs to check when the server is ready to accept connections. </li>
- <li> <tt>-v&nbsp;<em>verbosity</em></tt>&nbsp;: be more or less verbose.
-By default, <em>verbosity</em> is 1: print warning messages to stderr.
-0 means only print fatal error messages ; 2 means print status and
-connection information for every client. </li>
- <li> <tt>-c&nbsp;<em>maxconn</em></tt>&nbsp;: accept at most
-<em>maxconn</em> concurrent connections. Default is 40. It is
-impossible to set it higher than 1000. </li>
- <li> <tt>-C&nbsp;<em>localmaxconn</em></tt>&nbsp;: accept at most
-<em>localmaxconn</em> connections from the same IP address.
-Default is 40. It is impossible to set it higher than <em>maxconn</em>. </li>
- <li> <tt>-b&nbsp;<em>backlog</em></tt>&nbsp;: set a maximum of
-<em>backlog</em> backlog connections on the socket. Extra
-connection attempts will rejected by the kernel. </li>
- <li> <tt>-G&nbsp;<em>gidlist</em></tt>&nbsp;: change s6-tcpserver4's
-supplementary group list to <em>gidlist</em> after binding the socket.
-This is only valid when run as root. <em>gidlist</em> must be a
-comma-separated list of numerical group IDs. </li>
- <li> <tt>-g&nbsp;<em>gid</em></tt>&nbsp;: change s6-tcpserver4's group id
-to <em>gid</em> after binding the socket. This is only valid when run
-as root. </li>
- <li> <tt>-u&nbsp;<em>uid</em></tt>&nbsp;: change s6-tcpserver4's user id
-to <em>uid</em> after binding the socket. This is only valid when run
-as root. </li>
- <li> <tt>-U</tt>&nbsp;: change s6-tcpserver4's user id, group id and
-supplementary group list
-according to the values of the UID, GID and GIDLIST environment variables
-after binding the socket. This is only valid when run as root.
-This can be used with the
-<a href="//skarnet.org/software/s6/s6-envuidgid.html">s6-envuidgid</a>
-program to easily script a service that binds to a privileged socket
-then drops its privileges to those of a named non-root account. </li>
-</ul>
-
-<h2> Signals </h2>
-
-<ul>
- <li> SIGTERM: exit. </li>
- <li> SIGHUP: send a SIGTERM and a SIGCONT to all children. </li>
- <li> SIGQUIT: send a SIGTERM and a SIGCONT to all children, then exit. </li>
- <li> SIGABRT: send a SIGKILL to all children, then exit. </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> Unlike its ancestor
-<a href="https://cr.yp.to/ucspi-tcp/tcpserver.html">tcpserver</a>,
-s6-tcpserver4 performs just the bare minimum: the point is to have a
-very small and very fast process to serve connections with the least
-possible overhead. Features such as additional environment variables,
-access control and DNS resolution are provided
-via the <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>
-program. </li>
- <li> In previous releases of s6-networking, s6-tcpserver4 was
-monolithic: it did the work of
-<a href="s6-tcpserver4-socketbinder.html">s6-tcpserver4-socketbinder</a>,
-<a href="//skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a> and
-<a href="s6-tcpserver4d.html">s6-tcpserver4d</a> itself. The functionality has now
-been split into several different programs because some service startup
-schemes require the daemon to get its socket from an external
-program instead of creating and binding it itself. The most obvious
-application of this is upgrading a long-lived process without
-losing existing connections. </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/s6-tcpserver6-socketbinder.html b/doc/s6-tcpserver6-socketbinder.html
deleted file mode 100644
index 5bb2ae5..0000000
--- a/doc/s6-tcpserver6-socketbinder.html
+++ /dev/null
@@ -1,82 +0,0 @@
-<html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Language" content="en" />
- <title>s6-networking: the s6-tcpserver6-socketbinder program</title>
- <meta name="Description" content="s6-networking: the s6-tcpserver6-socketbinder program" />
- <meta name="Keywords" content="s6-networking s6-tcpserver6-socketbinder tcpserver ucspi inet ipv6 socket bind listen" />
- <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
- </head>
-<body>
-
-<p>
-<a href="index.html">s6-networking</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>s6-tcpserver6-socketbinder</tt> program </h1>
-
-<p>
-<tt>s6-tcpserver6-socketbinder</tt> binds an INET domain
-socket to an IPv6 address and port, then executes a program.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
- s6-tcpserver6-socketbinder [ -d | -D ] [ -b <em>backlog</em> ] [ -M | -m ] [ -B ] <em>ip</em> <em>port</em> <em>prog...</em>
-</pre>
-
-<ul>
- <li> s6-tcpserver6-socketbinder creates an TCP socket
-and binds it to IPv6 address <em>ip</em>, port <em>port</em>.
-It prepares the socket to accept connections by calling
-<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/listen.html">listen()</a>. </li>
- <li> It then execs into <em>prog...</em> with the open socket
-as its standard input. </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-d</tt>&nbsp;: allow instant rebinding to the same IP and port
-even if it has been used not long ago - this is the SO_REUSEADDR flag to
-<a href="https://pubs.opengroup.org/onlinepubs/9699919799/functions/setsockopt.html">setsockopt()</a>
-and is generally used with server programs. This is the default. </li>
- <li> <tt>-D</tt>&nbsp;: disallow instant rebinding to the same path. </li>
- <li> <tt>-b&nbsp;<em>backlog</em></tt>&nbsp;: set a maximum of
-<em>backlog</em> backlog connections on the socket - extra
-connection attempts will rejected by the kernel. The default is SOMAXCONN,
-i.e. the maximum number allowed by the system. If <em>backlog</em>
-is 0, then the socket will be created, but it <strong>will not be
-listening</strong>. </li>
- <li> <tt>-M</tt>&nbsp;: create a TCP socket. This is the default. </li>
- <li> <tt>-m</tt>&nbsp;: create a UDP socket. Note
-that by default UDP sockets are not connection-mode, and <tt>listen()</tt>
-will fail - so you should always give the <tt>-b0</tt> option to
-s6-tcpserver6-socketbinder along with <tt>-m</tt>. </li>
- <li> <tt>-B</tt>&nbsp;: create a blocking socket. Default is non-blocking. </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> The socket is provided <strong>non-blocking by default</strong>. </li>
- <li> s6-tcpserver6-socketbinder is part of a set of basic blocks used to
-build a flexible TCP/IPv6 super-server. It normally should be given a
-command line crafted to make it execute into
-<a href="s6-tcpserver6d.html">s6-tcpserver6d</a> to accept connections
-from clients, or into a program such as
-<a href="//skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a>
-to drop privileges before doing so. </li>
- <li> The <a href="s6-tcpserver6.html">s6-tcpserver6</a> program does
-exactly this. It implements
-a full TCP/IPv6 super-server by building a command line starting with
-s6-tcpserver6-socketbinder and ending with s6-tcpserver6d followed by the
-application program, and executing into it. </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/s6-tcpserver6.html b/doc/s6-tcpserver6.html
deleted file mode 100644
index 01be274..0000000
--- a/doc/s6-tcpserver6.html
+++ /dev/null
@@ -1,136 +0,0 @@
-<html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Language" content="en" />
- <title>s6-networking: the s6-tcpserver6 program</title>
- <meta name="Description" content="s6-networking: the s6-tcpserver6 program" />
- <meta name="Keywords" content="s6-networking s6-tcpserver6 tcpserver ucspi tcp server super-server ipv6" />
- <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
- </head>
-<body>
-
-<p>
-<a href="index.html">s6-networking</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>s6-tcpserver6</tt> program </h1>
-
-<p>
-<tt>s6-tcpserver6</tt> is a super-server for IPv6 TCP
-connections. It accepts connections from clients, and forks a
-program to handle each connection.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
- s6-tcpserver6 [ -1 ] [ -v <em>verbosity</em> ] [ -c <em>maxconn</em> ] [ -C <em>localmaxconn</em> ] [ -b <em>backlog</em> ] [ -G <em>gidlist</em> ] [ -g <em>gid</em> ] [ -u <em>uid</em> ] [ -U ] <em>ip</em> <em>port</em> <em>prog...</em>
-</pre>
-
-<ul>
- <li> s6-tcpserver6 binds to local IPv6 address <em>ip</em>,
-port <em>port</em>. </li>
- <li> It closes its stdin and stdout. </li>
- <li> For every TCP connection to this address and port, it
-forks. The child sets some environment variables, then
-executes <em>prog...</em> with stdin reading from the network socket
-and stdout writing to it. </li>
- <li> Depending on the verbosity level, it logs what it does to stderr. </li>
- <li> It runs until killed by a signal. Depending on the received
-signal, it may kill its children before exiting. </li>
- <li> s6-tcpserver6 actually doesn't do any of this itself. It is
-a wrapper, rewriting the command line and executing into a chain
-of programs that perform those duties. </li>
-</ul>
-
-<h2> Environment variables </h2>
-
-<p>
- For each connection, an instance of <em>prog...</em> is spawned with
-the following variables set:
-</p>
-
-<ul>
- <li> PROTO: always set to TCP </li>
- <li> TCPREMOTEIP: set to the originating address, in canonical IPv6 form </li>
- <li> TCPREMOTEPORT: set to the originating port </li>
- <li> TCPCONNNUM: set to the number of connections originating from
-the same IPv6 address </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-1</tt>&nbsp;: write <em>port</em> to stdout, before
-closing it, right after binding and listening to the network socket.
-If stdout is suitably redirected, this can be used by monitoring
-programs to check when the server is ready to accept connections. </li>
- <li> <tt>-v&nbsp;<em>verbosity</em></tt>&nbsp;: be more or less verbose.
-By default, <em>verbosity</em> is 1: print warning messages to stderr.
-0 means only print fatal error messages ; 2 means print status and
-connection information for every client. </li>
- <li> <tt>-c&nbsp;<em>maxconn</em></tt>&nbsp;: accept at most
-<em>maxconn</em> concurrent connections. Default is 40. It is
-impossible to set it higher than 1000. </li>
- <li> <tt>-C&nbsp;<em>localmaxconn</em></tt>&nbsp;: accept at most
-<em>localmaxconn</em> connections from the same IP address.
-Default is 40. It is impossible to set it higher than <em>maxconn</em>. </li>
- <li> <tt>-b&nbsp;<em>backlog</em></tt>&nbsp;: set a maximum of
-<em>backlog</em> backlog connections on the socket. Extra
-connection attempts will rejected by the kernel. </li>
- <li> <tt>-G&nbsp;<em>gidlist</em></tt>&nbsp;: change s6-tcpserver6's
-supplementary group list to <em>gidlist</em> after binding the socket.
-This is only valid when run as root. <em>gidlist</em> must be a
-comma-separated list of numerical group IDs. </li>
- <li> <tt>-g&nbsp;<em>gid</em></tt>&nbsp;: change s6-tcpserver6's group id
-to <em>gid</em> after binding the socket. This is only valid when run
-as root. </li>
- <li> <tt>-u&nbsp;<em>uid</em></tt>&nbsp;: change s6-tcpserver6's user id
-to <em>uid</em> after binding the socket. This is only valid when run
-as root. </li>
- <li> <tt>-U</tt>&nbsp;: change s6-tcpserver6's user id, group id and
-supplementary group list
-according to the values of the UID, GID and GIDLIST environment variables
-after binding the socket. This is only valid when run as root.
-This can be used with the
-<a href="//skarnet.org/software/s6/s6-envuidgid.html">s6-envuidgid</a>
-program to easily script a service that binds to a privileged socket
-then drops its privileges to those of a named non-root account. </li>
-</ul>
-
-<h2> Signals </h2>
-
-<ul>
- <li> SIGTERM: exit. </li>
- <li> SIGHUP: send a SIGTERM and a SIGCONT to all children. </li>
- <li> SIGQUIT: send a SIGTERM and a SIGCONT to all children, then exit. </li>
- <li> SIGABRT: send a SIGKILL to all children, then exit. </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> s6-tcpserver6 will only serve real IPv6 addresses; it does not
-default to an IPv4 address. The
-<a href="s6-tcpserver4.html">s6-tcpserver4</a> program should be
-used to serve IPv4 addresses. </li>
- <li> s6-tcpserver6 will only work if the underlying
-<a href="//skarnet.org/software/skalibs/">skalibs</a> has
-been compiled with IPv6 support. </li>
- <li> In previous releases of s6-networking, s6-tcpserver6 was
-monolithic: it did the work of
-<a href="s6-tcpserver6-socketbinder.html">s6-tcpserver6-socketbinder</a>,
-<a href="//skarnet.org/software/s6/s6-applyuidgid.html">s6-applyuidgid</a> and
-<a href="s6-tcpserver6d.html">s6-tcpserver6d</a> itself. The functionality has now
-been split into several different programs because some service startup
-schemes require the daemon to get its socket from an external
-program instead of creating and binding it itself. The most obvious
-application of this is upgrading a long-lived process without
-losing existing connections. </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/s6-tcpserver6d.html b/doc/s6-tcpserver6d.html
deleted file mode 100644
index 585fa41..0000000
--- a/doc/s6-tcpserver6d.html
+++ /dev/null
@@ -1,112 +0,0 @@
-<html>
- <head>
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <meta http-equiv="Content-Language" content="en" />
- <title>s6-networking: the s6-tcpserver6d program</title>
- <meta name="Description" content="s6-networking: the s6-tcpserver6d program" />
- <meta name="Keywords" content="s6-networking s6-tcpserver6d tcpserver ucspi tcp server super-server ipv6" />
- <!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
- </head>
-<body>
-
-<p>
-<a href="index.html">s6-networking</a><br />
-<a href="//skarnet.org/software/">Software</a><br />
-<a href="//skarnet.org/">skarnet.org</a>
-</p>
-
-<h1> The <tt>s6-tcpserver6d</tt> program </h1>
-
-<p>
-<tt>s6-tcpserver6d</tt> is the serving part of the
-<a href="s6-tcpserver6.html">s6-tcpserver6</a> super-server.
-It assumes that its stdin is a bound and listening TCP/IPv6 socket,
-and it accepts connections from clients connecting to it,
-forking a program to handle each connection.
-</p>
-
-<h2> Interface </h2>
-
-<pre>
- s6-tcpserver6d [ -1 ] [ -v <em>verbosity</em> ] [ -c <em>maxconn</em> ] [ -C <em>localmaxconn</em> ] <em>prog...</em>
-</pre>
-
-<ul>
- <li> s6-tcpserver6d accepts connections from clients to an already
-bound and listening TCP socket which is its standard input. </li>
- <li> For every TCP connection to this socket, it
-forks. The child sets some environment variables, then
-executes <em>prog...</em> with stdin reading from the network
-socket and stdout writing to it. </li>
- <li> Depending on the verbosity level, it logs what it does to stderr. </li>
- <li> It runs until killed by a signal. Depending on the received
-signal, it may kill its children before exiting. </li>
-</ul>
-
-<h2> Environment variables </h2>
-
-<p>
- For each connection, an instance of <em>prog...</em> is spawned with
-the following variables set:
-</p>
-
-<ul>
- <li> PROTO: always set to TCP </li>
- <li> TCPREMOTEIP: set to the originating address </li>
- <li> TCPREMOTEPORT: set to the originating port </li>
- <li> TCPCONNNUM: set to the number of connections originating from
-the same IP address </li>
-</ul>
-
-<h2> Options </h2>
-
-<ul>
- <li> <tt>-1</tt>&nbsp;: write a newline to stdout, and close stdout,
-right before entering the client-accepting loop.
-If stdout is suitably redirected, this can be used by monitoring
-programs to check when the server is accepting connections, for instance
-s6's <a href="//skarnet.org/software/s6/notifywhenup.html">readiness
-notification mechanism</a>. </li>
- <li> <tt>-v&nbsp;<em>verbosity</em></tt>&nbsp;: be more or less verbose.
-By default, <em>verbosity</em> is 1: print warning messages to stderr.
-0 means only print fatal error messages ; 2 means print status and
-connection information for every client. </li>
- <li> <tt>-c&nbsp;<em>maxconn</em></tt>&nbsp;: accept at most
-<em>maxconn</em> concurrent connections. Default is 40. It is
-impossible to set it higher than 1000. </li>
- <li> <tt>-C&nbsp;<em>localmaxconn</em></tt>&nbsp;: accept at most
-<em>localmaxconn</em> connections from the same IP address.
-Default is 40. It is impossible to set it higher than <em>maxconn</em>. </li>
-</ul>
-
-<h2> Signals </h2>
-
-<ul>
- <li> SIGTERM: exit. </li>
- <li> SIGHUP: send a SIGTERM and a SIGCONT to all children. </li>
- <li> SIGQUIT: send a SIGTERM and a SIGCONT to all children, then exit. </li>
- <li> SIGABRT: send a SIGKILL to all children, then exit. </li>
-</ul>
-
-<h2> Notes </h2>
-
-<ul>
- <li> Unlike its ancestor
-<a href="https://cr.yp.to/ucspi-tcp/tcpserver.html">tcpserver</a>,
-s6-tcpserver6d performs just the bare minimum: the point is to have a
-very small and very fast process to serve connections with the least
-possible overhead. Features such as additional environment variables,
-access control and DNS resolution are provided
-via the <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>
-program. </li>
- <li> s6-tcpserver6d is meant to be execve'd into by a program that gets
-the listening socket. That program is normally
-<a href="s6-tcpserver6-socketbinder.html">s6-tcpserver6-socketbinder</a>,
-which creates the socket itself; but it can be a different one if the
-socket is to be retrieved by another means, for instance by fd-passing
-from a fd-holding daemon (some people call this "socket activation"). </li>
-</ul>
-
-</body>
-</html>
diff --git a/doc/s6-tcpserver4d.html b/doc/s6-tcpserverd.html
index a11bae1..6600a7b 100644
--- a/doc/s6-tcpserver4d.html
+++ b/doc/s6-tcpserverd.html
@@ -3,9 +3,9 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Language" content="en" />
- <title>s6-networking: the s6-tcpserver4d program</title>
- <meta name="Description" content="s6-networking: the s6-tcpserver4d program" />
- <meta name="Keywords" content="s6-networking s6-tcpserver4d tcpserver ucspi tcp server super-server ipv4" />
+ <title>s6-networking: the s6-tcpserverd program</title>
+ <meta name="Description" content="s6-networking: the s6-tcpserverd program" />
+ <meta name="Keywords" content="s6-networking s6-tcpserverd tcpserver ucspi tcp server super-server ipv4 ipv6 TCP/IP" />
<!-- <link rel="stylesheet" type="text/css" href="//skarnet.org/default.css" /> -->
</head>
<body>
@@ -16,28 +16,27 @@
<a href="//skarnet.org/">skarnet.org</a>
</p>
-<h1> The <tt>s6-tcpserver4d</tt> program </h1>
+<h1> The <tt>s6-tcpserverd</tt> program </h1>
<p>
-<tt>s6-tcpserver4d</tt> is the serving part of the
-<a href="s6-tcpserver4.html">s6-tcpserver4</a> super-server.
-It assumes that its stdin is a bound and listening TCP/IPv4 socket,
+<tt>s6-tcpserverd</tt> is the serving part of the
+<a href="s6-tcpserver.html">s6-tcpserver</a> super-server.
+It assumes that its stdin is a bound and listening TCP/IP socket,
and it accepts connections from clients connecting to it,
-forking a program to handle each connection.
+spawning a program to handle each connection.
</p>
<h2> Interface </h2>
<pre>
- s6-tcpserver4d [ -1 ] [ -v <em>verbosity</em> ] [ -c <em>maxconn</em> ] [ -C <em>localmaxconn</em> ] <em>prog...</em>
+ s6-tcpserverd [ -1 ] [ -v <em>verbosity</em> ] [ -c <em>maxconn</em> ] [ -C <em>localmaxconn</em> ] <em>prog...</em>
</pre>
<ul>
- <li> s6-tcpserver4d accepts connections from clients to an already
+ <li> s6-tcpserverd accepts connections from clients to an already
bound and listening TCP socket which is its standard input. </li>
<li> For every TCP connection to this socket, it
-forks. The child sets some environment variables, then
-executes <em>prog...</em> with stdin reading from the network
+spawns a <em>prog...</em> child with stdin reading from the network
socket and stdout writing to it. </li>
<li> Depending on the verbosity level, it logs what it does to stderr. </li>
<li> It runs until killed by a signal. Depending on the received
@@ -53,8 +52,10 @@ the following variables set:
<ul>
<li> PROTO: always set to TCP </li>
- <li> TCPREMOTEIP: set to the originating address </li>
- <li> TCPREMOTEPORT: set to the originating port </li>
+ <li> TCPLOCALIP: set to the server socket's address </li>
+ <li> TCPLOCALPORT: set to the server socket's port </li>
+ <li> TCPREMOTEIP: set to the client socket's address </li>
+ <li> TCPREMOTEPORT: set to the client socket's port </li>
<li> TCPCONNNUM: set to the number of connections originating from
the same IP address </li>
</ul>
@@ -62,8 +63,8 @@ the same IP address </li>
<h2> Options </h2>
<ul>
- <li> <tt>-1</tt>&nbsp;: write a newline to stdout, and close stdout,
-right before entering the client-accepting loop.
+ <li> <tt>-1</tt>&nbsp;: write the local port, followed by newline,
+to stdout, and close stdout, right before entering the client-accepting loop.
If stdout is suitably redirected, this can be used by monitoring
programs to check when the server is accepting connections. This can be
used with s6's <a href="//skarnet.org/software/s6/notifywhenup.html">readiness
@@ -75,7 +76,7 @@ By default, <em>verbosity</em> is 1: print warning messages to stderr.
connection information for every client. </li>
<li> <tt>-c&nbsp;<em>maxconn</em></tt>&nbsp;: accept at most
<em>maxconn</em> concurrent connections. Default is 40. It is
-impossible to set it higher than 1000. </li>
+impossible to set it higher than 16384. </li>
<li> <tt>-C&nbsp;<em>localmaxconn</em></tt>&nbsp;: accept at most
<em>localmaxconn</em> connections from the same IP address.
Default is 40. It is impossible to set it higher than <em>maxconn</em>. </li>
@@ -95,15 +96,14 @@ Default is 40. It is impossible to set it higher than <em>maxconn</em>. </li>
<ul>
<li> Unlike its ancestor
<a href="https://cr.yp.to/ucspi-tcp/tcpserver.html">tcpserver</a>,
-s6-tcpserver4d performs just the bare minimum: the point is to have a
-very small and very fast process to serve connections with the least
-possible overhead. Features such as additional environment variables,
-access control and DNS resolution are provided
-via the <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>
+s6-tcpserverd performs just the bare minimum: the point is to have a
+small and very fast process to serve connections with the least
+possible overhead. Features such as access control and DNS resolution
+are provided via the <a href="s6-tcpserver-access.html">s6-tcpserver-access</a>
program. </li>
- <li> s6-tcpserver4d is meant to be execve'd into by a program that gets
+ <li> s6-tcpserverd is meant to be execve'd into by a program that gets
the listening socket. That program is normally
-<a href="s6-tcpserver4-socketbinder.html">s6-tcpserver4-socketbinder</a>,
+<a href="s6-tcpserver-socketbinder.html">s6-tcpserver-socketbinder</a>,
which creates the socket itself; but it can be a different one if the
socket is to be retrieved by another means, for instance by fd-passing
from a fd-holding daemon (some people call this "socket activation"). </li>
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 7b2c27b..0f20319 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -18,7 +18,7 @@
<h1> What has changed in s6-networking </h1>
-<h2> in 2.5.1.4 </h2>
+<h2> in 2.6.0.0 </h2>
<ul>
<li> <a href="//skarnet.org/software/skalibs/">skalibs</a>
@@ -35,7 +35,24 @@ optional dependency bumped to 1.1.1w </li>
optional dependency bumped to 3.7.0 </li>
<li> <a href="s6-tcpserver-access.html">s6-tcpserver-access</a> does
not print a warning on <tt>-v 2</tt> or more when it is run without
-the <tt>-i</tt> or </tt>-x</tt> option. </li>
+the <tt>-i</tt> or </tt>-x</tt> option. It is not needed anymore in
+order to export TCPLOCALIP and TCPLOCALPORT to the applications. </li>
+ <li> The tcpserver chain has been unified!
+<tt>s6-tcpserver4</tt>, <tt>s6-tcpserver6</tt>,
+<tt>s6-tcpserver4-socketbinder</tt>, <tt>s6-tcpserver6-socketbinder</tt>,
+<tt>s6-tcpserver4d</tt> and <tt>s6-tcpserver6d</tt> have all
+disappeared. Instead, there are just 3 programs:
+ <ul>
+ <li> <a href="s6-tcpserver-socketbinder.html">s6-tcpserver-socketbinder</a>,
+for socket binding </li>
+ <li> <a href="s6-tcpserverd.html">s6-tcpserverd</a>, the long-lived
+process. It now exports TCPLOCALIP and TCPLOCALPORT in addition to PROTO,
+TCPREMOTEIP, TCPREMOTEPORT and TCPCONNNUM. </li>
+ <li> <a href="s6-tcpserver.html">s6-tcpserver</a>, which still has
+the same interface except that the <tt>-4</tt> and <tt>-6</tt> options
+have been removed, and that is still a wrapper around the others. </li>
+ </ul>
+ </li>
</ul>
<h2> in 2.5.1.3 </h2>
diff --git a/package/deps.mak b/package/deps.mak
index 7c919da..6144259 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -13,13 +13,9 @@ src/conn-tools/s6-getservbyname.o src/conn-tools/s6-getservbyname.lo: src/conn-t
src/conn-tools/s6-ident-client.o src/conn-tools/s6-ident-client.lo: src/conn-tools/s6-ident-client.c src/include/s6-networking/ident.h
src/conn-tools/s6-tcpclient.o src/conn-tools/s6-tcpclient.lo: src/conn-tools/s6-tcpclient.c src/include/s6-networking/ident.h
src/conn-tools/s6-tcpserver-access.o src/conn-tools/s6-tcpserver-access.lo: src/conn-tools/s6-tcpserver-access.c src/include/s6-networking/config.h src/include/s6-networking/ident.h
+src/conn-tools/s6-tcpserver-socketbinder.o src/conn-tools/s6-tcpserver-socketbinder.lo: src/conn-tools/s6-tcpserver-socketbinder.c
src/conn-tools/s6-tcpserver.o src/conn-tools/s6-tcpserver.lo: src/conn-tools/s6-tcpserver.c src/include/s6-networking/config.h
-src/conn-tools/s6-tcpserver4-socketbinder.o src/conn-tools/s6-tcpserver4-socketbinder.lo: src/conn-tools/s6-tcpserver4-socketbinder.c
-src/conn-tools/s6-tcpserver4.o src/conn-tools/s6-tcpserver4.lo: src/conn-tools/s6-tcpserver4.c src/include/s6-networking/config.h
-src/conn-tools/s6-tcpserver4d.o src/conn-tools/s6-tcpserver4d.lo: src/conn-tools/s6-tcpserver4d.c
-src/conn-tools/s6-tcpserver6-socketbinder.o src/conn-tools/s6-tcpserver6-socketbinder.lo: src/conn-tools/s6-tcpserver6-socketbinder.c
-src/conn-tools/s6-tcpserver6.o src/conn-tools/s6-tcpserver6.lo: src/conn-tools/s6-tcpserver6.c src/include/s6-networking/config.h
-src/conn-tools/s6-tcpserver6d.o src/conn-tools/s6-tcpserver6d.lo: src/conn-tools/s6-tcpserver6d.c
+src/conn-tools/s6-tcpserverd.o src/conn-tools/s6-tcpserverd.lo: src/conn-tools/s6-tcpserverd.c
src/libs6net/s6net_ident_client.o src/libs6net/s6net_ident_client.lo: src/libs6net/s6net_ident_client.c src/include/s6-networking/ident.h
src/libs6net/s6net_ident_error.o src/libs6net/s6net_ident_error.lo: src/libs6net/s6net_ident_error.c src/include/s6-networking/ident.h
src/libs6net/s6net_ident_reply_get.o src/libs6net/s6net_ident_reply_get.lo: src/libs6net/s6net_ident_reply_get.c src/include/s6-networking/ident.h
@@ -124,18 +120,10 @@ s6-tcpserver: EXTRA_LIBS := -lskarnet
s6-tcpserver: src/conn-tools/s6-tcpserver.o
s6-tcpserver-access: EXTRA_LIBS := -ls6dns -ls6 -lskarnet ${SOCKET_LIB} ${SYSCLOCK_LIB}
s6-tcpserver-access: src/conn-tools/s6-tcpserver-access.o ${LIBS6NET}
-s6-tcpserver4: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
-s6-tcpserver4: src/conn-tools/s6-tcpserver4.o
-s6-tcpserver4-socketbinder: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
-s6-tcpserver4-socketbinder: src/conn-tools/s6-tcpserver4-socketbinder.o
-s6-tcpserver4d: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
-s6-tcpserver4d: src/conn-tools/s6-tcpserver4d.o
-s6-tcpserver6: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
-s6-tcpserver6: src/conn-tools/s6-tcpserver6.o
-s6-tcpserver6-socketbinder: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
-s6-tcpserver6-socketbinder: src/conn-tools/s6-tcpserver6-socketbinder.o
-s6-tcpserver6d: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
-s6-tcpserver6d: src/conn-tools/s6-tcpserver6d.o
+s6-tcpserver-socketbinder: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
+s6-tcpserver-socketbinder: src/conn-tools/s6-tcpserver-socketbinder.o
+s6-tcpserverd: EXTRA_LIBS := -lskarnet ${SOCKET_LIB}
+s6-tcpserverd: src/conn-tools/s6-tcpserverd.o
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
libs6net.a.xyzzy: src/libs6net/s6net_ident_client.o src/libs6net/s6net_ident_reply_get.o src/libs6net/s6net_ident_reply_parse.o src/libs6net/s6net_ident_error.o
else
diff --git a/package/info b/package/info
index e693bf6..8a7dd83 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=s6-networking
-version=2.5.1.4
+version=2.6.0.0
category=net
package_macro_name=S6_NETWORKING
diff --git a/package/modes b/package/modes
index 2327ea2..f403d4a 100644
--- a/package/modes
+++ b/package/modes
@@ -1,13 +1,9 @@
s6-getservbyname 0755
s6-ident-client 0755
s6-tcpclient 0755
-s6-tcpserver4 0755
-s6-tcpserver4d 0755
-s6-tcpserver4-socketbinder 0755
-s6-tcpserver6 0755
-s6-tcpserver6d 0755
-s6-tcpserver6-socketbinder 0755
s6-tcpserver 0755
+s6-tcpserver-socketbinder 0755
+s6-tcpserverd 0755
s6-tcpserver-access 0755
s6-clockadd 0700
s6-clockview 0755
@@ -16,9 +12,9 @@ s6-taiclock 0755
s6-taiclockd 0755
s6-tlsclient 0755
s6-tlsc 0755
+s6-ucspitlsc 0755
s6-tlsc-io 0755
s6-tlsserver 0755
s6-tlsd 0755
-s6-tlsd-io 0755
-s6-ucspitlsc 0755
s6-ucspitlsd 0755
+s6-tlsd-io 0755
diff --git a/package/targets.mak b/package/targets.mak
index ca34bdb..120f861 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -3,12 +3,8 @@ s6-getservbyname \
s6-ident-client \
s6-tcpclient \
s6-tcpserver \
-s6-tcpserver4 \
-s6-tcpserver4d \
-s6-tcpserver4-socketbinder \
-s6-tcpserver6 \
-s6-tcpserver6d \
-s6-tcpserver6-socketbinder \
+s6-tcpserver-socketbinder \
+s6-tcpserverd \
s6-tcpserver-access \
s6-clockadd \
s6-clockview \
diff --git a/src/conn-tools/deps-exe/s6-tcpserver4 b/src/conn-tools/deps-exe/s6-tcpserver-socketbinder
index 19869b2..19869b2 100644
--- a/src/conn-tools/deps-exe/s6-tcpserver4
+++ b/src/conn-tools/deps-exe/s6-tcpserver-socketbinder
diff --git a/src/conn-tools/deps-exe/s6-tcpserver4d b/src/conn-tools/deps-exe/s6-tcpserver4d
deleted file mode 100644
index 19869b2..0000000
--- a/src/conn-tools/deps-exe/s6-tcpserver4d
+++ /dev/null
@@ -1,2 +0,0 @@
--lskarnet
-${SOCKET_LIB}
diff --git a/src/conn-tools/deps-exe/s6-tcpserver6 b/src/conn-tools/deps-exe/s6-tcpserver6
deleted file mode 100644
index 19869b2..0000000
--- a/src/conn-tools/deps-exe/s6-tcpserver6
+++ /dev/null
@@ -1,2 +0,0 @@
--lskarnet
-${SOCKET_LIB}
diff --git a/src/conn-tools/deps-exe/s6-tcpserver6-socketbinder b/src/conn-tools/deps-exe/s6-tcpserver6-socketbinder
deleted file mode 100644
index 19869b2..0000000
--- a/src/conn-tools/deps-exe/s6-tcpserver6-socketbinder
+++ /dev/null
@@ -1,2 +0,0 @@
--lskarnet
-${SOCKET_LIB}
diff --git a/src/conn-tools/deps-exe/s6-tcpserver6d b/src/conn-tools/deps-exe/s6-tcpserver6d
deleted file mode 100644
index 19869b2..0000000
--- a/src/conn-tools/deps-exe/s6-tcpserver6d
+++ /dev/null
@@ -1,2 +0,0 @@
--lskarnet
-${SOCKET_LIB}
diff --git a/src/conn-tools/deps-exe/s6-tcpserver4-socketbinder b/src/conn-tools/deps-exe/s6-tcpserverd
index 19869b2..19869b2 100644
--- a/src/conn-tools/deps-exe/s6-tcpserver4-socketbinder
+++ b/src/conn-tools/deps-exe/s6-tcpserverd
diff --git a/src/conn-tools/s6-tcpserver-access.c b/src/conn-tools/s6-tcpserver-access.c
index addf66b..ddd6072 100644
--- a/src/conn-tools/s6-tcpserver-access.c
+++ b/src/conn-tools/s6-tcpserver-access.c
@@ -127,6 +127,14 @@ int main (int argc, char const *const *argv)
char const *x ;
char tmp[protolen + 11] ;
memcpy(tmp, proto, protolen) ;
+ memcpy(tmp + protolen, "LOCALIP", 8) ;
+ x = getenv(tmp) ;
+ if (!x) strerr_dienotset(100, tmp) ;
+ if (!ip46_scan(x, &localip)) strerr_dieinvalid(100, tmp) ;
+ memcpy(tmp + protolen + 5, "PORT", 5) ;
+ x = getenv(tmp) ;
+ if (!x) strerr_dienotset(100, tmp) ;
+ if (!uint160_scan(x, &localport)) strerr_dieinvalid(100, tmp) ;
memcpy(tmp + protolen, "REMOTEIP", 9) ;
x = getenv(tmp) ;
if (!x) strerr_dienotset(100, tmp) ;
@@ -180,17 +188,8 @@ int main (int argc, char const *const *argv)
{
char const *x = 0 ;
char idbuf[S6NET_IDENT_ID_SIZE] ;
- char fmt[IP46_FMT] ;
char tmp[protolen + 11] ;
- if (socket_local46(0, &localip, &localport) < 0)
- strerr_diefu1sys(111, "socket_local") ;
- fmt[ip46_fmt(fmt, &localip)] = 0 ;
memcpy(tmp, proto, protolen) ;
- memcpy(tmp + protolen, "LOCALIP", 8) ;
- if (!env_addmodif(&modifs, tmp, fmt)) dienomem() ;
- fmt[uint16_fmt(fmt, localport)] = 0 ;
- memcpy(tmp + protolen + 5, "PORT", 5) ;
- if (!env_addmodif(&modifs, tmp, fmt)) dienomem() ;
memcpy(tmp + protolen, "REMOTEINFO", 11) ;
if (flagident)
{
@@ -215,7 +214,6 @@ int main (int argc, char const *const *argv)
}
else x = idbuf ;
}
-
if (!env_addmodif(&modifs, tmp, x)) dienomem() ;
}
diff --git a/src/conn-tools/s6-tcpserver4-socketbinder.c b/src/conn-tools/s6-tcpserver-socketbinder.c
index aadb3d9..bc40ef4 100644
--- a/src/conn-tools/s6-tcpserver4-socketbinder.c
+++ b/src/conn-tools/s6-tcpserver-socketbinder.c
@@ -11,9 +11,10 @@
#include <skalibs/fmtscan.h>
#include <skalibs/strerr.h>
#include <skalibs/socket.h>
+#include <skalibs/ip46.h>
#include <skalibs/exec.h>
-#define USAGE "s6-tcpserver4-socketbinder [ -d | -D ] [ -b backlog ] [ -M | -m ] [ -B ] ip4 port prog..."
+#define USAGE "s6-tcpserver-socketbinder [ -d | -D ] [ -b backlog ] [ -M | -m ] [ -B ] ip port prog..."
#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const *const *argv)
@@ -22,9 +23,9 @@ int main (int argc, char const *const *argv)
int flagreuse = 1 ;
int flagudp = 0 ;
unsigned int flags = O_NONBLOCK ;
- char ip[4] ;
+ ip46 ip ;
uint16_t port ;
- PROG = "s6-tcpserver4-socketbinder" ;
+ PROG = "s6-tcpserver-socketbinder" ;
{
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
@@ -45,13 +46,13 @@ int main (int argc, char const *const *argv)
argc -= l.ind ; argv += l.ind ;
}
if (argc < 3) dieusage() ;
- if (!ip4_scan(argv[0], ip) || !uint160_scan(argv[1], &port)) dieusage() ;
+ if (!ip46_scan(argv[0], &ip) || !uint160_scan(argv[1], &port)) dieusage() ;
close(0) ;
- if (flagudp ? socket_udp4_internal(flags) : socket_tcp4_internal(flags))
+ if (flagudp ? socket_udp46_internal(ip46_is6(&ip), flags) : socket_tcp46_internal(ip46_is6(&ip), flags))
strerr_diefu1sys(111, "create socket") ;
- if ((flagreuse ? socket_bind4_reuse(0, ip, port) : socket_bind4(0, ip, port)) < 0)
+ if ((flagreuse ? socket_bind46_reuse(0, &ip, port) : socket_bind46(0, &ip, port)) == -1)
strerr_diefu5sys(111, "bind to ", argv[0], ":", argv[1], " ") ;
- if (backlog && socket_listen(0, backlog) < 0)
+ if (backlog && socket_listen(0, backlog) == -1)
strerr_diefu5sys(111, "listen to ", argv[0], ":", argv[1], " ") ;
xexec(argv+2) ;
diff --git a/src/conn-tools/s6-tcpserver.c b/src/conn-tools/s6-tcpserver.c
index 435fe0d..edc13ea 100644
--- a/src/conn-tools/s6-tcpserver.c
+++ b/src/conn-tools/s6-tcpserver.c
@@ -13,7 +13,7 @@
#include <s6-networking/config.h>
-#define USAGE "s6-tcpserver [ -q | -Q | -v ] [ -4 | -6 ] [ -d | -D ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] [ -b backlog ] [ -G gid,gid,... ] [ -g gid ] [ -u uid ] [ -U ] ip port prog..."
+#define USAGE "s6-tcpserver [ -q | -Q | -v ] [ -d | -D ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] [ -b backlog ] [ -G gid,gid,... ] [ -g gid ] [ -u uid ] [ -U ] ip port prog..."
#define dieusage() strerr_dieusage(100, USAGE)
int main (int argc, char const *const *argv)
@@ -29,13 +29,12 @@ int main (int argc, char const *const *argv)
unsigned int maxconn = 0 ;
unsigned int localmaxconn = 0 ;
unsigned int backlog = (unsigned int)-1 ;
- unsigned int what = 0 ;
PROG = "s6-tcpserver" ;
{
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
{
- int opt = subgetopt_r(argc, argv, "qQvDd1U46c:C:b:u:g:G:", &l) ;
+ int opt = subgetopt_r(argc, argv, "qQvDd1Uc:C:b:u:g:G:", &l) ;
if (opt == -1) break ;
switch (opt)
{
@@ -44,8 +43,6 @@ int main (int argc, char const *const *argv)
case 'v' : verbosity = 2 ; break ;
case 'D' : flagreuse = 0 ; break ;
case 'd' : flagreuse = 1 ; break ;
- case '4' : what = 4 ; break ;
- case '6' : what = 6 ; break ;
case 'c' : if (!uint0_scan(l.arg, &maxconn)) dieusage() ; if (!maxconn) maxconn = 1 ; break ;
case 'C' : if (!uint0_scan(l.arg, &localmaxconn)) dieusage() ; if (!localmaxconn) localmaxconn = 1 ; break ;
case 'b' : if (!uint0_scan(l.arg, &backlog)) dieusage() ; break ;
@@ -61,19 +58,12 @@ int main (int argc, char const *const *argv)
if (argc < 3) dieusage() ;
}
- if (!what)
- {
- ip46 ip ;
- if (!ip46_scan(argv[0], &ip)) dieusage() ;
- what = ip46_is6(&ip) ? 6 : 4 ;
- }
-
{
size_t pos = 0 ;
unsigned int m = 0 ;
char fmt[UINT_FMT * 3 + UID_FMT + GID_FMT * (NGROUPS_MAX + 1)] ;
char const *newargv[23 + argc] ;
- newargv[m++] = what == 6 ? S6_NETWORKING_BINPREFIX "s6-tcpserver6-socketbinder" : S6_NETWORKING_BINPREFIX "s6-tcpserver4-socketbinder" ;
+ newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver-socketbinder" ;
if (!flagreuse) newargv[m++] = "-D" ;
if (backlog != (unsigned int)-1)
{
@@ -112,7 +102,7 @@ int main (int argc, char const *const *argv)
}
newargv[m++] = "--" ;
}
- newargv[m++] = what == 6 ? S6_NETWORKING_BINPREFIX "s6-tcpserver6d" : S6_NETWORKING_BINPREFIX "s6-tcpserver4d" ;
+ newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserverd" ;
if (!verbosity) newargv[m++] = "-v0" ;
else if (verbosity == 2) newargv[m++] = "-v2" ;
if (flag1) newargv[m++] = "-1" ;
diff --git a/src/conn-tools/s6-tcpserver4.c b/src/conn-tools/s6-tcpserver4.c
deleted file mode 100644
index eb828a4..0000000
--- a/src/conn-tools/s6-tcpserver4.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ISC license. */
-
-#include <sys/types.h>
-#include <limits.h>
-
-#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr.h>
-#include <skalibs/exec.h>
-
-#include <s6/config.h>
-
-#include <s6-networking/config.h>
-
-#define USAGE "s6-tcpserver4 [ -v verbosity ] [ -d | -D ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] [ -b backlog ] [ -G gid,gid,... ] [ -g gid ] [ -u uid ] [ -U ] ip port prog..."
-#define dieusage() strerr_dieusage(100, USAGE)
-
-int main (int argc, char const *const *argv)
-{
- unsigned int verbosity = 1 ;
- int flag1 = 0 ;
- int flagU = 0 ;
- int flagreuse = 1 ;
- uid_t uid = 0 ;
- gid_t gid = 0 ;
- gid_t gids[NGROUPS_MAX] ;
- size_t gidn = (size_t)-1 ;
- unsigned int maxconn = 0 ;
- unsigned int localmaxconn = 0 ;
- unsigned int backlog = (unsigned int)-1 ;
- PROG = "s6-tcpserver4" ;
- {
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "Dd1Uv:c:C:b:u:g:G:", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'D' : flagreuse = 0 ; break ;
- case 'd' : flagreuse = 1 ; break ;
- case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
- case 'c' : if (!uint0_scan(l.arg, &maxconn)) dieusage() ; if (!maxconn) maxconn = 1 ; break ;
- case 'C' : if (!uint0_scan(l.arg, &localmaxconn)) dieusage() ; if (!localmaxconn) localmaxconn = 1 ; break ;
- case 'b' : if (!uint0_scan(l.arg, &backlog)) dieusage() ; break ;
- case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ;
- case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ;
- case 'G' : if (!gid_scanlist(gids, NGROUPS_MAX, l.arg, &gidn) && *l.arg) dieusage() ; break ;
- case '1' : flag1 = 1 ; break ;
- case 'U' : flagU = 1 ; uid = 0 ; gid = 0 ; gidn = (size_t)-1 ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- if (argc < 3) dieusage() ;
- }
-
- {
- size_t pos = 0 ;
- unsigned int m = 0 ;
- char fmt[UINT_FMT * 4 + UID_FMT + GID_FMT * (NGROUPS_MAX + 1)] ;
- char const *newargv[24 + argc] ;
- newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver4-socketbinder" ;
- if (!flagreuse) newargv[m++] = "-D" ;
- if (backlog != (unsigned int)-1)
- {
- if (!backlog) backlog = 1 ;
- newargv[m++] = "-b" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, backlog) ;
- fmt[pos++] = 0 ;
- }
- newargv[m++] = "--" ;
- newargv[m++] = *argv++ ;
- newargv[m++] = *argv++ ;
- if (flagU || uid || gid || gidn != (size_t)-1)
- {
- newargv[m++] = S6_EXTBINPREFIX "s6-applyuidgid" ;
- if (flagU) newargv[m++] = "-Uz" ;
- if (uid)
- {
- newargv[m++] = "-u" ;
- newargv[m++] = fmt + pos ;
- pos += uid_fmt(fmt + pos, uid) ;
- fmt[pos++] = 0 ;
- }
- if (gid)
- {
- newargv[m++] = "-g" ;
- newargv[m++] = fmt + pos ;
- pos += gid_fmt(fmt + pos, gid) ;
- fmt[pos++] = 0 ;
- }
- if (gidn != (size_t)-1)
- {
- newargv[m++] = "-G" ;
- newargv[m++] = fmt + pos ;
- pos += gid_fmtlist(fmt + pos, gids, gidn) ;
- fmt[pos++] = 0 ;
- }
- newargv[m++] = "--" ;
- }
- newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver4d" ;
- if (verbosity != 1)
- {
- newargv[m++] = "-v" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, verbosity) ;
- fmt[pos++] = 0 ;
- }
- if (flag1) newargv[m++] = "-1" ;
- if (maxconn)
- {
- newargv[m++] = "-c" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, maxconn) ;
- fmt[pos++] = 0 ;
- }
- if (localmaxconn)
- {
- newargv[m++] = "-C" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, localmaxconn) ;
- fmt[pos++] = 0 ;
- }
- newargv[m++] = "--" ;
- while (*argv) newargv[m++] = *argv++ ;
- newargv[m++] = 0 ;
- xexec(newargv) ;
- }
-}
diff --git a/src/conn-tools/s6-tcpserver6-socketbinder.c b/src/conn-tools/s6-tcpserver6-socketbinder.c
deleted file mode 100644
index b1c7dba..0000000
--- a/src/conn-tools/s6-tcpserver6-socketbinder.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/* ISC license. */
-
-#include <skalibs/nonposix.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/socket.h>
-
-#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/fmtscan.h>
-#include <skalibs/strerr.h>
-#include <skalibs/socket.h>
-#include <skalibs/exec.h>
-
-#define USAGE "s6-tcpserver6-socketbinder [ -d | -D ] [ -b backlog ] [ -M | -m ] [ -B ] ip6 port prog..."
-#define dieusage() strerr_dieusage(100, USAGE)
-
-int main (int argc, char const *const *argv)
-{
- unsigned int backlog = SOMAXCONN ;
- int flagreuse = 1 ;
- int flagudp = 0 ;
- unsigned int flags = O_NONBLOCK ;
- char ip[16] ;
- uint16_t port ;
- PROG = "s6-tcpserver6-socketbinder" ;
- {
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "DdMmBb:", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'D' : flagreuse = 0 ; break ;
- case 'd' : flagreuse = 1 ; break ;
- case 'M' : flagudp = 0 ; break ;
- case 'm' : flagudp = 1 ; break ;
- case 'B' : flags = 0 ; break ;
- case 'b' : if (!uint0_scan(l.arg, &backlog)) dieusage() ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- }
- if (argc < 3) dieusage() ;
- if (!ip6_scan(argv[0], ip) || !uint160_scan(argv[1], &port)) dieusage() ;
- close(0) ;
- if (flagudp ? socket_udp6_internal(flags) : socket_tcp6_internal(flags))
- strerr_diefu1sys(111, "create socket") ;
- if ((flagreuse ? socket_bind6_reuse(0, ip, port) : socket_bind6(0, ip, port)) < 0)
- strerr_diefu5sys(111, "bind to ", argv[0], ":", argv[1], " ") ;
- if (backlog && socket_listen(0, backlog) < 0)
- strerr_diefu5sys(111, "listen to ", argv[0], ":", argv[1], " ") ;
-
- xexec(argv+2) ;
-}
diff --git a/src/conn-tools/s6-tcpserver6.c b/src/conn-tools/s6-tcpserver6.c
deleted file mode 100644
index 491d7e0..0000000
--- a/src/conn-tools/s6-tcpserver6.c
+++ /dev/null
@@ -1,131 +0,0 @@
-/* ISC license. */
-
-#include <sys/types.h>
-#include <limits.h>
-
-#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr.h>
-#include <skalibs/exec.h>
-
-#include <s6/config.h>
-
-#include <s6-networking/config.h>
-
-#define USAGE "s6-tcpserver6 [ -v verbosity ] [ -d | -D ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] [ -b backlog ] [ -G gid,gid,... ] [ -g gid ] [ -u uid ] [ -U ] ip port prog..."
-#define dieusage() strerr_dieusage(100, USAGE)
-
-int main (int argc, char const *const *argv)
-{
- unsigned int verbosity = 1 ;
- int flag1 = 0 ;
- int flagU = 0 ;
- int flagreuse = 1 ;
- uid_t uid = 0 ;
- gid_t gid = 0 ;
- gid_t gids[NGROUPS_MAX] ;
- size_t gidn = (size_t)-1 ;
- unsigned int maxconn = 0 ;
- unsigned int localmaxconn = 0 ;
- unsigned int backlog = (unsigned int)-1 ;
- PROG = "s6-tcpserver6" ;
- {
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "Dd1Uv:c:C:b:u:g:G:", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'D' : flagreuse = 0 ; break ;
- case 'd' : flagreuse = 1 ; break ;
- case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
- case 'c' : if (!uint0_scan(l.arg, &maxconn)) dieusage() ; if (!maxconn) maxconn = 1 ; break ;
- case 'C' : if (!uint0_scan(l.arg, &localmaxconn)) dieusage() ; if (!localmaxconn) localmaxconn = 1 ; break ;
- case 'b' : if (!uint0_scan(l.arg, &backlog)) dieusage() ; break ;
- case 'u' : if (!uid0_scan(l.arg, &uid)) dieusage() ; break ;
- case 'g' : if (!gid0_scan(l.arg, &gid)) dieusage() ; break ;
- case 'G' : if (!gid_scanlist(gids, NGROUPS_MAX, l.arg, &gidn) && *l.arg) dieusage() ; break ;
- case '1' : flag1 = 1 ; break ;
- case 'U' : flagU = 1 ; uid = 0 ; gid = 0 ; gidn = (size_t)-1 ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- if (argc < 3) dieusage() ;
- }
-
- {
- size_t pos = 0 ;
- unsigned int m = 0 ;
- char fmt[UINT_FMT * 4 + UID_FMT + GID_FMT * (NGROUPS_MAX + 1)] ;
- char const *newargv[24 + argc] ;
- newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver6-socketbinder" ;
- if (!flagreuse) newargv[m++] = "-D" ;
- if (backlog != (unsigned int)-1)
- {
- if (!backlog) backlog = 1 ;
- newargv[m++] = "-b" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, backlog) ;
- fmt[pos++] = 0 ;
- }
- newargv[m++] = "--" ;
- newargv[m++] = *argv++ ;
- newargv[m++] = *argv++ ;
- if (flagU || uid || gid || gidn != (size_t)-1)
- {
- newargv[m++] = S6_EXTBINPREFIX "s6-applyuidgid" ;
- if (flagU) newargv[m++] = "-Uz" ;
- if (uid)
- {
- newargv[m++] = "-u" ;
- newargv[m++] = fmt + pos ;
- pos += uid_fmt(fmt + pos, uid) ;
- fmt[pos++] = 0 ;
- }
- if (gid)
- {
- newargv[m++] = "-g" ;
- newargv[m++] = fmt + pos ;
- pos += gid_fmt(fmt + pos, gid) ;
- fmt[pos++] = 0 ;
- }
- if (gidn != (size_t)-1)
- {
- newargv[m++] = "-G" ;
- newargv[m++] = fmt + pos ;
- pos += gid_fmtlist(fmt + pos, gids, gidn) ;
- fmt[pos++] = 0 ;
- }
- newargv[m++] = "--" ;
- }
- newargv[m++] = S6_NETWORKING_BINPREFIX "s6-tcpserver6d" ;
- if (verbosity != 1)
- {
- newargv[m++] = "-v" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, verbosity) ;
- fmt[pos++] = 0 ;
- }
- if (flag1) newargv[m++] = "-1" ;
- if (maxconn)
- {
- newargv[m++] = "-c" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, maxconn) ;
- fmt[pos++] = 0 ;
- }
- if (localmaxconn)
- {
- newargv[m++] = "-C" ;
- newargv[m++] = fmt + pos ;
- pos += uint_fmt(fmt + pos, localmaxconn) ;
- fmt[pos++] = 0 ;
- }
- newargv[m++] = "--" ;
- while (*argv) newargv[m++] = *argv++ ;
- newargv[m++] = 0 ;
- xexec(newargv) ;
- }
-}
diff --git a/src/conn-tools/s6-tcpserver6d.c b/src/conn-tools/s6-tcpserver6d.c
deleted file mode 100644
index 4168d91..0000000
--- a/src/conn-tools/s6-tcpserver6d.c
+++ /dev/null
@@ -1,374 +0,0 @@
-/* ISC license. */
-
-#include <string.h>
-#include <stdint.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <signal.h>
-
-#include <skalibs/posixplz.h>
-#include <skalibs/allreadwrite.h>
-#include <skalibs/types.h>
-#include <skalibs/sgetopt.h>
-#include <skalibs/strerr.h>
-#include <skalibs/fmtscan.h>
-#include <skalibs/env.h>
-#include <skalibs/cspawn.h>
-#include <skalibs/djbunix.h>
-#include <skalibs/sig.h>
-#include <skalibs/selfpipe.h>
-#include <skalibs/iopause.h>
-#include <skalibs/socket.h>
-
-#define ABSOLUTE_MAXCONN 16384
-
-#define USAGE "s6-tcpserver6d [ -v verbosity ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] prog..."
-
-typedef struct pidip_s pidip_t, *pidip_t_ref ;
-struct pidip_s
-{
- pid_t pid ;
- char ip[16] ;
-} ;
-
-typedef struct ipnum_s ipnum_t, *ipnum_t_ref ;
-struct ipnum_s
-{
- char ip[16] ;
- unsigned int num ;
-} ;
-
-static unsigned int maxconn = 40 ;
-static unsigned int localmaxconn = 40 ;
-static unsigned int verbosity = 1 ;
-static int cont = 1 ;
-static pidip_t *pidip = 0 ;
-static unsigned int numconn = 0 ;
-static ipnum_t *ipnum = 0 ;
-static unsigned int iplen = 0 ;
-
-static char fmtmaxconn[UINT_FMT+1] = "/" ;
-static char fmtlocalmaxconn[UINT_FMT+1] = "/" ;
-
-static inline void dieusage ()
-{
- strerr_dieusage(100, USAGE) ;
-}
-
-static inline void X (void)
-{
- strerr_dief1x(101, "internal inconsistency. Please submit a bug-report.") ;
-}
-
-static inline unsigned int lookup_pid (pid_t pid)
-{
- unsigned int i = 0 ;
- for (; i < numconn ; i++) if (pid == pidip[i].pid) break ;
- return i ;
-}
-
-static inline unsigned int lookup_ip (char const *ip)
-{
- unsigned int i = 0 ;
- for (; i < iplen ; i++) if (!memcmp(ip, ipnum[i].ip, 16)) break ;
- return i ;
-}
-
-static inline void log_start (void)
-{
- strerr_warni1x("starting") ;
-}
-
-static inline void log_exit (void)
-{
- strerr_warni1x("exiting") ;
-}
-
-static void log_status (void)
-{
- char fmt[UINT_FMT] ;
- fmt[uint_fmt(fmt, numconn)] = 0 ;
- strerr_warni3x("status: ", fmt, fmtmaxconn) ;
-}
-
-static inline void log_deny (char const *ip, uint16_t port, unsigned int num)
-{
- char fmtip[IP6_FMT] ;
- char fmtport[UINT16_FMT] ;
- char fmtnum[UINT_FMT] ;
- fmtip[ip6_fmt(fmtip, ip)] = 0 ;
- fmtport[uint16_fmt(fmtport, port)] = 0 ;
- fmtnum[uint_fmt(fmtnum, num)] = 0 ;
- strerr_warni7sys("deny ", fmtip, " port ", fmtport, " count ", fmtnum, fmtlocalmaxconn) ;
-}
-
-static inline void log_accept (pid_t pid, char const *ip, uint16_t port, unsigned int num)
-{
- char fmtipport[IP6_FMT + UINT16_FMT + 6] ;
- char fmtpid[PID_FMT] ;
- char fmtnum[UINT_FMT] ;
- size_t n ;
- n = ip6_fmt(fmtipport, ip) ;
- memcpy(fmtipport + n, " port ", 6) ; n += 6 ;
- n += uint16_fmt(fmtipport + n, port) ;
- fmtipport[n] = 0 ;
- fmtnum[uint_fmt(fmtnum, num)] = 0 ;
- fmtpid[pid_fmt(fmtpid, pid)] = 0 ;
- strerr_warni7x("allow ", fmtipport, " pid ", fmtpid, " count ", fmtnum, fmtlocalmaxconn) ;
-}
-
-static inline void log_close (pid_t pid, char const *ip, int w)
-{
- char fmtpid[PID_FMT] ;
- char fmtip[IP6_FMT] = "?" ;
- char fmtw[UINT_FMT] ;
- fmtpid[pid_fmt(fmtpid, pid)] = 0 ;
- fmtip[ip6_fmt(fmtip, ip)] = 0 ;
- fmtw[uint_fmt(fmtw, WIFSIGNALED(w) ? WTERMSIG(w) : WEXITSTATUS(w))] = 0 ;
- strerr_warni6x("end pid ", fmtpid, " ip ", fmtip, WIFSIGNALED(w) ? " signal " : " exitcode ", fmtw) ;
-}
-
-static void killthem (int sig)
-{
- unsigned int i = 0 ;
- for (; i < numconn ; i++) kill(pidip[i].pid, sig) ;
-}
-
-static inline void wait_children (void)
-{
- for (;;)
- {
- unsigned int i ;
- int w ;
- pid_t pid = wait_nohang(&w) ;
- if (pid < 0)
- if (errno != ECHILD) strerr_diefu1sys(111, "wait_nohang") ;
- else break ;
- else if (!pid) break ;
- i = lookup_pid(pid) ;
- if (i < numconn) /* it's one of ours ! */
- {
- unsigned int j = lookup_ip(pidip[i].ip) ;
- if (j >= iplen) X() ;
- if (!--ipnum[j].num) ipnum[j] = ipnum[--iplen] ;
- --numconn ;
- if (verbosity >= 2)
- {
- log_close(pid, pidip[i].ip, w) ;
- log_status() ;
- }
- pidip[i] = pidip[numconn] ;
- }
- }
-}
-
-static inline void handle_signals (void)
-{
- for (;;) switch (selfpipe_read())
- {
- case -1 : strerr_diefu1sys(111, "read selfpipe") ;
- case 0 : return ;
- case SIGCHLD : wait_children() ; break ;
- case SIGTERM :
- {
- if (verbosity >= 2)
- strerr_warni3x("received ", "SIGTERM,", " quitting") ;
- cont = 0 ;
- break ;
- }
- case SIGHUP :
- {
- if (verbosity >= 2)
- strerr_warni5x("received ", "SIGHUP,", " sending ", "SIGTERM+SIGCONT", " to all connections") ;
- killthem(SIGTERM) ;
- killthem(SIGCONT) ;
- break ;
- }
- case SIGQUIT :
- {
- if (verbosity >= 2)
- strerr_warni6x("received ", "SIGQUIT,", " sending ", "SIGTERM+SIGCONT", " to all connections", " and quitting") ;
- cont = 0 ;
- killthem(SIGTERM) ;
- killthem(SIGCONT) ;
- break ;
- }
- case SIGABRT :
- {
- if (verbosity >= 2)
- strerr_warni6x("received ", "SIGABRT,", " sending ", "SIGKILL", " to all connections", " and quitting") ;
- cont = 0 ;
- killthem(SIGKILL) ;
- break ;
- }
- default : X() ;
- }
-}
-
-static inline void new_connection (int s, char const *ip, uint16_t port, char const *const *argv, char const *const *envp, size_t envlen)
-{
- pid_t pid ;
- unsigned int i = lookup_ip(ip) ;
- unsigned int num = (i < iplen) ? ipnum[i].num : 0 ;
- size_t m = 0 ;
- char fmt[47 + IP6_FMT + UINT16_FMT + UINT_FMT] ;
-
- if (num >= localmaxconn)
- {
- log_deny(ip, port, num) ;
- return ;
- }
-
- memcpy(fmt + m, "PROTO=TCP\0TCPREMOTEIP=", 22) ; m += 22 ;
- m += ip6_fmt(fmt + m, ip) ; fmt[m++] = 0 ;
- memcpy(fmt + m, "TCPREMOTEPORT=", 14) ; m += 14 ;
- m += uint16_fmt(fmt + m, port) ; fmt[m++] = 0 ;
- memcpy(fmt + m, "TCPCONNNUM=", 11) ; m += 11 ;
- m += uint_fmt(fmt + m, num) ; fmt[m++] = 0 ;
-
- {
- cspawn_fileaction fa[2] =
- {
- [0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = 0, [1] = s } } },
- [1] = { .type = CSPAWN_FA_COPY, .x = { .fd2 = { [0] = 1, [1] = 0 } } }
- } ;
- char const *newenvp[envlen + 5] ;
- env_mergen(newenvp, envlen + 5, envp, envlen, fmt, m, 4) ;
- pid = cspawn(argv[0], argv, newenvp, CSPAWN_FLAGS_SELFPIPE_FINISH, fa, 2) ;
- }
- if (!pid)
- {
- if (verbosity) strerr_warnwu2sys("spawn ", argv[0]) ;
- return ;
- }
-
- if (i < iplen) ipnum[i].num = num + 1 ;
- else
- {
- memcpy(ipnum[iplen].ip, ip, 16) ;
- ipnum[iplen++].num = 1 ;
- }
- pidip[numconn].pid = pid ;
- memcpy(pidip[numconn++].ip, ip, 16) ;
- if (verbosity >= 2)
- {
- log_accept(pid, ip, port, ipnum[i].num) ;
- log_status() ;
- }
-}
-
-int main (int argc, char const *const *argv)
-{
- iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0, .events = IOPAUSE_READ | IOPAUSE_EXCEPT } } ;
- PROG = "s6-tcpserver6d" ;
- {
- subgetopt l = SUBGETOPT_ZERO ;
- int flag1 = 0 ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "1c:C:v:", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case '1' : flag1 = 1 ; break ;
- case 'c' : if (!uint0_scan(l.arg, &maxconn)) dieusage() ; break ;
- case 'C' : if (!uint0_scan(l.arg, &localmaxconn)) dieusage() ; break ;
- case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- if (!argc || !*argv[0]) dieusage() ;
- {
- struct stat st ;
- if (fstat(0, &st) < 0) strerr_diefu1sys(111, "fstat stdin") ;
- if (!S_ISSOCK(st.st_mode)) strerr_dief1x(100, "stdin is not a socket") ;
- }
- if (coe(0) < 0) strerr_diefu1sys(111, "make socket close-on-exec") ;
- if (flag1)
- {
- if (fcntl(1, F_GETFD) < 0)
- strerr_dief1sys(100, "called with option -1 but stdout said") ;
- }
- else close(1) ;
- if (!maxconn) maxconn = 1 ;
- if (maxconn > ABSOLUTE_MAXCONN) maxconn = ABSOLUTE_MAXCONN ;
- if (localmaxconn > maxconn) localmaxconn = maxconn ;
-
- x[0].fd = selfpipe_init() ;
- if (x[0].fd == -1) strerr_diefu1sys(111, "create selfpipe") ;
- if (!sig_altignore(SIGPIPE)) strerr_diefu1sys(111, "ignore SIGPIPE") ;
- {
- sigset_t set ;
- sigemptyset(&set) ;
- sigaddset(&set, SIGCHLD) ;
- sigaddset(&set, SIGTERM) ;
- sigaddset(&set, SIGHUP) ;
- sigaddset(&set, SIGQUIT) ;
- sigaddset(&set, SIGABRT) ;
- if (!selfpipe_trapset(&set)) strerr_diefu1sys(111, "trap signals") ;
- }
- if (flag1)
- {
- uint16_t port ;
- uint16_t m = 0 ;
- char ip[16] ;
- char fmtport[UINT16_FMT] ;
- if (socket_local6(0, ip, &port) == -1)
- {
- if (verbosity) strerr_warnwu1sys("socket_local6") ;
- }
- else m = uint16_fmt(fmtport, port) ;
- fmtport[m++] = '\n' ;
- allwrite(1, fmtport, m) ;
- fd_close(1) ;
- }
- fmtlocalmaxconn[1+uint_fmt(fmtlocalmaxconn+1, localmaxconn)] = 0 ;
- if (verbosity >= 2)
- {
- fmtmaxconn[1+uint_fmt(fmtmaxconn+1, maxconn)] = 0 ;
- log_start() ;
- log_status() ;
- }
- }
-
- {
- pidip_t pidip_inyostack[maxconn] ;
- ipnum_t ipnum_inyostack[maxconn] ;
- size_t envlen = env_len((char const *const *)environ) ;
- pidip = pidip_inyostack ; ipnum = ipnum_inyostack ;
-
- while (cont)
- {
- if (iopause_g(x, 1 + (numconn < maxconn), 0) < 0)
- strerr_diefu1sys(111, "iopause") ;
-
- if (x[0].revents & IOPAUSE_EXCEPT) strerr_dief1x(111, "trouble with selfpipe") ;
- if (x[0].revents & IOPAUSE_READ) { handle_signals() ; continue ; }
- if (numconn < maxconn)
- {
- if (x[1].revents & IOPAUSE_EXCEPT) strerr_dief1x(111, "trouble with socket") ;
- if (x[1].revents & IOPAUSE_READ)
- {
- char ip[16] ;
- uint16_t port ;
- int fd = socket_accept6(x[1].fd, ip, &port) ;
- if (fd < 0)
- {
- if (verbosity) strerr_warnwu1sys("accept") ;
- }
- else
- {
- new_connection(fd, ip, port, argv, (char const *const *)environ, envlen) ;
- fd_close(fd) ;
- }
- }
- }
- }
- }
- if (verbosity >= 2) log_exit() ;
- return 0 ;
-}
diff --git a/src/conn-tools/s6-tcpserver4d.c b/src/conn-tools/s6-tcpserverd.c
index 5982816..5a15dd9 100644
--- a/src/conn-tools/s6-tcpserver4d.c
+++ b/src/conn-tools/s6-tcpserverd.c
@@ -13,11 +13,11 @@
#include <skalibs/uint16.h>
#include <skalibs/uint32.h>
#include <skalibs/types.h>
+#include <skalibs/ip46.h>
#include <skalibs/allreadwrite.h>
#include <skalibs/sgetopt.h>
#include <skalibs/strerr.h>
#include <skalibs/fmtscan.h>
-#include <skalibs/diuint32.h>
#include <skalibs/env.h>
#include <skalibs/cspawn.h>
#include <skalibs/djbunix.h>
@@ -30,7 +30,13 @@
#define ABSOLUTE_MAXCONN 16384
-#define USAGE "s6-tcpserver4d [ -v verbosity ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] prog..."
+#define USAGE "s6-tcpserverd [ -v verbosity ] [ -1 ] [ -c maxconn ] [ -C localmaxconn ] prog..."
+
+static uint32_t maxconn = 40 ;
+static uint32_t localmaxconn = 40 ;
+static uint32_t verbosity = 1 ;
+static int cont = 1 ;
+static int is6 ;
typedef struct pidi_s pidi, *pidi_ref ;
struct pidi_s
@@ -39,21 +45,18 @@ struct pidi_s
uint32_t i ;
} ;
-static uint32_t maxconn = 40 ;
-static uint32_t localmaxconn = 40 ;
-static uint32_t verbosity = 1 ;
-static int cont = 1 ;
-
static genset *pidis ;
#define PIDI(i) genset_p(pidi, pidis, (i))
#define numconn genset_n(pidis)
+static avltreen *by_pid ;
+
static genset *ipnums ;
-#define IPNUM(i) genset_p(diuint32, ipnums, (i))
+#define IP(i) (genset_p(char, ipnums, (i)) + 4)
+#define NUMP(i) ((uint32_t *)genset_p(char, ipnums, (i)))
static avltreen *by_ip ;
-static avltreen *by_pid ;
-static char fmtmaxconn[UINT32_FMT+1] = "/" ;
-static char fmtlocalmaxconn[UINT32_FMT+1] = "/" ;
+static char fmtmaxconn[UINT32_FMT + 1] = "/" ;
+static char fmtlocalmaxconn[UINT32_FMT + 1] = "/" ;
static inline void dieusage ()
@@ -68,8 +71,7 @@ static inline void X (void)
static void *bypid_dtok (uint32_t d, void *aux)
{
- genset *g = aux ;
- return &genset_p(pidi, g, d)->pid ;
+ return &genset_p(pidi, (genset *)aux, d)->pid ;
}
static int bypid_cmp (void const *a, void const *b, void *aux)
@@ -82,21 +84,18 @@ static int bypid_cmp (void const *a, void const *b, void *aux)
static void *byip_dtok (uint32_t d, void *aux)
{
- genset *g = aux ;
- return &genset_p(diuint32, g, d)->left ;
+ return genset_p(char, (genset *)aux, d) + 4 ;
}
static int byip_cmp (void const *a, void const *b, void *aux)
{
(void)aux ;
- uint32_t aa = *(uint32_t const *)a ;
- uint32_t bb = *(uint32_t const *)b ;
- return aa < bb ? -1 : aa > bb ;
+ return memcmp(a, b, is6 ? 16 : 4) ;
}
-static inline void log_start (void)
+static inline void log_start (char const *fmtip, char const *fmtport)
{
- strerr_warni1x("starting") ;
+ strerr_warni4x("starting - bound to ip ", fmtip, " port ", fmtport) ;
}
static inline void log_exit (void)
@@ -111,41 +110,37 @@ static void log_status (void)
strerr_warni3x("status: ", fmt, fmtmaxconn) ;
}
-static inline void log_deny (uint32_t ip, uint16_t port, uint32_t num)
+static inline void log_deny (char const *ip, uint16_t port, uint32_t num)
{
- char fmtip[UINT32_FMT] ;
+ char fmtip[IP46_FMT] ;
char fmtport[UINT16_FMT] ;
char fmtnum[UINT32_FMT] ;
- fmtip[ip4_fmtu32(fmtip, ip)] = 0 ;
+ fmtip[is6 ? ip6_fmt(fmtip, ip) : ip4_fmt(fmtip, ip)] = 0 ;
fmtport[uint16_fmt(fmtport, port)] = 0 ;
fmtnum[uint32_fmt(fmtnum, num)] = 0 ;
strerr_warni7sys("deny ", fmtip, ":", fmtport, " count ", fmtnum, fmtlocalmaxconn) ;
}
-static inline void log_accept (pid_t pid, uint32_t ip, uint16_t port, uint32_t num)
+static inline void log_accept (pid_t pid, char const *ip, uint16_t port, uint32_t num)
{
- char fmtipport[IP4_FMT + UINT16_FMT + 1] ;
- char fmtpid[PID_FMT] ;
+ char fmtip[IP46_FMT] ;
+ char fmtport[UINT16_FMT] ;
char fmtnum[UINT32_FMT] ;
- size_t n ;
- n = ip4_fmtu32(fmtipport, ip) ;
- fmtipport[n++] = ':' ;
- n += uint16_fmt(fmtipport + n, port) ;
- fmtipport[n] = 0 ;
+ char fmtpid[PID_FMT] ;
+ fmtip[is6 ? ip6_fmt(fmtip, ip) : ip4_fmt(fmtip, ip)] = 0 ;
+ fmtport[uint16_fmt(fmtport, port)] = 0 ;
fmtnum[uint32_fmt(fmtnum, num)] = 0 ;
fmtpid[pid_fmt(fmtpid, pid)] = 0 ;
- strerr_warni7x("allow ", fmtipport, " pid ", fmtpid, " count ", fmtnum, fmtlocalmaxconn) ;
+ strerr_warni9x("allow ", fmtip, ":", fmtport, " pid ", fmtpid, " count ", fmtnum, fmtlocalmaxconn) ;
}
-static inline void log_close (pid_t pid, uint32_t ip, int w)
+static inline void log_close (pid_t pid, char const *ip, int w)
{
char fmtpid[PID_FMT] ;
- char fmtip[IP4_FMT] = "?" ;
char fmtw[UINT_FMT] ;
fmtpid[pid_fmt(fmtpid, pid)] = 0 ;
- fmtip[ip4_fmtu32(fmtip, ip)] = 0 ;
fmtw[uint_fmt(fmtw, WIFSIGNALED(w) ? WTERMSIG(w) : WEXITSTATUS(w))] = 0 ;
- strerr_warni6x("end pid ", fmtpid, " ip ", fmtip, WIFSIGNALED(w) ? " signal " : " exitcode ", fmtw) ;
+ strerr_warni4x("end pid ", fmtpid, WIFSIGNALED(w) ? " signal " : " exitcode ", fmtw) ;
}
static int killthem_iter (void *data, void *aux)
@@ -173,12 +168,13 @@ static inline void wait_children (void)
if (avltreen_search(by_pid, &pid, &d))
{
uint32_t i = PIDI(d)->i ;
- uint32_t ip = IPNUM(i)->left ;
+ char ip[SKALIBS_IP_SIZE] ;
+ memcpy(ip, IP(i), is6 ? 16 : 4) ;
avltreen_delete(by_pid, &pid) ;
genset_delete(pidis, d) ;
- if (!--IPNUM(i)->right)
+ if (!--*NUMP(i))
{
- avltreen_delete(by_ip, &ip) ;
+ avltreen_delete(by_ip, ip) ;
genset_delete(ipnums, i) ;
}
if (verbosity >= 2)
@@ -207,7 +203,7 @@ static inline void handle_signals (void)
case SIGHUP :
{
if (verbosity >= 2)
- strerr_warni5x("received ", "SIGHUP,", " sending ", "SIGTERM+SIGCONT", " to all connections") ;
+ strerr_warni5x("received ", "SIGHUP,", " sending ", "SIGTERM and SIGCONT", " to all connections") ;
killthem(SIGTERM) ;
killthem(SIGCONT) ;
break ;
@@ -215,7 +211,7 @@ static inline void handle_signals (void)
case SIGQUIT :
{
if (verbosity >= 2)
- strerr_warni6x("received ", "SIGQUIT,", " sending ", "SIGTERM+SIGCONT", " to all connections", " and quitting") ;
+ strerr_warni6x("received ", "SIGQUIT,", " sending ", "SIGTERM and SIGCONT", " to all connections", " and quitting") ;
cont = 0 ;
killthem(SIGTERM) ;
killthem(SIGCONT) ;
@@ -233,28 +229,25 @@ static inline void handle_signals (void)
}
}
-static inline void new_connection (int s, uint32_t ip, uint16_t port, char const *const *argv, char const *const *envp, size_t envlen)
+static inline void new_connection (int s, char const *ip, uint16_t port, char const *const *argv, char const *const *envp, char *modifs, size_t m, size_t envlen)
{
- size_t m = 0 ;
pid_t pid ;
uint32_t d ;
- uint32_t num = 0 ;
- char fmt[47 + IP4_FMT + UINT16_FMT + UINT_FMT] ;
-
- if (avltreen_search(by_ip, &ip, &d)) num = IPNUM(d)->right ;
+ uint32_t num = avltreen_search(by_ip, ip, &d) ? *NUMP(d) : 0 ;
if (num >= localmaxconn)
{
log_deny(ip, port, num) ;
return ;
}
- memcpy(fmt + m, "PROTO=TCP\0TCPREMOTEIP=", 22) ; m += 22 ;
- m += ip4_fmtu32(fmt + m, ip) ;
- fmt[m++] = 0 ;
- memcpy(fmt + m, "TCPREMOTEPORT=", 14) ; m += 14 ;
- m += uint16_fmt(fmt + m, port) ; fmt[m++] = 0 ;
- memcpy(fmt + m, "TCPCONNNUM=", 11) ; m += 11 ;
- m += uint_fmt(fmt + m, num) ; fmt[m++] = 0 ;
+ m += is6 ? ip6_fmt(modifs + m, ip) : ip4_fmt(modifs + m, ip) ;
+ modifs[m++] = 0 ;
+ memcpy(modifs + m, "TCPREMOTEPORT=", 14) ; m += 14 ;
+ m += uint16_fmt(modifs + m, port) ;
+ modifs[m++] = 0 ;
+ memcpy(modifs + m, "TCPCONNNUM=", 11) ; m += 11 ;
+ m += uint32_fmt(modifs + m, num) ;
+ modifs[m++] = 0 ;
{
cspawn_fileaction fa[2] =
@@ -262,22 +255,22 @@ static inline void new_connection (int s, uint32_t ip, uint16_t port, char const
[0] = { .type = CSPAWN_FA_MOVE, .x = { .fd2 = { [0] = 0, [1] = s } } },
[1] = { .type = CSPAWN_FA_COPY, .x = { .fd2 = { [0] = 1, [1] = 0 } } }
} ;
- char const *newenvp[envlen + 5] ;
- env_mergen(newenvp, envlen + 5, envp, envlen, fmt, m, 4) ;
+ char const *newenvp[envlen + 7] ;
+ env_mergen(newenvp, envlen + 7, envp, envlen, modifs, m, 6) ;
pid = cspawn(argv[0], argv, newenvp, CSPAWN_FLAGS_SELFPIPE_FINISH, fa, 2) ;
- }
- if (!pid)
- {
- if (verbosity) strerr_warnwu2sys("spawn ", argv[0]) ;
- return ;
+ if (!pid)
+ {
+ if (verbosity) strerr_warnwu2sys("spawn ", argv[0]) ;
+ return ;
+ }
}
- if (num) IPNUM(d)->right++ ;
+ if (num) (*NUMP(d))++ ;
else
{
d = genset_new(ipnums) ;
- IPNUM(d)->left = ip ;
- IPNUM(d)->right = 1 ;
+ *NUMP(d) = 1 ;
+ memcpy(IP(d), ip, is6 ? 16 : 4) ;
avltreen_insert(by_ip, d) ;
}
@@ -287,7 +280,7 @@ static inline void new_connection (int s, uint32_t ip, uint16_t port, char const
avltreen_insert(by_pid, num) ;
if (verbosity >= 2)
{
- log_accept(pid, ip, port, IPNUM(d)->right) ;
+ log_accept(pid, ip, port, *NUMP(d)) ;
log_status() ;
}
}
@@ -296,7 +289,7 @@ int main (int argc, char const *const *argv)
{
iopause_fd x[2] = { { .events = IOPAUSE_READ }, { .fd = 0, .events = IOPAUSE_READ | IOPAUSE_EXCEPT } } ;
int flag1 = 0 ;
- PROG = "s6-tcpserver4d" ;
+ PROG = "s6-tcpserverd" ;
{
subgetopt l = SUBGETOPT_ZERO ;
for (;;)
@@ -348,7 +341,8 @@ int main (int argc, char const *const *argv)
}
{
- diuint32 ipnum_storage[maxconn] ;
+ /* Yo dawg, I herd u like stack allocations */
+ char ipnum_storage[maxconn * (is6 ? 20 : 8)] ;
uint32_t ipnum_freelist[maxconn] ;
avlnode byip_storage[maxconn] ;
uint32_t byip_freelist[maxconn] ;
@@ -361,8 +355,12 @@ int main (int argc, char const *const *argv)
avltreen byip_info ;
avltreen bypid_info ;
size_t envlen = env_len((char const *const *)environ) ;
+ size_t m = 21 ;
+ char ip[SKALIBS_IP_SIZE] ;
+ uint16_t port ;
+ char modifs[sizeof("PROTO=TCP TCPLOCALIP= TCPLOCALPORT= TCPREMOTEIP= TCPREMOTEPORT= TCPCONNNUM=") + 2 * (IP46_FMT + UINT16_FMT) + UINT32_FMT] = "PROTO=TCP\0TCPLOCALIP=" ;
- GENSET_init(&ipnum_info, diuint32, ipnum_storage, ipnum_freelist, maxconn) ;
+ genset_init(&ipnum_info, ipnum_storage, ipnum_freelist, is6 ? 20 : 8, maxconn) ;
GENSET_init(&pidi_info, pidi, pidi_storage, pidi_freelist, maxconn) ;
avltreen_init(&byip_info, byip_storage, byip_freelist, maxconn, &byip_dtok, &byip_cmp, &ipnum_info) ;
avltreen_init(&bypid_info, bypid_storage, bypid_freelist, maxconn, &bypid_dtok, &bypid_cmp, &pidi_info) ;
@@ -371,51 +369,61 @@ int main (int argc, char const *const *argv)
by_ip = &byip_info ;
by_pid = &bypid_info ;
- if (verbosity >= 2)
- {
- fmtmaxconn[1+uint32_fmt(fmtmaxconn+1, maxconn)] = 0 ;
- log_start() ;
- log_status() ;
- }
-
- if (flag1)
{
- uint16_t port ;
- uint16_t m = 0 ;
- char ip[4] ;
+ size_t iplen, portlen ;
+ char fmtip[IP4_FMT] ;
char fmtport[UINT16_FMT] ;
- if (socket_local4(0, ip, &port) == -1)
+ ip46 loc ;
+ if (socket_local46(0, &loc, &port) == -1)
+ strerr_diefu1sys(111, "get local socket information") ;
+ is6 = ip46_is6(&loc) ;
+ memcpy(ip, loc.ip, is6 ? 16 : 4) ;
+ iplen = is6 ? ip6_fmt(fmtip, ip) : ip4_fmt(fmtip, ip) ;
+ portlen = uint16_fmt(fmtport, port) ;
+ memcpy(modifs + m, fmtip, iplen) ; m += iplen ;
+ memcpy(modifs + m, "\0TCPLOCALPORT=", 14) ; m += 14 ;
+ memcpy(modifs + m, fmtport, portlen) ; m += portlen ;
+ memcpy(modifs + m, "\0TCPREMOTEIP=", 13) ; m += 13 ;
+
+ if (verbosity >= 2)
{
- if (verbosity) strerr_warnwu1sys("socket_local4") ;
+ fmtmaxconn[1 + uint32_fmt(fmtmaxconn+1, maxconn)] = 0 ;
+ log_start(fmtip, fmtport) ;
+ log_status() ;
+ }
+
+ if (flag1)
+ {
+ fmtport[portlen] = '\n' ;
+ allwrite(1, fmtport, portlen + 1) ;
+ close(1) ;
}
- else m = uint16_fmt(fmtport, port) ;
- fmtport[m++] = '\n' ;
- allwrite(1, fmtport, m) ;
- close(1) ;
}
while (cont)
{
- if (iopause_g(x, 1 + (numconn < maxconn), 0) < 0) strerr_diefu1sys(111, "iopause") ;
+ if (iopause_g(x, 1 + (numconn < maxconn), 0) == -1)
+ strerr_diefu1sys(111, "iopause") ;
+
if (x[0].revents & IOPAUSE_EXCEPT) strerr_dief1x(111, "trouble with selfpipe") ;
- if (x[0].revents & IOPAUSE_READ) { handle_signals() ; continue ; }
+ if (x[0].revents & IOPAUSE_READ)
+ {
+ handle_signals() ;
+ continue ;
+ }
if (numconn < maxconn)
{
if (x[1].revents & IOPAUSE_EXCEPT) strerr_dief1x(111, "trouble with socket") ;
if (x[1].revents & IOPAUSE_READ)
{
- char packedip[4] ;
- uint16_t port ;
- int fd = socket_accept4(x[1].fd, packedip, &port) ;
+ int fd = is6 ? socket_accept6(x[1].fd, ip, &port) : socket_accept4(x[1].fd, ip, &port) ;
if (fd == -1)
{
if (verbosity) strerr_warnwu1sys("accept") ;
}
else
{
- uint32_t ip ;
- uint32_unpack_big(packedip, &ip) ;
- new_connection(fd, ip, port, argv, (char const *const *)environ, envlen) ;
+ new_connection(fd, ip, port, argv, (char const *const *)environ, modifs, m, envlen) ;
fd_close(fd) ;
}
}