Hi,
attached path extends socket configurables with another
knob - TCP Congestion Avoidance selection. Linux implements
handful of those, useful in various situations. For example,
TCP Low Priority may be used by FTP service to gracefully
yield bandwidth for more important TCP/IP streams.
Until recently TCP_CONGESTION was Linux-specific, recently
FreeBSD 8 and OpenSolaris gained compatible support.
address. Defaults to <option>false</option>.</para></listitem>
</varlistentry>
address. Defaults to <option>false</option>.</para></listitem>
</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>
<varlistentry>
<term><varname>ExecStartPre=</varname></term>
<term><varname>ExecStartPost=</varname></term>
{ "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" },
{ "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" },
EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
{ "What", config_parse_string, &u->mount.parameters_fragment.what, "Mount" },
#include "unit.h"
#include "socket.h"
#include "unit.h"
#include "socket.h"
+#include "netinet/tcp.h"
#include "log.h"
#include "load-dropin.h"
#include "load-fragment.h"
#include "log.h"
#include "load-dropin.h"
#include "load-fragment.h"
+ free(s->tcp_congestion);
+ s->tcp_congestion = NULL;
+
free(s->bind_to_device);
s->bind_to_device = NULL;
free(s->bind_to_device);
s->bind_to_device = NULL;
"%sSocketMode: %04o\n"
"%sDirectoryMode: %04o\n"
"%sKeepAlive: %s\n"
"%sSocketMode: %04o\n"
"%sDirectoryMode: %04o\n"
"%sKeepAlive: %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, 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,
if (s->control_pid > 0)
fprintf(f,
if (r < 0 && x < 0)
log_warning("IP_TTL/IPV6_UNICAST_HOPS failed: %m");
}
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) {
}
static void socket_apply_fifo_options(Socket *s, int fd) {
int mark;
bool free_bind;
char *bind_to_device;
int mark;
bool free_bind;
char *bind_to_device;
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
SocketAddressBindIPv6Only bind_ipv6_only;
/* Only for INET6 sockets: issue IPV6_V6ONLY sockopt */
SocketAddressBindIPv6Only bind_ipv6_only;