]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: mux: implement a get_first_cs() method
authorWilly Tarreau <w@1wt.eu>
Sun, 18 Nov 2018 20:29:20 +0000 (21:29 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 18 Nov 2018 20:29:20 +0000 (21:29 +0100)
This method is used to retrieve the first known good conn_stream from
the mux. It will be used to find the other end of a connection when
dealing with the proxy protocol for example.

include/proto/connection.h
include/types/connection.h
src/mux_h2.c
src/mux_pt.c

index 1aa0ed909433c16238ab43c892d7af8307fecf41..0b4a0d84520603725aa2e421b0b7511337857f47 100644 (file)
@@ -632,6 +632,22 @@ static inline struct conn_stream *cs_new(struct connection *conn)
        return cs;
 }
 
+/* Retrieves any valid conn_stream from this connection, preferably the first
+ * valid one. The purpose is to be able to figure one other end of a private
+ * connection for purposes like source binding or proxy protocol header
+ * emission. In such cases, any conn_stream is expected to be valid so the
+ * mux is encouraged to return the first one it finds. If the connection has
+ * no mux or the mux has no get_first_cs() method or the mux has no valid
+ * conn_stream, NULL is returned. The output pointer is purposely marked
+ * const to discourage the caller from modifying anything there.
+ */
+static inline const struct conn_stream *cs_get_first(const struct connection *conn)
+{
+       if (!conn || !conn->mux || !conn->mux->get_first_cs)
+               return NULL;
+       return conn->mux->get_first_cs(conn);
+}
+
 static inline void conn_force_unsubscribe(struct connection *conn)
 {
        if (conn->recv_wait) {
index 889decb6c6de2a9c1dfe9f17ecf322bf94ba8d3c..ebc60e46054bbccec5bef0ec4dec670aadcb9acf 100644 (file)
@@ -321,6 +321,7 @@ struct mux_ops {
        void (*shutw)(struct conn_stream *cs, enum cs_shw_mode);     /* shutw function */
 
        struct conn_stream *(*attach)(struct connection *); /* Create and attach a conn_stream to an outgoing connection */
+       const struct conn_stream *(*get_first_cs)(const struct connection *); /* retrieves any valid conn_stream from this connection */
        void (*detach)(struct conn_stream *); /* Detach a conn_stream from an outgoing connection, when the request is done */
        void (*show_fd)(struct buffer *, struct connection *); /* append some data about connection into chunk for "show fd" */
        int (*subscribe)(struct conn_stream *cs, int event_type, void *param); /* Subscribe to events, such as "being able to send" */
index de635127e98b113dd1beecc2e606079426fb10a4..a643759f915414c6577a06e4633559ba9231b6ac 100644 (file)
@@ -2539,6 +2539,27 @@ static struct conn_stream *h2_attach(struct connection *conn)
        return NULL;
 }
 
+/* Retrieves the first valid conn_stream from this connection, or returns NULL.
+ * We have to scan because we may have some orphan streams. It might be
+ * beneficial to scan backwards from the end to reduce the likeliness to find
+ * orphans.
+ */
+static const struct conn_stream *h2_get_first_cs(const struct connection *conn)
+{
+       struct h2c *h2c = conn->mux_ctx;
+       struct h2s *h2s;
+       struct eb32_node *node;
+
+       node = eb32_first(&h2c->streams_by_id);
+       while (node) {
+               h2s = container_of(node, struct h2s, by_id);
+               if (h2s->cs)
+                       return h2s->cs;
+               node = eb32_next(node);
+       }
+       return NULL;
+}
+
 /*
  * Detach the stream from the connection and possibly release the connection.
  */
@@ -3770,6 +3791,7 @@ const struct mux_ops h2_ops = {
        .subscribe = h2_subscribe,
        .unsubscribe = h2_unsubscribe,
        .attach = h2_attach,
+       .get_first_cs = h2_get_first_cs,
        .detach = h2_detach,
        .shutr = h2_shutr,
        .shutw = h2_shutw,
index 4195ec2505624e32a9a4480ac37a1eaa05170383..dd052c5fda27f683e7d80fd42583290289f8670f 100644 (file)
@@ -72,6 +72,16 @@ static struct conn_stream *mux_pt_attach(struct connection *conn)
        return NULL;
 }
 
+/* Retrieves a valid conn_stream from this connection, or returns NULL. For
+ * this mux, it's easy as we can only store a single conn_stream.
+ */
+static const struct conn_stream *mux_pt_get_first_cs(const struct connection *conn)
+{
+       struct conn_stream *cs = conn->mux_ctx;
+
+       return cs;
+}
+
 /*
  * Detach the stream from the connection and possibly release the connection.
  */
@@ -183,6 +193,7 @@ const struct mux_ops mux_pt_ops = {
        .snd_pipe = mux_pt_snd_pipe,
 #endif
        .attach = mux_pt_attach,
+       .get_first_cs = mux_pt_get_first_cs,
        .detach = mux_pt_detach,
        .shutr = mux_pt_shutr,
        .shutw = mux_pt_shutw,