• Willy Tarreau's avatar
    net/tcp-fastopen: make connect()'s return case more consistent with non-TFO · 3979ad7e
    Willy Tarreau authored
    Without TFO, any subsequent connect() call after a successful one returns
    -1 EISCONN. The last API update ensured that __inet_stream_connect() can
    return -1 EINPROGRESS in response to sendmsg() when TFO is in use to
    indicate that the connection is now in progress. Unfortunately since this
    function is used both for connect() and sendmsg(), it has the undesired
    side effect of making connect() now return -1 EINPROGRESS as well after
    a successful call, while at the same time poll() returns POLLOUT. This
    can confuse some applications which happen to call connect() and to
    check for -1 EISCONN to ensure the connection is usable, and for which
    EINPROGRESS indicates a need to poll, causing a loop.
    
    This problem was encountered in haproxy where a call to connect() is
    precisely used in certain cases to confirm a connection's readiness.
    While arguably haproxy's behaviour should be improved here, it seems
    important to aim at a more robust behaviour when the goal of the new
    API is to make it easier to implement TFO in existing applications.
    
    This patch simply ensures that we preserve the same semantics as in
    the non-TFO case on the connect() syscall when using TFO, while still
    returning -1 EINPROGRESS on sendmsg(). For this we simply tell
    __inet_stream_connect() whether we're doing a regular connect() or in
    fact connecting for a sendmsg() call.
    
    Cc: Wei Wang <weiwan@google.com>
    Cc: Yuchung Cheng <ycheng@google.com>
    Cc: Eric Dumazet <edumazet@google.com>
    Signed-off-by: default avatarWilly Tarreau <w@1wt.eu>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    3979ad7e
tcp.c 88.1 KB