MEDIUM: conn_stream: add cs_recv() as a default rcv_buf() function

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.
This commit is contained in:
Willy Tarreau 2018-03-02 13:55:01 +01:00
parent 5e1cc5ea83
commit 11c9aa424e
4 changed files with 44 additions and 3 deletions

View 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

View 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)) {

View 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
*/

View 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;