From 8f8c92fe9357f9ef589e144042e1d1dba18c0bf1 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 23 Jul 2012 19:45:44 +0200 Subject: [PATCH] MAJOR: connection: add a new CO_FL_CONNECTED flag This new flag is used to indicate that the connection was already connected. It can be used by I/O handlers to know that a connection has just completed. It is used by stream_sock_update_conn(), allowing the sock_opt handlers not to manipulate the SI timeout nor the BF_WRITE_NULL flag anymore. --- include/types/connection.h | 1 + src/connection.c | 4 ++++ src/proto_tcp.c | 12 ------------ src/stream_interface.c | 6 ++++++ 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/include/types/connection.h b/include/types/connection.h index 2a7a9f5a0..578c5b5a6 100644 --- a/include/types/connection.h +++ b/include/types/connection.h @@ -39,6 +39,7 @@ enum { /* flags below are used for connection handshakes */ CO_FL_SI_SEND_PROXY = 0x00000004, /* send a valid PROXY protocol header */ CO_FL_NOTIFY_SI = 0x00000008, /* notify stream interface about changes */ + CO_FL_CONNECTED = 0x00000010, /* the connection is now established */ }; /* This structure describes a connection with its methods and data. diff --git a/src/connection.c b/src/connection.c index ef5838ab9..35db516bb 100644 --- a/src/connection.c +++ b/src/connection.c @@ -63,6 +63,10 @@ int conn_fd_handler(int fd) if (conn->flags & CO_FL_NOTIFY_SI) stream_sock_update_conn(conn); + /* Last check, verify if the connection just established */ + if (!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED))) + conn->flags |= CO_FL_CONNECTED; + /* remove the events before leaving */ fdtab[fd].ev &= ~(FD_POLL_IN | FD_POLL_OUT | FD_POLL_HUP | FD_POLL_ERR); return ret; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index c785384ec..04b325678 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -527,8 +527,6 @@ int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir) int tcp_connect_probe(struct connection *conn) { int fd = conn->t.sock.fd; - struct stream_interface *si = container_of(conn, struct stream_interface, conn); - struct buffer *b = si->ob; int retval = 0; if (conn->flags & CO_FL_ERROR) @@ -541,10 +539,6 @@ int tcp_connect_probe(struct connection *conn) if ((fdtab[fd].ev & (FD_POLL_IN|FD_POLL_HUP)) == FD_POLL_HUP) goto out_error; - /* we might have been called just after an asynchronous shutw */ - if (b->flags & BF_SHUTW) - goto out_wakeup; - /* We have no data to send to check the connection, and * getsockopt() will not inform us whether the connection * is still pending. So we'll reuse connect() to check the @@ -564,17 +558,11 @@ int tcp_connect_probe(struct connection *conn) /* otherwise we're connected */ } - /* OK we just need to indicate that we got a connection - * and that we wrote nothing. - */ - b->flags |= BF_WRITE_NULL; - /* The FD is ready now, we'll mark the connection as complete and * forward the event to the data layer which will update the stream * interface flags. */ conn->flags &= ~CO_FL_WAIT_L4_CONN; - si->exp = TICK_ETERNITY; out_wakeup: out_ignore: diff --git a/src/stream_interface.c b/src/stream_interface.c index 1a6db199a..8415abbb5 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -501,6 +501,12 @@ void stream_sock_update_conn(struct connection *conn) if (conn->flags & CO_FL_ERROR) si->flags |= SI_FL_ERR; + /* check for recent connection establishment */ + if (!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED))) { + si->exp = TICK_ETERNITY; + si->ob->flags |= BF_WRITE_NULL; + } + /* process consumer side, only once if possible */ if (fdtab[fd].ev & (FD_POLL_OUT | FD_POLL_ERR)) { if (si->ob->flags & BF_OUT_EMPTY) {