Skip to content
  • Eric Dumazet's avatar
    tcp: better retrans tracking for defer-accept · e6c022a4
    Eric Dumazet authored
    
    
    For passive TCP connections using TCP_DEFER_ACCEPT facility,
    we incorrectly increment req->retrans each time timeout triggers
    while no SYNACK is sent.
    
    SYNACK are not sent for TCP_DEFER_ACCEPT that were established (for
    which we received the ACK from client). Only the last SYNACK is sent
    so that we can receive again an ACK from client, to move the req into
    accept queue. We plan to change this later to avoid the useless
    retransmit (and potential problem as this SYNACK could be lost)
    
    TCP_INFO later gives wrong information to user, claiming imaginary
    retransmits.
    
    Decouple req->retrans field into two independent fields :
    
    num_retrans : number of retransmit
    num_timeout : number of timeouts
    
    num_timeout is the counter that is incremented at each timeout,
    regardless of actual SYNACK being sent or not, and used to
    compute the exponential timeout.
    
    Introduce inet_rtx_syn_ack() helper to increment num_retrans
    only if ->rtx_syn_ack() succeeded.
    
    Use inet_rtx_syn_ack() from tcp_check_req() to increment num_retrans
    when we re-send a SYNACK in answer to a (retransmitted) SYN.
    Prior to this patch, we were not counting these retransmits.
    
    Change tcp_v[46]_rtx_synack() to increment TCP_MIB_RETRANSSEGS
    only if a synack packet was successfully queued.
    
    Reported-by: default avatarYuchung Cheng <ycheng@google.com>
    Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
    Cc: Julian Anastasov <ja@ssi.bg>
    Cc: Vijay Subramanian <subramanian.vijay@gmail.com>
    Cc: Elliott Hughes <enh@google.com>
    Cc: Neal Cardwell <ncardwell@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    e6c022a4