mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-23 07:12:09 +00:00
[TCP]: TCP_DEFER_ACCEPT updates - process as established
Change TCP_DEFER_ACCEPT implementation so that it transitions a connection to ESTABLISHED after handshake is complete instead of leaving it in SYN-RECV until some data arrvies. Place connection in accept queue when first data packet arrives from slow path. Benefits: - established connection is now reset if it never makes it to the accept queue - diagnostic state of established matches with the packet traces showing completed handshake - TCP_DEFER_ACCEPT timeouts are expressed in seconds and can now be enforced with reasonable accuracy instead of rounding up to next exponential back-off of syn-ack retry. Signed-off-by: Patrick McManus <mcmanus@ducksong.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e4c7884028
commit
ec3c0982a2
9 changed files with 99 additions and 33 deletions
|
@ -571,10 +571,8 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
|
|||
does sequence test, SYN is truncated, and thus we consider
|
||||
it a bare ACK.
|
||||
|
||||
If icsk->icsk_accept_queue.rskq_defer_accept, we silently drop this
|
||||
bare ACK. Otherwise, we create an established connection. Both
|
||||
ends (listening sockets) accept the new incoming connection and try
|
||||
to talk to each other. 8-)
|
||||
Both ends (listening sockets) accept the new incoming
|
||||
connection and try to talk to each other. 8-)
|
||||
|
||||
Note: This case is both harmless, and rare. Possibility is about the
|
||||
same as us discovering intelligent life on another plant tomorrow.
|
||||
|
@ -642,13 +640,6 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
|
|||
if (!(flg & TCP_FLAG_ACK))
|
||||
return NULL;
|
||||
|
||||
/* If TCP_DEFER_ACCEPT is set, drop bare ACK. */
|
||||
if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
|
||||
TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
|
||||
inet_rsk(req)->acked = 1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* OK, ACK is valid, create big socket and
|
||||
* feed this segment to it. It will repeat all
|
||||
* the tests. THIS SEGMENT MUST MOVE SOCKET TO
|
||||
|
@ -687,7 +678,24 @@ struct sock *tcp_check_req(struct sock *sk,struct sk_buff *skb,
|
|||
inet_csk_reqsk_queue_unlink(sk, req, prev);
|
||||
inet_csk_reqsk_queue_removed(sk, req);
|
||||
|
||||
inet_csk_reqsk_queue_add(sk, req, child);
|
||||
if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept &&
|
||||
TCP_SKB_CB(skb)->end_seq == tcp_rsk(req)->rcv_isn + 1) {
|
||||
|
||||
/* the accept queue handling is done is est recv slow
|
||||
* path so lets make sure to start there
|
||||
*/
|
||||
tcp_sk(child)->pred_flags = 0;
|
||||
sock_hold(sk);
|
||||
sock_hold(child);
|
||||
tcp_sk(child)->defer_tcp_accept.listen_sk = sk;
|
||||
tcp_sk(child)->defer_tcp_accept.request = req;
|
||||
|
||||
inet_csk_reset_keepalive_timer(child,
|
||||
inet_csk(sk)->icsk_accept_queue.rskq_defer_accept * HZ);
|
||||
} else {
|
||||
inet_csk_reqsk_queue_add(sk, req, child);
|
||||
}
|
||||
|
||||
return child;
|
||||
|
||||
listen_overflow:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue