Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67da22d2 authored by Yuchung Cheng's avatar Yuchung Cheng Committed by David S. Miller
Browse files

net-tcp: Fast Open client - cookie-less mode



In trusted networks, e.g., intranet, data-center, the client does not
need to use Fast Open cookie to mitigate DoS attacks. In cookie-less
mode, sendmsg() with MSG_FASTOPEN flag will send SYN-data regardless
of cookie availability.

Signed-off-by: default avatarYuchung Cheng <ycheng@google.com>
Acked-by: default avatarEric Dumazet <edumazet@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent aab48743
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -476,6 +476,8 @@ tcp_fastopen - INTEGER

	The values (bitmap) are:
	1: Enables sending data in the opening SYN on the client
	5: Enables sending data in the opening SYN on the client regardless
	   of cookie availability.

	Default: 0

+1 −0
Original line number Diff line number Diff line
@@ -387,6 +387,7 @@ struct tcp_sock {
	u8	repair_queue;
	u8	do_early_retrans:1,/* Enable RFC5827 early-retransmit  */
		early_retrans_delayed:1, /* Delayed ER timer installed */
		syn_data:1,	/* SYN includes data */
		syn_fastopen:1;	/* SYN includes Fast Open option */

/* RTT measurement */
+1 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo);

/* Bit Flags for sysctl_tcp_fastopen */
#define	TFO_CLIENT_ENABLE	1
#define	TFO_CLIENT_NO_COOKIE	4	/* Data in SYN w/o cookie option */

extern struct inet_timewait_death_row tcp_death_row;

+6 −2
Original line number Diff line number Diff line
@@ -5650,7 +5650,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
				    struct tcp_fastopen_cookie *cookie)
{
	struct tcp_sock *tp = tcp_sk(sk);
	struct sk_buff *data = tcp_write_queue_head(sk);
	struct sk_buff *data = tp->syn_data ? tcp_write_queue_head(sk) : NULL;
	u16 mss = tp->rx_opt.mss_clamp;
	bool syn_drop;

@@ -5665,6 +5665,9 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack,
		mss = opt.mss_clamp;
	}

	if (!tp->syn_fastopen)  /* Ignore an unsolicited cookie */
		cookie->len = -1;

	/* The SYN-ACK neither has cookie nor acknowledges the data. Presumably
	 * the remote receives only the retransmitted (regular) SYNs: either
	 * the original SYN-data or the corresponding SYN-ACK is lost.
@@ -5816,7 +5819,8 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,

		tcp_finish_connect(sk, skb);

		if (tp->syn_fastopen && tcp_rcv_fastopen_synack(sk, skb, &foc))
		if ((tp->syn_fastopen || tp->syn_data) &&
		    tcp_rcv_fastopen_synack(sk, skb, &foc))
			return -1;

		if (sk->sk_write_pending ||
+5 −1
Original line number Diff line number Diff line
@@ -2864,6 +2864,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
	struct sk_buff *syn_data = NULL, *data;
	unsigned long last_syn_loss = 0;

	tp->rx_opt.mss_clamp = tp->advmss;  /* If MSS is not cached */
	tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie,
			       &syn_loss, &last_syn_loss);
	/* Recurring FO SYN losses: revert to regular handshake temporarily */
@@ -2873,7 +2874,9 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
		goto fallback;
	}

	if (fo->cookie.len <= 0)
	if (sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE)
		fo->cookie.len = -1;
	else if (fo->cookie.len <= 0)
		goto fallback;

	/* MSS for SYN-data is based on cached MSS and bounded by PMTU and
@@ -2916,6 +2919,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
	fo->copied = data->len;

	if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) {
		tp->syn_data = (fo->copied > 0);
		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE);
		goto done;
	}