Add a bit TCPI_OPT_SYN_DATA (32) to the socket option TCP_INFO:tcpi_options. It's set if the data in SYN (sent or received) is acked by SYN-ACK. Server or client application can use this information to check Fast Open success rate.
Unified · Split
| @@ -191,7 +191,8 @@ struct tcp_sock { · 190 unmodified lines | ||
| 191 | 191 | u8 do_early_retrans:1,/* Enable RFC5827 early-retransmit */ |
| 192 | 192 | early_retrans_delayed:1, /* Delayed ER timer installed */ |
| 193 | 193 | syn_data:1, /* SYN includes data */ |
| 194 | − syn_fastopen:1; /* SYN includes Fast Open option */ | |
| 194 | + syn_fastopen:1, /* SYN includes Fast Open option */ | |
| 195 | + syn_data_acked:1;/* data in SYN is acked by SYN-ACK */ | |
| 195 | 196 | |
| 196 | 197 | /* RTT measurement */ |
| 197 | 198 | u32 srtt; /* smoothed round trip time << 3 */ |
| @@ -130,6 +130,7 @@ enum { · 129 unmodified lines | ||
| 130 | 130 | #define TCPI_OPT_WSCALE 4 |
| 131 | 131 | #define TCPI_OPT_ECN 8 /* ECN was negociated at TCP session init */ |
| 132 | 132 | #define TCPI_OPT_ECN_SEEN 16 /* we received at least one packet with ECT */ |
| 133 | +#define TCPI_OPT_SYN_DATA 32 /* SYN-ACK acked data in SYN sent or rcvd */ | |
| 133 | 134 | |
| 134 | 135 | enum tcp_ca_state { |
| 135 | 136 | TCP_CA_Open = 0, |
| @@ -2764,6 +2764,8 @@ void tcp_get_info(const struct sock *sk, struct tcp_info *info) · 2763 unmodified lines | ||
| 2764 | 2764 | info->tcpi_options |= TCPI_OPT_ECN; |
| 2765 | 2765 | if (tp->ecn_flags & TCP_ECN_SEEN) |
| 2766 | 2766 | info->tcpi_options |= TCPI_OPT_ECN_SEEN; |
| 2767 | + if (tp->syn_data_acked) | |
| 2768 | + info->tcpi_options |= TCPI_OPT_SYN_DATA; | |
| 2767 | 2769 | |
| 2768 | 2770 | info->tcpi_rto = jiffies_to_usecs(icsk->icsk_rto); |
| 2769 | 2771 | info->tcpi_ato = jiffies_to_usecs(icsk->icsk_ack.ato); |
| @@ -5646,6 +5646,7 @@ static bool tcp_rcv_fastopen_synack(struct sock *sk, struct sk_buff *synack, · 5645 unmodified lines | ||
| 5646 | 5646 | tcp_rearm_rto(sk); |
| 5647 | 5647 | return true; |
| 5648 | 5648 | } |
| 5649 | + tp->syn_data_acked = tp->syn_data; | |
| 5649 | 5650 | return false; |
| 5650 | 5651 | } |
| 5651 | 5652 | |
| @@ -1461,6 +1461,7 @@ static int tcp_v4_conn_req_fastopen(struct sock *sk, · 1460 unmodified lines | ||
| 1461 | 1461 | skb_set_owner_r(skb, child); |
| 1462 | 1462 | __skb_queue_tail(&child->sk_receive_queue, skb); |
| 1463 | 1463 | tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq; |
| 1464 | + tp->syn_data_acked = 1; | |
| 1464 | 1465 | } |
| 1465 | 1466 | sk->sk_data_ready(sk, 0); |
| 1466 | 1467 | bh_unlock_sock(child); |
| @@ -510,6 +510,7 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, · 509 unmodified lines | ||
| 510 | 510 | newtp->rx_opt.mss_clamp = req->mss; |
| 511 | 511 | TCP_ECN_openreq_child(newtp, req); |
| 512 | 512 | newtp->fastopen_rsk = NULL; |
| 513 | + newtp->syn_data_acked = 0; | |
| 513 | 514 | |
| 514 | 515 | TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_PASSIVEOPENS); |
| 515 | 516 | } |