]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: proto_tcp: remove any dependence on stream_interface
authorWilly Tarreau <wtarreau@exceliance.fr>
Thu, 30 Aug 2012 20:23:13 +0000 (22:23 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 3 Sep 2012 18:47:34 +0000 (20:47 +0200)
The last uses of the stream interfaces were in tcp_connect_server() and
could easily and more appropriately be moved to its callers, si_connect()
and connect_server(), making a lot more sense.

Now the function should theorically be usable for health checks.

It also appears more obvious that the file is split into two distinct
parts :
  - the protocol layer used at the connection level
  - the tcp analysers executing tcp-* rules and their samples/acls.

include/proto/proto_tcp.h
include/proto/stream_interface.h
include/types/connection.h
include/types/protocols.h
src/backend.c
src/proto_tcp.c

index cdc1d3744aabe22a54381beec76e025ced3a96ba..5b6bf4499daaf008abf3c28373a05a1020cc6990 100644 (file)
@@ -30,7 +30,7 @@
 int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct sockaddr_storage *remote);
 void tcpv4_add_listener(struct listener *listener);
 void tcpv6_add_listener(struct listener *listener);
-int tcp_connect_server(struct stream_interface *si);
+int tcp_connect_server(struct connection *conn, int data);
 int tcp_connect_probe(struct connection *conn);
 int tcp_get_src(int fd, struct sockaddr *sa, socklen_t salen, int dir);
 int tcp_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
index 8cd4a31bd0c5955b176107be1f3007d277d2241f..05a321028b0074602c68a4b9d1426bf38a1a3713 100644 (file)
@@ -27,6 +27,7 @@
 #include <common/config.h>
 #include <types/session.h>
 #include <types/stream_interface.h>
+#include <proto/channel.h>
 #include <proto/connection.h>
 
 
@@ -128,9 +129,30 @@ static inline void si_chk_snd(struct stream_interface *si)
 /* Calls chk_snd on the connection using the ctrl layer */
 static inline int si_connect(struct stream_interface *si)
 {
+       int ret;
+
        if (unlikely(!si_ctrl(si) || !si_ctrl(si)->connect))
                return SN_ERR_INTERNAL;
-       return si_ctrl(si)->connect(si);
+
+       ret = si_ctrl(si)->connect(&si->conn, !channel_is_empty(si->ob));
+       if (ret != SN_ERR_NONE)
+               return ret;
+
+       /* needs src ip/port for logging */
+       if (si->flags & SI_FL_SRC_ADDR)
+               conn_get_from_addr(&si->conn);
+
+       /* Prepare to send a few handshakes related to the on-wire protocol. */
+       if (si->send_proxy_ofs)
+               si->conn.flags |= CO_FL_SI_SEND_PROXY;
+
+       /* we need to be notified about connection establishment */
+       si->conn.flags |= CO_FL_NOTIFY_SI;
+
+       /* we're in the process of establishing a connection */
+       si->state = SI_ST_CON;
+
+       return ret;
 }
 
 #endif /* _PROTO_STREAM_INTERFACE_H */
index 2612eaf92feff9e2775aef5c3a9109f3e9449e41..2fbd7793066001e338a12ee59358e46cb4d419cb 100644 (file)
@@ -80,6 +80,8 @@ enum {
         */
        CO_FL_POLL_SOCK     = CO_FL_HANDSHAKE | CO_FL_WAIT_L4_CONN | CO_FL_WAIT_L6_CONN,
 
+       /* This flag is set if lingering has already been disabled on the connection */
+
        /* These flags are used to report whether the from/to addresses are set or not */
        CO_FL_ADDR_FROM_SET = 0x00001000,  /* addr.from is set */
        CO_FL_ADDR_TO_SET   = 0x00002000,  /* addr.to is set */
index 68696441da7035d8d410af9220c18b60c709bc4e..275122fcbd297c97dc2c8601987140eb4be6024f 100644 (file)
@@ -135,7 +135,7 @@ struct listener {
        } conf;                         /* config information */
 };
 
-struct stream_interface;
+struct connection;
 
 /* This structure contains all information needed to easily handle a protocol.
  * Its primary goal is to ease listeners maintenance. Specifically, the
@@ -157,7 +157,7 @@ struct protocol {
        int (*unbind_all)(struct protocol *proto);      /* unbind all bound listeners */
        int (*enable_all)(struct protocol *proto);      /* enable all bound listeners */
        int (*disable_all)(struct protocol *proto);     /* disable all bound listeners */
-       int (*connect)(struct stream_interface *);      /* connect function if any */
+       int (*connect)(struct connection *, int data);  /* connect function if any */
        int (*get_src)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve src addr */
        int (*get_dst)(int fd, struct sockaddr *, socklen_t, int dir); /* syscall used to retrieve dst addr */
 
