diff --git a/include/proto/connection.h b/include/proto/connection.h index a64296071..a36906d18 100644 --- a/include/proto/connection.h +++ b/include/proto/connection.h @@ -43,6 +43,18 @@ int conn_fd_handler(int fd); int conn_recv_proxy(struct connection *conn, int flag); int make_proxy_line(char *buf, int buf_len, struct sockaddr_storage *src, struct sockaddr_storage *dst); +/* returns true is the transport layer is ready */ +static inline int conn_xprt_ready(struct connection *conn) +{ + return (conn->flags & CO_FL_XPRT_READY) && conn->xprt; +} + +/* returns true is the control layer is ready */ +static inline int conn_ctrl_ready(struct connection *conn) +{ + return (conn->flags & CO_FL_CTRL_READY); +} + /* Calls the init() function of the transport layer if any and if not done yet, * and sets the CO_FL_XPRT_READY flag to indicate it was properly initialized. * Returns <0 in case of error. diff --git a/include/proto/stream_interface.h b/include/proto/stream_interface.h index 7ab72ce7a..5408f1e05 100644 --- a/include/proto/stream_interface.h +++ b/include/proto/stream_interface.h @@ -149,6 +149,16 @@ static inline void si_attach_conn(struct stream_interface *si, struct connection conn_attach(conn, si, &si_conn_cb); } +/* Returns true if a connection is attached to the stream interface and + * if this connection is ready. + */ +static inline int si_conn_ready(struct stream_interface *si) +{ + struct connection *conn = objt_conn(si->end); + + return conn && conn_ctrl_ready(conn) && conn_xprt_ready(conn); +} + /* Attach appctx to the stream interface . The stream interface * is configured to work with an applet context. It is left to the caller to * call appctx_set_applet() to assign an applet to this context. diff --git a/src/stream_interface.c b/src/stream_interface.c index 34438d7e3..f2650d364 100644 --- a/src/stream_interface.c +++ b/src/stream_interface.c @@ -389,7 +389,7 @@ int conn_si_send_proxy(struct connection *conn, unsigned int flag) if (conn->flags & CO_FL_SOCK_WR_SH) goto out_error; - if (!(conn->flags & CO_FL_CTRL_READY)) + if (!conn_ctrl_ready(conn)) goto out_error; /* If we have a PROXY line to send, we'll use this to validate the @@ -812,7 +812,7 @@ static void stream_int_shutw_conn(struct stream_interface *si) /* quick close, the socket is alredy shut anyway */ } else if (si->flags & SI_FL_NOLINGER) { - if ((conn->flags & CO_FL_CTRL_READY) && conn->ctrl) { + if (conn_ctrl_ready(conn)) { setsockopt(conn->t.sock.fd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger)); } @@ -833,7 +833,7 @@ static void stream_int_shutw_conn(struct stream_interface *si) */ if (!(si->flags & SI_FL_NOHALF) || !(si->ib->flags & (CF_SHUTR|CF_DONT_READ))) { /* We shutdown transport layer */ - if ((conn->flags & CO_FL_CTRL_READY) && conn->ctrl) + if (conn_ctrl_ready(conn)) shutdown(conn->t.sock.fd, SHUT_WR); if (!(si->ib->flags & (CF_SHUTR|CF_DONT_READ))) { @@ -931,13 +931,13 @@ static void stream_int_chk_snd_conn(struct stream_interface *si) /* Before calling the data-level operations, we have to prepare * the polling flags to ensure we properly detect changes. */ - if ((conn->flags & CO_FL_CTRL_READY) && conn->ctrl) + if (conn_ctrl_ready(conn)) fd_want_send(conn->t.sock.fd); conn_refresh_polling_flags(conn); si_conn_send(conn); - if ((conn->flags & CO_FL_CTRL_READY) && (conn->flags & CO_FL_ERROR)) { + if (conn_ctrl_ready(conn) && (conn->flags & CO_FL_ERROR)) { /* Write error on the file descriptor */ fd_stop_both(conn->t.sock.fd); __conn_data_stop_both(conn); @@ -1287,7 +1287,7 @@ void stream_sock_read0(struct stream_interface *si) /* we want to immediately forward this close to the write side */ if (si->flags & SI_FL_NOLINGER) { si->flags &= ~SI_FL_NOLINGER; - if (conn->flags & CO_FL_CTRL_READY) + if (conn_ctrl_ready(conn)) setsockopt(conn->t.sock.fd, SOL_SOCKET, SO_LINGER, (struct linger *) &nolinger, sizeof(struct linger)); }