summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.socket.xml12
-rw-r--r--src/load-fragment.c1
-rw-r--r--src/socket.c14
-rw-r--r--src/socket.h1
4 files changed, 26 insertions, 2 deletions
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index 20dc00ed01..a7b8228aa0 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -438,6 +438,18 @@
</varlistentry>
<varlistentry>
+ <term><varname>TCPCongestion=</varname></term>
+ <listitem><para>Takes a string
+ value. Controls the TCP congestion
+ algorithm used by this socket. Should
+ be one of "westwood", "veno", "cubic",
+ "lp" or any other available algorithm
+ supported by the IP stack. This
+ setting applies only to stream
+ sockets.</para></listitem>
+ </varlistentry>
+
+ <varlistentry>
<term><varname>ExecStartPre=</varname></term>
<term><varname>ExecStartPost=</varname></term>
<listitem><para>Takes one or more
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 98f16f9a23..f2f2d72837 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1616,6 +1616,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "Mark", config_parse_int, &u->socket.mark, "Socket" },
{ "PipeSize", config_parse_size, &u->socket.pipe_size, "Socket" },
{ "FreeBind", config_parse_bool, &u->socket.free_bind, "Socket" },
+ { "TCPCongestion", config_parse_string, &u->socket.tcp_congestion, "Socket" },
EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
{ "What", config_parse_string, &u->mount.parameters_fragment.what, "Mount" },
diff --git a/src/socket.c b/src/socket.c
index 82a9348d13..2da3215a3d 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -31,6 +31,7 @@
#include "unit.h"
#include "socket.h"
+#include "netinet/tcp.h"
#include "log.h"
#include "load-dropin.h"
#include "load-fragment.h"
@@ -116,6 +117,9 @@ static void socket_done(Unit *u) {
s->service = NULL;
+ free(s->tcp_congestion);
+ s->tcp_congestion = NULL;
+
free(s->bind_to_device);
s->bind_to_device = NULL;
@@ -371,14 +375,16 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) {
"%sSocketMode: %04o\n"
"%sDirectoryMode: %04o\n"
"%sKeepAlive: %s\n"
- "%sFreeBind: %s\n",
+ "%sFreeBind: %s\n"
+ "%sTCPCongestion: %s\n",
prefix, socket_state_to_string(s->state),
prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
prefix, s->backlog,
prefix, s->socket_mode,
prefix, s->directory_mode,
prefix, yes_no(s->keep_alive),
- prefix, yes_no(s->free_bind));
+ prefix, yes_no(s->free_bind),
+ prefix, s->tcp_congestion);
if (s->control_pid > 0)
fprintf(f,
@@ -632,6 +638,10 @@ static void socket_apply_socket_options(Socket *s, int fd) {
if (r < 0 && x < 0)
log_warning("IP_TTL/IPV6_UNICAST_HOPS failed: %m");
}
+
+ if (s->tcp_congestion)
+ if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
+ log_warning("TCP_CONGESTION failed: %m");
}
static void socket_apply_fifo_options(Socket *s, int fd) {
diff --git a/src/socket.h b/src/socket.h
index 88ebf26f87..230dd200d5 100644
--- a/src/socket.h
+++ b/src/socket.h
@@ -114,6 +114,7 @@ struct Socket {
int mark;
bool free_bind;
char *bind_to_device;
+ char *tcp_congestion;
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
SocketAddressBindIPv6Only bind_ipv6_only;