mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 18:23:32 +08:00
socket-proxyd: Add --listener option for listener/destination pairs.
This commit is contained in:
parent
828db5d84a
commit
adcf4c81c5
1
TODO
1
TODO
@ -105,7 +105,6 @@ Features:
|
||||
* remove NSS usage from PID 1 (notably the specifiers)
|
||||
|
||||
* socket-proxyd:
|
||||
- Support multiple inherited sockets mapped to different remote hosts
|
||||
- Use a nonblocking alternative to getaddrinfo
|
||||
- Until we can start daemons directly, find a less ugly, less racy alternative than shell scripts for the second man page example.
|
||||
- Support starting daemons directly without requiring a shell script; update man pages
|
||||
|
@ -31,6 +31,12 @@
|
||||
<surname>Strauss</surname>
|
||||
<email>david@davidstrauss.net</email>
|
||||
</author>
|
||||
<author>
|
||||
<contrib>Developer</contrib>
|
||||
<firstname>Lennart</firstname>
|
||||
<surname>Poettering</surname>
|
||||
<email>lennart@poettering.net</email>
|
||||
</author>
|
||||
</authorgroup>
|
||||
</refentryinfo>
|
||||
<refmeta>
|
||||
@ -83,6 +89,17 @@
|
||||
<title>Options</title>
|
||||
<para>The following options are understood:</para>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><option>-l</option></term>
|
||||
<term><option>--listener</option></term>
|
||||
<listitem>
|
||||
<para>Restricts listening to a
|
||||
single inherited socket, specified
|
||||
as a file descriptor. By default,
|
||||
the proxy listens on all inherited
|
||||
sockets.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><option>-h</option></term>
|
||||
<term><option>--help</option></term>
|
||||
@ -196,8 +213,12 @@ while [ ! -f /tmp/nginx.pid ]
|
||||
do
|
||||
/usr/bin/inotifywait /tmp/nginx.pid
|
||||
done
|
||||
exec /usr/bin/systemd-socket-proxyd localhost 8080]]>
|
||||
exec /usr/bin/systemd-socket-proxyd localhost:8080]]>
|
||||
</programlisting>
|
||||
<para>Make it executable:</para>
|
||||
<programlisting>
|
||||
<![CDATA[chmod 755 /usr/bin/socket-proxyd-nginx.sh]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
<example label="nginx configuration">
|
||||
<title>
|
||||
@ -215,6 +236,63 @@ server {
|
||||
<![CDATA[# systemctl enable proxy-with-nginx.socket
|
||||
# systemctl start proxy-with-nginx.socket
|
||||
$ curl http://localhost:80/]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title>Multiple Listeners with Multiple Destinations</title>
|
||||
<para>When using namespaces, it may be useful to
|
||||
have multiple listeners with each going to a unique
|
||||
destination. systemd always passes sockets into
|
||||
services in the order specified in the socket
|
||||
unit, beginning with file descriptor 3.</para>
|
||||
<para>In this example, port <literal>80</literal>
|
||||
will proxy to <literal>localhost:8080</literal>,
|
||||
and port <literal>443</literal> will proxy to
|
||||
<literal>localhost:8443</literal>.</para>
|
||||
<example label="proxy socket unit">
|
||||
<title>/etc/systemd/system/multi-destination.socket</title>
|
||||
<programlisting>
|
||||
<![CDATA[[Socket]
|
||||
ListenStream=80
|
||||
ListenStream=443
|
||||
|
||||
[Install]
|
||||
WantedBy=sockets.target]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
<example label="proxy service unit">
|
||||
<title>/etc/systemd/system/multi-destination.service</title>
|
||||
<programlisting>
|
||||
<![CDATA[[Service]
|
||||
ExecStart=/usr/bin/socket-proxyd-multi-destination.sh
|
||||
PrivateTmp=true
|
||||
PrivateNetwork=true]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example label="shell script">
|
||||
<title>
|
||||
/usr/bin/socket-proxyd-multi-destination.sh</title>
|
||||
<programlisting>
|
||||
<![CDATA[#!/bin/sh
|
||||
/usr/bin/systemd-socket-proxyd --listener=3 localhost:8080 &
|
||||
/usr/bin/systemd-socket-proxyd --listener=4 localhost:8443 &
|
||||
wait]]>
|
||||
</programlisting>
|
||||
<para>Make it executable:</para>
|
||||
<programlisting>
|
||||
<![CDATA[chmod 755 /usr/bin/socket-proxyd-multi-destination.sh]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<example label="commands">
|
||||
<programlisting>
|
||||
<![CDATA[# systemctl enable multi-destination.socket
|
||||
# systemctl start multi-destination.socket
|
||||
$ curl http://localhost/
|
||||
$ curl https://localhost/]]>
|
||||
</programlisting>
|
||||
</example>
|
||||
</refsect2>
|
||||
|
@ -66,6 +66,7 @@ typedef struct Connection {
|
||||
} Connection;
|
||||
|
||||
static const char *arg_remote_host = NULL;
|
||||
static int arg_listener = -1;
|
||||
|
||||
static void connection_free(Connection *c) {
|
||||
assert(c);
|
||||
@ -554,8 +555,9 @@ static int help(void) {
|
||||
printf("%s [HOST:PORT]\n"
|
||||
"%s [SOCKET]\n\n"
|
||||
"Bidirectionally proxy local sockets to another (possibly remote) socket.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n",
|
||||
" -l --listener=FD Listen on a specific, single file descriptor.\n"
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n",
|
||||
program_invocation_short_name,
|
||||
program_invocation_short_name);
|
||||
|
||||
@ -565,22 +567,22 @@ static int help(void) {
|
||||
static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_IGNORE_ENV
|
||||
ARG_VERSION = 0x100
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "listener", required_argument, NULL, 'l' },
|
||||
{}
|
||||
};
|
||||
|
||||
int c;
|
||||
int c, fd;
|
||||
|
||||
assert(argc >= 0);
|
||||
assert(argv);
|
||||
|
||||
while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
|
||||
while ((c = getopt_long(argc, argv, "hl:", options, NULL)) >= 0) {
|
||||
|
||||
switch (c) {
|
||||
|
||||
@ -592,6 +594,18 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
puts(SYSTEMD_FEATURES);
|
||||
return 0;
|
||||
|
||||
case 'l':
|
||||
if (safe_atoi(optarg, &fd) < 0) {
|
||||
log_error("Failed to parse listener file descriptor: %s", optarg);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (fd < SD_LISTEN_FDS_START) {
|
||||
log_error("Listener file descriptor must be at least %d.", SD_LISTEN_FDS_START);
|
||||
return -EINVAL;
|
||||
}
|
||||
arg_listener = fd;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -632,19 +646,26 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
n = sd_listen_fds(1);
|
||||
if (n < 0) {
|
||||
log_error("Failed to receive sockets from parent.");
|
||||
r = n;
|
||||
goto finish;
|
||||
} else if (n == 0) {
|
||||
log_error("Didn't get any sockets passed in.");
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
|
||||
r = add_listen_socket(&context, event, fd);
|
||||
if (arg_listener == -1) {
|
||||
n = sd_listen_fds(1);
|
||||
if (n < 0) {
|
||||
log_error("Failed to receive sockets from parent.");
|
||||
r = n;
|
||||
goto finish;
|
||||
} else if (n == 0) {
|
||||
log_error("Didn't get any sockets passed in.");
|
||||
r = -EINVAL;
|
||||
goto finish;
|
||||
}
|
||||
log_info("Listening on %d inherited socket(s), starting with fd=%d.", n, SD_LISTEN_FDS_START);
|
||||
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + n; fd++) {
|
||||
r = add_listen_socket(&context, event, fd);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
log_info("Listening on single inherited socket fd=%d.", arg_listener);
|
||||
r = add_listen_socket(&context, event, arg_listener);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user