diff options
-rw-r--r-- | Documentation/networking/ip-sysctl.txt | 2 | ||||
-rw-r--r-- | include/linux/tcp.h | 1 | ||||
-rw-r--r-- | include/net/tcp.h | 1 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 8 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 6 |
5 files changed, 15 insertions, 3 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index 03964e088180..5f3ef7f7fcec 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
@@ -476,6 +476,8 @@ tcp_fastopen - INTEGER | |||
476 | 476 | ||
477 | The values (bitmap) are: | 477 | The values (bitmap) are: |
478 | 1: Enables sending data in the opening SYN on the client | 478 | 1: Enables sending data in the opening SYN on the client |
479 | 5: Enables sending data in the opening SYN on the client regardless | ||
480 | of cookie availability. | ||
479 | 481 | ||
480 | Default: 0 | 482 | Default: 0 |
481 | 483 | ||
diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 1edf96afab44..9febfb685c33 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h | |||
@@ -387,6 +387,7 @@ struct tcp_sock { | |||
387 | u8 repair_queue; | 387 | u8 repair_queue; |
388 | u8 do_early_retrans:1,/* Enable RFC5827 early-retransmit */ | 388 | u8 do_early_retrans:1,/* Enable RFC5827 early-retransmit */ |
389 | early_retrans_delayed:1, /* Delayed ER timer installed */ | 389 | early_retrans_delayed:1, /* Delayed ER timer installed */ |
390 | syn_data:1, /* SYN includes data */ | ||
390 | syn_fastopen:1; /* SYN includes Fast Open option */ | 391 | syn_fastopen:1; /* SYN includes Fast Open option */ |
391 | 392 | ||
392 | /* RTT measurement */ | 393 | /* RTT measurement */ |
diff --git a/include/net/tcp.h b/include/net/tcp.h index e07878d246aa..bc7c134ec054 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -214,6 +214,7 @@ extern void tcp_time_wait(struct sock *sk, int state, int timeo); | |||
214 | 214 | ||
215 | /* Bit Flags for sysctl_tcp_fastopen */ | 215 | /* Bit Flags for sysctl_tcp_fastopen */ |
216 | #define TFO_CLIENT_ENABLE 1 | 216 | #define TFO_CLIENT_ENABLE 1 |
217 | #define TFO_CLIENT_NO_COOKIE 4 /* Data in SYN w/o cookie option */ | ||
217 | 218 | ||
218 | extern struct inet_timewait_death_row tcp_death_row; | 219 | extern struct inet_timewait_death_row tcp_death_row; |
219 | 220 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c49a4fc175bd..e67d685a6c0e 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5650,7 +5650,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
5650 | struct tcp_fastopen_cookie *cookie) | 5650 | struct tcp_fastopen_cookie *cookie) |
5651 | { | 5651 | { |
5652 | struct tcp_sock *tp = tcp_sk(sk); | 5652 | struct tcp_sock *tp = tcp_sk(sk); |
5653 | struct sk_buff *data = tcp_write_queue_head(sk); | 5653 | struct sk_buff *data = tp->syn_data ? tcp_write_queue_head(sk) : NULL; |
5654 | u16 mss = tp->rx_opt.mss_clamp; | 5654 | u16 mss = tp->rx_opt.mss_clamp; |
5655 | bool syn_drop; | 5655 | bool syn_drop; |
5656 | 5656 | ||
@@ -5665,6 +5665,9 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, | |||
5665 | mss = opt.mss_clamp; | 5665 | mss = opt.mss_clamp; |
5666 | } | 5666 | } |
5667 | 5667 | ||
5668 | if (!tp->syn_fastopen) /* Ignore an unsolicited cookie */ | ||
5669 | cookie->len = -1; | ||
5670 | |||
5668 | /* The SYN-ACK neither has cookie nor acknowledges the data. Presumably | 5671 | /* The SYN-ACK neither has cookie nor acknowledges the data. Presumably |
5669 | * the remote receives only the retransmitted (regular) SYNs: either | 5672 | * the remote receives only the retransmitted (regular) SYNs: either |
5670 | * the original SYN-data or the corresponding SYN-ACK is lost. | 5673 | * 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, | |||
5816 | 5819 | ||
5817 | tcp_finish_connect(sk, skb); | 5820 | tcp_finish_connect(sk, skb); |
5818 | 5821 | ||
5819 | if (tp->syn_fastopen && tcp_rcv_fastopen_synack(sk, skb, &foc)) | 5822 | if ((tp->syn_fastopen || tp->syn_data) && |
5823 | tcp_rcv_fastopen_synack(sk, skb, &foc)) | ||
5820 | return -1; | 5824 | return -1; |
5821 | 5825 | ||
5822 | if (sk->sk_write_pending || | 5826 | if (sk->sk_write_pending || |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index c5cfd5ec3184..27a32acfdb62 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2864,6 +2864,7 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
2864 | struct sk_buff *syn_data = NULL, *data; | 2864 | struct sk_buff *syn_data = NULL, *data; |
2865 | unsigned long last_syn_loss = 0; | 2865 | unsigned long last_syn_loss = 0; |
2866 | 2866 | ||
2867 | tp->rx_opt.mss_clamp = tp->advmss; /* If MSS is not cached */ | ||
2867 | tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie, | 2868 | tcp_fastopen_cache_get(sk, &tp->rx_opt.mss_clamp, &fo->cookie, |
2868 | &syn_loss, &last_syn_loss); | 2869 | &syn_loss, &last_syn_loss); |
2869 | /* Recurring FO SYN losses: revert to regular handshake temporarily */ | 2870 | /* 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) | |||
2873 | goto fallback; | 2874 | goto fallback; |
2874 | } | 2875 | } |
2875 | 2876 | ||
2876 | if (fo->cookie.len <= 0) | 2877 | if (sysctl_tcp_fastopen & TFO_CLIENT_NO_COOKIE) |
2878 | fo->cookie.len = -1; | ||
2879 | else if (fo->cookie.len <= 0) | ||
2877 | goto fallback; | 2880 | goto fallback; |
2878 | 2881 | ||
2879 | /* MSS for SYN-data is based on cached MSS and bounded by PMTU and | 2882 | /* 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) | |||
2916 | fo->copied = data->len; | 2919 | fo->copied = data->len; |
2917 | 2920 | ||
2918 | if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) { | 2921 | if (tcp_transmit_skb(sk, syn_data, 0, sk->sk_allocation) == 0) { |
2922 | tp->syn_data = (fo->copied > 0); | ||
2919 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE); | 2923 | NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPFASTOPENACTIVE); |
2920 | goto done; | 2924 | goto done; |
2921 | } | 2925 | } |