]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connections: Add a new xprt method, remove_xprt.
authorOlivier Houchard <ohouchard@haproxy.com>
Thu, 23 May 2019 15:47:36 +0000 (17:47 +0200)
committerOlivier Houchard <cognet@ci0.org>
Wed, 5 Jun 2019 16:03:38 +0000 (18:03 +0200)
Add a new method to xprt_ops, remove_xprt. When called, if the provided
xprt_ctx is the same as the xprt's underlying xprt_ctx, it then uses the
new xprt provided, otherwise it calls the remove_xprt method of the next
xprt.
The goal is to be able to add a temporary xprt, that removes itself from
the chain when it did what it had to do. This will be used to implement
a pseudo-xprt for anything that just requires a handshake (such as the
proxy protocol).

include/types/connection.h
src/raw_sock.c
src/ssl_sock.c

index e6b3ed57524b4e9a44e6656585dfa0f2a05e6d13..e5139948559b7765b31449a5fb041ecc8bc0cb9d 100644 (file)
@@ -333,6 +333,7 @@ struct xprt_ops {
        char name[8];                               /* transport layer name, zero-terminated */
        int (*subscribe)(struct connection *conn, void *xprt_ctx, int event_type, void *param); /* Subscribe to events, such as "being able to send" */
        int (*unsubscribe)(struct connection *conn, void *xprt_ctx, int event_type, void *param); /* Unsubscribe to events */
+       int (*remove_xprt)(struct connection *conn, void *xprt_ctx, void *toremove_ctx, const struct xprt_ops *newops, void *newctx); /* Remove an xprt from the connection, used by temporary xprt such as the handshake one */
 };
 
 /* mux_ops describes the mux operations, which are to be performed at the
index a83cc3fcb536e0b093bb01c979e77419cb64d458..ad9f79257b3100e43d77ebb90a6e1bb7fc30c1c3 100644 (file)
@@ -415,12 +415,23 @@ static int raw_sock_unsubscribe(struct connection *conn, void *xprt_ctx, int eve
        return conn_unsubscribe(conn, xprt_ctx, event_type, param);
 }
 
+/* We can't have an underlying XPRT, so just return -1 to signify failure */
+static int raw_sock_remove_xprt(struct connection *conn, void *xprt_ctx, void *toremove_ctx, const struct xprt_ops *newops, void *newctx)
+{
+       /* This is the lowest xprt we can have, so if we get there we didn't
+        * find the xprt we wanted to remove, that's a bug
+        */
+       BUG_ON(1);
+       return -1;
+}
+
 /* transport-layer operations for RAW sockets */
 static struct xprt_ops raw_sock = {
        .snd_buf  = raw_sock_from_buf,
        .rcv_buf  = raw_sock_to_buf,
        .subscribe = raw_sock_subscribe,
        .unsubscribe = raw_sock_unsubscribe,
+       .remove_xprt = raw_sock_remove_xprt,
 #if defined(USE_LINUX_SPLICE)
        .rcv_pipe = raw_sock_to_pipe,
        .snd_pipe = raw_sock_from_pipe,
index 201f04c206bccec5f9b52240a033b5c3dd7ceb2c..1d018aa02089840450a9a6abaf797729c157f976 100644 (file)
@@ -211,7 +211,7 @@ struct ssl_sock_ctx {
        struct connection *conn;
        SSL *ssl;
        BIO *bio;
-       struct xprt_ops *xprt;
+       const struct xprt_ops *xprt;
        void *xprt_ctx;
        struct wait_event wait_event;
        struct wait_event *recv_wait;
@@ -5630,6 +5630,22 @@ static int ssl_unsubscribe(struct connection *conn, void *xprt_ctx, int event_ty
        return 0;
 }
 
+/* Remove the specified xprt. If if it our underlying XPRT, remove it and
+ * return 0, otherwise just call the remove_xprt method from the underlying
+ * XPRT.
+ */
+static int ssl_remove_xprt(struct connection *conn, void *xprt_ctx, void *toremove_ctx, const struct xprt_ops *newops, void *newctx)
+{
+       struct ssl_sock_ctx *ctx = xprt_ctx;
+
+       if (ctx->xprt_ctx == toremove_ctx) {
+               ctx->xprt_ctx = newctx;
+               ctx->xprt = newops;
+               return 0;
+       }
+       return (ctx->xprt->remove_xprt(conn, ctx->xprt_ctx, toremove_ctx, newops, newctx));
+}
+
 static struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned short state)
 {
        struct ssl_sock_ctx *ctx = context;
@@ -9825,6 +9841,7 @@ static struct xprt_ops ssl_sock = {
        .rcv_buf  = ssl_sock_to_buf,
        .subscribe = ssl_subscribe,
        .unsubscribe = ssl_unsubscribe,
+       .remove_xprt = ssl_remove_xprt,
        .rcv_pipe = NULL,
        .snd_pipe = NULL,
        .shutr    = NULL,