mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-21 13:16:57 +00:00
MAJOR: connection: call data layer handshakes from the handler
Handshakes is not called anymore from the data handlers, they're only called from the connection handler when their flag is set. Also, this move has uncovered an issue with the stream interface notifier : it doesn't consider the FD_WAIT_* flags possibly set by the handshake handlers. This will result in a stuck handshake when no data is in the output buffer. In order to cover this, for now we'll perform the EV_FD_SET in the SSL handshake function, but this needs to be addressed separately from the stream interface operations.
This commit is contained in:
parent
0b0c097a3a
commit
c76ae33bfc
@ -35,11 +35,17 @@ struct protocol;
|
||||
enum {
|
||||
CO_FL_NONE = 0x00000000,
|
||||
CO_FL_ERROR = 0x00000001, /* a fatal error was reported */
|
||||
CO_FL_WAIT_L4_CONN = 0x00000002, /* waiting for L4 to be connected */
|
||||
CO_FL_CONNECTED = 0x00000002, /* the connection is now established */
|
||||
CO_FL_WAIT_L4_CONN = 0x00000004, /* waiting for L4 to be connected */
|
||||
CO_FL_WAIT_L6_CONN = 0x00000008, /* waiting for L6 to be connected (eg: SSL) */
|
||||
|
||||
CO_FL_NOTIFY_SI = 0x00000010, /* notify stream interface about changes */
|
||||
|
||||
/* 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 */
|
||||
CO_FL_SI_SEND_PROXY = 0x00000020, /* send a valid PROXY protocol header */
|
||||
|
||||
/* below we have all handshake flags grouped into one */
|
||||
CO_FL_HANDSHAKE = CO_FL_SI_SEND_PROXY,
|
||||
};
|
||||
|
||||
/* This structure describes a connection with its methods and data.
|
||||
|
@ -27,31 +27,48 @@ int conn_fd_handler(int fd)
|
||||
struct connection *conn = fdtab[fd].owner;
|
||||
int ret = 0;
|
||||
|
||||
if (!conn)
|
||||
if (unlikely(!conn))
|
||||
goto leave;
|
||||
|
||||
if (conn->flags & CO_FL_ERROR)
|
||||
goto leave;
|
||||
|
||||
if (conn->flags & CO_FL_SI_SEND_PROXY)
|
||||
if ((ret = conn_si_send_proxy(conn, CO_FL_SI_SEND_PROXY)))
|
||||
process_handshake:
|
||||
while (unlikely(conn->flags & CO_FL_HANDSHAKE)) {
|
||||
if (unlikely(conn->flags & CO_FL_ERROR))
|
||||
goto leave;
|
||||
|
||||
if (conn->flags & CO_FL_SI_SEND_PROXY)
|
||||
if ((ret = conn_si_send_proxy(conn, CO_FL_SI_SEND_PROXY)))
|
||||
goto leave;
|
||||
}
|
||||
|
||||
/* OK now we're in the data phase now */
|
||||
|
||||
if (fdtab[fd].ev & (FD_POLL_IN | FD_POLL_HUP | FD_POLL_ERR))
|
||||
if (!conn->data->read(conn))
|
||||
ret |= FD_WAIT_READ;
|
||||
|
||||
if (conn->flags & CO_FL_ERROR)
|
||||
if (unlikely(conn->flags & CO_FL_ERROR))
|
||||
goto leave;
|
||||
|
||||
/* It may happen during the data phase that a handshake is
|
||||
* enabled again (eg: SSL)
|
||||
*/
|
||||
if (unlikely(conn->flags & CO_FL_HANDSHAKE))
|
||||
goto process_handshake;
|
||||
|
||||
if (fdtab[fd].ev & (FD_POLL_OUT | FD_POLL_ERR))
|
||||
if (!conn->data->write(conn))
|
||||
ret |= FD_WAIT_WRITE;
|
||||
|
||||
if (conn->flags & CO_FL_ERROR)
|
||||
if (unlikely(conn->flags & CO_FL_ERROR))
|
||||
goto leave;
|
||||
|
||||
if (conn->flags & CO_FL_WAIT_L4_CONN) {
|
||||
/* It may happen during the data phase that a handshake is
|
||||
* enabled again (eg: SSL)
|
||||
*/
|
||||
if (unlikely(conn->flags & CO_FL_HANDSHAKE))
|
||||
goto process_handshake;
|
||||
|
||||
if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN)) {
|
||||
/* still waiting for a connection to establish and no data to
|
||||
* send in order to probe it ? Then let's retry the connect().
|
||||
*/
|
||||
@ -64,7 +81,7 @@ int conn_fd_handler(int fd)
|
||||
stream_sock_update_conn(conn);
|
||||
|
||||
/* Last check, verify if the connection just established */
|
||||
if (!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED)))
|
||||
if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED))))
|
||||
conn->flags |= CO_FL_CONNECTED;
|
||||
|
||||
/* remove the events before leaving */
|
||||
|
@ -502,7 +502,7 @@ void stream_sock_update_conn(struct connection *conn)
|
||||
si->flags |= SI_FL_ERR;
|
||||
|
||||
/* check for recent connection establishment */
|
||||
if (!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_CONNECTED))) {
|
||||
if (unlikely(!(conn->flags & (CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN | CO_FL_CONNECTED)))) {
|
||||
si->exp = TICK_ETERNITY;
|
||||
si->ob->flags |= BF_WRITE_NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user