diff options
author | Yuchung Cheng <ycheng@google.com> | 2014-05-11 23:22:11 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-13 17:53:02 -0400 |
commit | 843f4a55e336e6d0c7bb92e7f9621535bc8d5fcd (patch) | |
tree | 17010fcb1b56174476b471758c3ca4f825ccbe7f /net/ipv4/tcp_minisocks.c | |
parent | 89278c9dc922272df921042aafa18311f3398c6c (diff) |
tcp: use tcp_v4_send_synack on first SYN-ACK
To avoid large code duplication in IPv6, we need to first simplify
the complicate SYN-ACK sending code in tcp_v4_conn_request().
To use tcp_v4(6)_send_synack() to send all SYN-ACKs, we need to
initialize the mini socket's receive window before trying to
create the child socket and/or building the SYN-ACK packet. So we move
that initialization from tcp_make_synack() to tcp_v4_conn_request()
as a new function tcp_openreq_init_req_rwin().
After this refactoring the SYN-ACK sending code is simpler and easier
to implement Fast Open for IPv6.
Signed-off-by: Yuchung Cheng <ycheng@google.com>
Signed-off-by: Daniel Lee <longinus00@gmail.com>
Signed-off-by: Jerry Chu <hkchu@google.com>
Acked-by: Neal Cardwell <ncardwell@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
-rw-r--r-- | net/ipv4/tcp_minisocks.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 05c1b155251d..e68e0d4af6c9 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -362,6 +362,37 @@ void tcp_twsk_destructor(struct sock *sk) | |||
362 | } | 362 | } |
363 | EXPORT_SYMBOL_GPL(tcp_twsk_destructor); | 363 | EXPORT_SYMBOL_GPL(tcp_twsk_destructor); |
364 | 364 | ||
365 | void tcp_openreq_init_rwin(struct request_sock *req, | ||
366 | struct sock *sk, struct dst_entry *dst) | ||
367 | { | ||
368 | struct inet_request_sock *ireq = inet_rsk(req); | ||
369 | struct tcp_sock *tp = tcp_sk(sk); | ||
370 | __u8 rcv_wscale; | ||
371 | int mss = dst_metric_advmss(dst); | ||
372 | |||
373 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) | ||
374 | mss = tp->rx_opt.user_mss; | ||
375 | |||
376 | /* Set this up on the first call only */ | ||
377 | req->window_clamp = tp->window_clamp ? : dst_metric(dst, RTAX_WINDOW); | ||
378 | |||
379 | /* limit the window selection if the user enforce a smaller rx buffer */ | ||
380 | if (sk->sk_userlocks & SOCK_RCVBUF_LOCK && | ||
381 | (req->window_clamp > tcp_full_space(sk) || req->window_clamp == 0)) | ||
382 | req->window_clamp = tcp_full_space(sk); | ||
383 | |||
384 | /* tcp_full_space because it is guaranteed to be the first packet */ | ||
385 | tcp_select_initial_window(tcp_full_space(sk), | ||
386 | mss - (ireq->tstamp_ok ? TCPOLEN_TSTAMP_ALIGNED : 0), | ||
387 | &req->rcv_wnd, | ||
388 | &req->window_clamp, | ||
389 | ireq->wscale_ok, | ||
390 | &rcv_wscale, | ||
391 | dst_metric(dst, RTAX_INITRWND)); | ||
392 | ireq->rcv_wscale = rcv_wscale; | ||
393 | } | ||
394 | EXPORT_SYMBOL(tcp_openreq_init_rwin); | ||
395 | |||
365 | static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, | 396 | static inline void TCP_ECN_openreq_child(struct tcp_sock *tp, |
366 | struct request_sock *req) | 397 | struct request_sock *req) |
367 | { | 398 | { |