]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: raw-sock: Specifiy amount of data to send via snd_pipe callback
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 26 Sep 2023 16:05:29 +0000 (18:05 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Tue, 17 Oct 2023 16:51:13 +0000 (18:51 +0200)
When data were sent using the kernel splicing, we tried to send all data
with no restriction. Most of time it is valid. However, because the payload
representation may differ between the producer and the consumer, it is
important to be able to specify how must data to send via the splicing.

Of course, for performance reason, it is important to maximize amount of
data send via splicing at each call. However, on edge-cases, this now can be
limited.

include/haproxy/connection-t.h
src/raw_sock.c

index bd08f1cb02cb8f0df461d2a01cff5e0796655f32..f6edc30dfcb48db06a2ebd09a2c80ba976e44f16 100644 (file)
@@ -388,7 +388,7 @@ struct xprt_ops {
        size_t (*rcv_buf)(struct connection *conn, void *xprt_ctx, struct buffer *buf, size_t count, int flags); /* recv callback */
        size_t (*snd_buf)(struct connection *conn, void *xprt_ctx, const struct buffer *buf, size_t count, int flags); /* send callback */
        int  (*rcv_pipe)(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count); /* recv-to-pipe callback */
-       int  (*snd_pipe)(struct connection *conn, void *xprt_ctx, struct pipe *pipe); /* send-to-pipe callback */
+       int  (*snd_pipe)(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count); /* send-to-pipe callback */
        void (*shutr)(struct connection *conn, void *xprt_ctx, int);    /* shutr function */
        void (*shutw)(struct connection *conn, void *xprt_ctx, int);    /* shutw function */
        void (*close)(struct connection *conn, void *xprt_ctx);         /* close the transport layer */
index 31ca970f18b300b0c3ff980b764da5fbdb08ac32..1287dc5e2ef6194a14d9e43f74e487f067571ba5 100644 (file)
@@ -160,7 +160,7 @@ int raw_sock_to_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe,
 
 /* Send as many bytes as possible from the pipe to the connection's socket.
  */
-int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe)
+int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pipe, unsigned int count)
 {
        int ret, done;
 
@@ -179,9 +179,12 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip
                return 0;
        }
 
+       if (unlikely(count > pipe->data))
+               count = pipe->data;
+
        done = 0;
-       while (pipe->data) {
-               ret = splice(pipe->cons, NULL, conn->handle.fd, NULL, pipe->data,
+       while (count) {
+               ret = splice(pipe->cons, NULL, conn->handle.fd, NULL, count,
                             SPLICE_F_MOVE|SPLICE_F_NONBLOCK);
 
                if (ret <= 0) {
@@ -198,6 +201,7 @@ int raw_sock_from_pipe(struct connection *conn, void *xprt_ctx, struct pipe *pip
                }
 
                done += ret;
+               count -= ret;
                pipe->data -= ret;
        }
        if (unlikely(conn->flags & CO_FL_WAIT_L4_CONN) && done) {