be defined with intermediate certificates, and "ca-verify-file" with
certificates to ending the chain, like root CA.
+cc <algo>
+ This setting is only available on systems which define TCP_CONGESTION, and
+ was validated on Linux and FreeBSD. It takes the name of a TCP congestion
+ control algorithm and configures the listener to use this algorithm on all
+ connections that are accepted from this listener. Typical names include
+ "reno", "cubic" and will depend on the operating system. On some systems,
+ special permissions may be required to configure certain algorithms. On
+ Linux, the list of available algorithms may be found in the sysctl
+ "net.ipv4.tcp_available_congestion_control", and the list of those permitted
+ without privileges is in "net.ipv4.tcp_allowed_congestion_control". In order
+ to access algorithms requiring extra permissions, the "cap_net_admin"
+ capability might be required (see "setcap" in the global section). In case of
+ failure to configure a specific congestion control algorithm, the default one
+ will remain unchanged and a warning will be emitted to report the problem.
+ Example:
+
+ frontend public
+ bind :443 cc bbr # use the BBR algorithm for high bandwidths
+
ciphers <ciphers>
This setting is only available when support for OpenSSL was built in. It sets
the string describing the list of cipher algorithms ("cipher suite") that are
int maxseg; /* for TCP, advertised MSS */
int tcp_ut; /* for TCP, user timeout */
char *tcp_md5sig; /* TCP MD5 signature password (RFC2385) */
+ char *cc_algo; /* TCP congestion control algorithm ("cc" parameter) */
int idle_ping; /* MUX idle-ping interval in ms */
int maxaccept; /* if set, max number of connections accepted at once (-1 when disabled) */
unsigned int backlog; /* if set, listen backlog */
}
#endif
+#if defined(TCP_CONGESTION)
+/* parse the "cc" bind keyword */
+static int bind_parse_cc(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+ if (!*args[cur_arg + 1]) {
+ memprintf(err, "'%s' : missing TCP congestion control algorithm", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ ha_free(&conf->cc_algo);
+ conf->cc_algo = strdup(args[cur_arg + 1]);
+ if (!conf->cc_algo) {
+ memprintf(err, "'%s %s' : out of memory", args[cur_arg], args[cur_arg + 1]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ return 0;
+}
+#endif
+
#if defined(TCP_DEFER_ACCEPT) || defined(SO_ACCEPTFILTER)
/* parse the "defer-accept" bind keyword */
static int bind_parse_defer_accept(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
* not enabled.
*/
static struct bind_kw_list bind_kws = { "TCP", { }, {
+#if defined(TCP_CONGESTION)
+ { "cc", bind_parse_cc, 1 }, /* set TCP congestion control algorithm */
+#endif
#if defined(TCP_DEFER_ACCEPT) || defined(SO_ACCEPTFILTER)
{ "defer-accept", bind_parse_defer_accept, 0 }, /* wait for some data for 1 second max before doing accept */
#endif
bind_conf->rhttp_srvname = NULL;
bind_conf->tcp_md5sig = NULL;
+ bind_conf->cc_algo = NULL;
return bind_conf;
}
}
#endif
+
+#if defined(TCP_CONGESTION)
+ if (listener->bind_conf->cc_algo) {
+ /* Changing congestion control might fail due to loaded
+ * algorithms or permission. In this case the default algorithm
+ * remains active, but we can emit a warning about it to give a
+ * chance to the user to fix it.
+ */
+ if (setsockopt(fd, IPPROTO_TCP, TCP_CONGESTION, listener->bind_conf->cc_algo, strlen(listener->bind_conf->cc_algo)) < 0) {
+ chunk_appendf(msg, "%scannot set TCP congestion control algorithm, (%s)", msg->data ? ", " : "",
+ strerror(errno));
+ err |= ERR_WARN;
+ }
+ }
+#endif
+
#if defined(__linux__) && defined(TCP_MD5SIG)
if (listener->bind_conf->tcp_md5sig) {
struct tcp_md5sig md5;
free(bind_conf->guid_prefix);
free(bind_conf->rhttp_srvname);
free(bind_conf->tcp_md5sig);
+ free(bind_conf->cc_algo);
#ifdef USE_QUIC
free(bind_conf->quic_cc_algo);
#endif