]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: conn_stream: add cs_recv() as a default rcv_buf() function
authorWilly Tarreau <w@1wt.eu>
Fri, 2 Mar 2018 12:55:01 +0000 (13:55 +0100)
committerWilly Tarreau <w@1wt.eu>
Fri, 20 Jul 2018 17:21:43 +0000 (19:21 +0200)
This function is generic and is able to automatically transfer data
from a conn_stream's rx buffer to the destination buffer. It does this
automatically if the mux doesn't define another rcv_buf() function.

include/proto/connection.h
src/checks.c
src/connection.c
src/stream_interface.c

index ce7ef38119a866c6dda5465afaf511cf97577c0c..dba7fca991825f907a115f8190b7cb56305950a4 100644 (file)
@@ -44,6 +44,9 @@ int init_connection();
  */
 void conn_fd_handler(int fd);
 
+/* conn_stream functions */
+size_t __cs_recv(struct conn_stream *cs, struct buffer *buf, size_t count, int flags);
+
 /* receive a PROXY protocol header over a connection */
 int conn_recv_proxy(struct connection *conn, int flag);
 int make_proxy_line(char *buf, int buf_len, struct server *srv, struct connection *remote);
@@ -300,6 +303,17 @@ static inline void cs_update_mux_polling(struct conn_stream *cs)
                conn->mux->update_poll(cs);
 }
 
+/* conn_stream receive function. Uses mux->rcv_buf() if defined, otherwise
+ * falls back to __cs_recv().
+ */
+static inline size_t cs_recv(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
+{
+       if (cs->conn->mux->rcv_buf)
+               return cs->conn->mux->rcv_buf(cs, buf, count, flags);
+       else
+               return __cs_recv(cs, buf, count, flags);
+}
+
 /***** Event manipulation primitives for use by DATA I/O callbacks *****/
 /* The __conn_* versions do not propagate to lower layers and are only meant
  * to be used by handlers called by the connection handler. The other ones
index af6ddd453a1af265e8ba879c9af5fcc09bc2b9c2..b965ee6937142989e645e33c01bdc1c45f0f7d04 100644 (file)
@@ -850,7 +850,7 @@ static void event_srv_chk_r(struct conn_stream *cs)
 
        done = 0;
 
-       conn->mux->rcv_buf(cs, &check->bi, b_size(&check->bi), 0);
+       cs_recv(cs, &check->bi, b_size(&check->bi), 0);
        if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH) || cs->flags & CS_FL_ERROR) {
                done = 1;
                if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !b_data(&check->bi)) {
@@ -2918,7 +2918,7 @@ static int tcpcheck_main(struct check *check)
                                goto out_end_tcpcheck;
 
                        __cs_want_recv(cs);
-                       if (conn->mux->rcv_buf(cs, &check->bi, b_size(&check->bi), 0) <= 0) {
+                       if (cs_recv(cs, &check->bi, b_size(&check->bi), 0) <= 0) {
                                if (conn->flags & (CO_FL_ERROR | CO_FL_SOCK_RD_SH) || cs->flags & CS_FL_ERROR) {
                                        done = 1;
                                        if ((conn->flags & CO_FL_ERROR || cs->flags & CS_FL_ERROR) && !b_data(&check->bi)) {
index e02129093a3331aadae467a7346efdabaf188a34..4b1e066edb2a223978f839152cceea56ff70f0a3 100644 (file)
@@ -383,6 +383,33 @@ int conn_sock_drain(struct connection *conn)
        return 1;
 }
 
+/*
+ * default conn_stream recv() : this one is used when cs->rcv_buf == NULL.
+ * It reads up to <count> bytes from cs->rxbuf, puts them into <buf> and
+ * returns the count. It possibly sets/clears CS_FL_RCV_MORE depending on the
+ * buffer's state, and may set CS_FL_EOS. The number of bytes transferred is
+ * returned. <buf> is not touched if <count> is null, but cs flags will be
+ * updated to indicate any RCV_MORE or EOS.
+ */
+size_t __cs_recv(struct conn_stream *cs, struct buffer *buf, size_t count, int flags)
+{
+       size_t ret = 0;
+
+       /* transfer possibly pending data to the upper layer */
+       ret = b_xfer(buf, &cs->rxbuf, count);
+
+       if (b_data(&cs->rxbuf))
+               cs->flags |= CS_FL_RCV_MORE;
+       else {
+               cs->flags &= ~CS_FL_RCV_MORE;
+               if (cs->flags & CS_FL_REOS)
+                       cs->flags |= CS_FL_EOS;
+               cs_drop_rxbuf(cs);
+       }
+
+       return ret;
+}
+
 /*
  * Get data length from tlv
  */
index f1b52c176b15e4d1178b84db276dbc31c1cf9cc3..a0c73bca2f3222118ca395e782f665cdfd1c8792 100644 (file)
@@ -1236,7 +1236,7 @@ static void si_cs_recv_cb(struct conn_stream *cs)
                        break;
                }
 
-               ret = conn->mux->rcv_buf(cs, &ic->buf, max, co_data(ic) ? CO_RFL_BUF_WET : 0);
+               ret = cs_recv(cs, &ic->buf, max, co_data(ic) ? CO_RFL_BUF_WET : 0);
                if (cs->flags & CS_FL_RCV_MORE)
                        si->flags |= SI_FL_WAIT_ROOM;