index 3cb10fe86e286b06e7d81224c8d4a0c6b30095e4..c2ecda82858d34422b7d2601abaad52609343a68 100644 (file)
@@ -1009,11 +1009,18 @@ int connect_server(struct session *s)
        if (s->fe->options2 & PR_O2_SRC_ADDR)
                s->req->cons->flags |= SI_FL_SRC_ADDR;
 
+       /* disable lingering */
+       if (s->be->options & PR_O_TCP_NOLING)
+               s->req->cons->flags |= SI_FL_NOLINGER;
+
        err = si_connect(s->req->cons);
 
        if (err != SN_ERR_NONE)
                return err;
 
+       /* set connect timeout */
+       s->req->cons->exp = tick_add_ifset(now_ms, s->be->timeout.connect);
+
        srv = target_srv(&s->target);
        if (srv) {
                s->flags |= SN_CURR_SESS;
index 7998f400fd70eecd801e95038e2af219cac499da..b61d87e6c09a9513975deff6d22c4efa810711aa 100644 (file)
@@ -49,7 +49,6 @@
 #include <proto/sample.h>
 #include <proto/session.h>
 #include <proto/stick_table.h>
-#include <proto/stream_interface.h>
 #include <proto/task.h>
 
 #ifdef CONFIG_HAP_CTTPROXY
@@ -210,12 +209,15 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
 
 
 /*
- * This function initiates a connection to the target assigned to this session
- * (si->{target,addr.to}). A source address may be pointed to by si->addr.from
- * in case of transparent proxying. Normal source bind addresses are still
- * determined locally (due to the possible need of a source port).
- * si->target may point either to a valid server or to a backend, depending
- * on si->target.type. Only TARG_TYPE_PROXY and TARG_TYPE_SERVER are supported.
+ * This function initiates a TCP connection establishment to the target assigned
+ * to connection <conn> using (si->{target,addr.to}). A source address may be
+ * pointed to by conn->addr.from in case of transparent proxying. Normal source
+ * bind addresses are still determined locally (due to the possible need of a
+ * source port). conn->target may point either to a valid server or to a backend,
+ * depending on conn->target.type. Only TARG_TYPE_PROXY and TARG_TYPE_SERVER are
+ * supported. The <data> parameter is a boolean indicating whether there are data
+ * waiting for being sent or not, in order to adjust data write polling and on
+ * some platforms, the ability to avoid an empty initial ACK.
  *
  * It can return one of :
  *  - SN_ERR_NONE if everything's OK
@@ -227,12 +229,11 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
  * Additionnally, in the case of SN_ERR_RESOURCE, an emergency log will be emitted.
  */
 
-int tcp_connect_server(struct stream_interface *si)
+int tcp_connect_server(struct connection *conn, int data)
 {
        int fd;
        struct server *srv;
        struct proxy *be;
-       struct connection *conn = &si->conn;
 
        switch (conn->target.type) {
        case TARG_TYPE_PROXY:
@@ -285,9 +286,6 @@ int tcp_connect_server(struct stream_interface *si)
        if (be->options & PR_O_TCP_SRV_KA)
                setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &one, sizeof(one));
 
-       if (be->options & PR_O_TCP_NOLING)
-               si->flags |= SI_FL_NOLINGER;
-
        /* allow specific binding :
         * - server-specific at first
         * - proxy-specific next
@@ -409,7 +407,7 @@ int tcp_connect_server(struct stream_interface *si)
         * machine with the first ACK. We only do this if there are pending
         * data in the buffer.
         */
-       if ((be->options2 & PR_O2_SMARTCON) && si->ob->buf.o)
+       if ((be->options2 & PR_O2_SMARTCON) && data)
                 setsockopt(fd, IPPROTO_TCP, TCP_QUICKACK, &zero, sizeof(zero));
 #endif
 
@@ -453,28 +451,16 @@ int tcp_connect_server(struct stream_interface *si)
                }
        }
 
-       /* needs src ip/port for logging */
-       if (si->flags & SI_FL_SRC_ADDR)
-               conn_get_from_addr(conn);
-
        fdtab[fd].owner = conn;
        fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
        conn->flags  = CO_FL_WAIT_L4_CONN; /* connection in progress */
-       conn->flags |= CO_FL_NOTIFY_SI; /* we're on a stream_interface */
-
-       /* Prepare to send a few handshakes related to the on-wire protocol. */
-       if (si->send_proxy_ofs)
-               conn->flags |= CO_FL_SI_SEND_PROXY;
 
        fdtab[fd].iocb = conn_fd_handler;
        fd_insert(fd);
        conn_sock_want_send(conn);  /* for connect status */
-       if (!channel_is_empty(si->ob))
+       if (data)
                conn_data_want_send(conn);  /* prepare to send data if any */
 
-       si->state = SI_ST_CON;
-       si->exp = tick_add_ifset(now_ms, be->timeout.connect);
-
        return SN_ERR_NONE;  /* connection is OK */
 }