introduction of spoofed TCP segments into the connection stream. But it can
be useful for any very long-lived TCP connections.
+tcp-ss <mode>
+ Sets the TCP Save SYN option for all incoming connections instantiated from
+ this listening socket. This option is available on Linux since version 4.3.
+ It instructs the kernel to try to keep a copy of the incoming IP packet
+ containing the TCP SYN flag, for later inspection. The option knows 3 modes:
+ - 0 SYN packet saving is disabled, this is the default
+ - 1 SYN packet saving is enabled, and contains IP and TCP headers
+ - 2 SYN packet saving is enabled, and contains ETH, IP and TCP headers
+
+ This only works for regular TCP connections, and is ignored for other
+ protocols (e.g. UNIX sockets). See also "fc.saved_syn".
+
tcp-ut <delay>
Sets the TCP User Timeout for all incoming connections instantiated from this
listening socket. This option is available on Linux since version 2.6.37. It
unsigned int backlog; /* if set, listen backlog */
int maxconn; /* maximum connections allowed on this listener */
int (*accept)(struct connection *conn); /* upper layer's accept() */
+ int tcp_ss; /* for TCP, Save SYN */
int level; /* stats access level (ACCESS_LVL_*) */
int severity_output; /* default severity output format in cli feedback messages */
short int nice; /* nice value to assign to the instantiated tasks */
}
#endif
+#ifdef TCP_SAVE_SYN
+/* parse the "tcp-ss" bind keyword */
+static int bind_parse_tcp_ss(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
+{
+ int tcp_ss = -1;
+
+ if (isdigit((unsigned char)*args[cur_arg + 1]))
+ tcp_ss = atoi(args[cur_arg + 1]);
+
+ if (tcp_ss < 0 || tcp_ss > 2) {
+ memprintf(err, "'%s' : TCP Save SYN option expects an integer argument from 0 to 2", args[cur_arg]);
+ return ERR_ALERT | ERR_FATAL;
+ }
+
+ conf->tcp_ss = tcp_ss;
+ return 0;
+}
+#endif
+
#ifdef TCP_USER_TIMEOUT
/* parse the "tcp-ut" bind keyword */
static int bind_parse_tcp_ut(char **args, int cur_arg, struct proxy *px, struct bind_conf *conf, char **err)
#if defined(__linux__) && defined(TCP_MD5SIG)
{ "tcp-md5sig", bind_parse_tcp_md5sig, 1 }, /* set TCP MD5 signature password */
#endif
+#ifdef TCP_SAVE_SYN
+ { "tcp-ss", bind_parse_tcp_ss, 1 }, /* set TCP Save SYN option (0=no, 1=yes, 2=with MAC hdr) */
+#endif
#ifdef TCP_USER_TIMEOUT
{ "tcp-ut", bind_parse_tcp_ut, 1 }, /* set User Timeout on listening socket */
#endif
}
}
#endif
+#if defined(TCP_SAVE_SYN)
+ if (listener->bind_conf->tcp_ss) {
+ if (setsockopt(fd, IPPROTO_TCP, TCP_SAVE_SYN,
+ &listener->bind_conf->tcp_ss, sizeof(listener->bind_conf->tcp_ss)) == -1) {
+ chunk_appendf(msg, "%scannot set TCP Save SYN, (%s)", msg->data ? ", " : "",
+ strerror(errno));
+ err |= ERR_WARN;
+ }
+ } else
+ setsockopt(fd, IPPROTO_TCP, TCP_SAVE_SYN, &zero, sizeof(zero));
+#endif
#if defined(TCP_USER_TIMEOUT)
if (listener->bind_conf->tcp_ut) {
if (setsockopt(fd, IPPROTO_TCP, TCP_USER_TIMEOUT,