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
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,
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;
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;
.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,