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

Commit 07e100f9 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller
Browse files

tcp: restore fastopen with no data in SYN packet



Yuchung tracked a regression caused by commit 57be5bda ("ip: convert
tcp_sendmsg() to iov_iter primitives") for TCP Fast Open.

Some Fast Open users do not actually add any data in the SYN packet.

Fixes: 57be5bda ("ip: convert tcp_sendmsg() to iov_iter primitives")
Reported-by: default avatarYuchung Cheng <ycheng@google.com>
Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Acked-by: default avatarYuchung Cheng <ycheng@google.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3822b5c2
Loading
Loading
Loading
Loading
+12 −11
Original line number Original line Diff line number Diff line
@@ -3150,7 +3150,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
{
{
	struct tcp_sock *tp = tcp_sk(sk);
	struct tcp_sock *tp = tcp_sk(sk);
	struct tcp_fastopen_request *fo = tp->fastopen_req;
	struct tcp_fastopen_request *fo = tp->fastopen_req;
	int syn_loss = 0, space, err = 0, copied;
	int syn_loss = 0, space, err = 0;
	unsigned long last_syn_loss = 0;
	unsigned long last_syn_loss = 0;
	struct sk_buff *syn_data;
	struct sk_buff *syn_data;


@@ -3188,7 +3188,8 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
		goto fallback;
		goto fallback;
	syn_data->ip_summed = CHECKSUM_PARTIAL;
	syn_data->ip_summed = CHECKSUM_PARTIAL;
	memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
	memcpy(syn_data->cb, syn->cb, sizeof(syn->cb));
	copied = copy_from_iter(skb_put(syn_data, space), space,
	if (space) {
		int copied = copy_from_iter(skb_put(syn_data, space), space,
					    &fo->data->msg_iter);
					    &fo->data->msg_iter);
		if (unlikely(!copied)) {
		if (unlikely(!copied)) {
			kfree_skb(syn_data);
			kfree_skb(syn_data);
@@ -3198,7 +3199,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn)
			skb_trim(syn_data, copied);
			skb_trim(syn_data, copied);
			space = copied;
			space = copied;
		}
		}

	}
	/* No more data pending in inet_wait_for_connect() */
	/* No more data pending in inet_wait_for_connect() */
	if (space == fo->size)
	if (space == fo->size)
		fo->data = NULL;
		fo->data = NULL;