mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-14 07:24:32 +00:00
MINOR: connection: implement alpn registration of muxes
Selecting a mux based on ALPN and the proxy mode will quickly become a pain. This commit provides new functions to register/lookup a mux based on the ALPN string and the proxy mode to make this easier. Given that we're not supposed to support a wide range of muxes, the lookup should not have any measurable performance impact.
This commit is contained in:
parent
53a4766e40
commit
2386be64ba
@ -23,6 +23,7 @@
|
|||||||
#define _PROTO_CONNECTION_H
|
#define _PROTO_CONNECTION_H
|
||||||
|
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/ist.h>
|
||||||
#include <common/memory.h>
|
#include <common/memory.h>
|
||||||
#include <types/connection.h>
|
#include <types/connection.h>
|
||||||
#include <types/listener.h>
|
#include <types/listener.h>
|
||||||
@ -31,6 +32,7 @@
|
|||||||
|
|
||||||
extern struct pool_head *pool2_connection;
|
extern struct pool_head *pool2_connection;
|
||||||
extern struct xprt_ops *registered_xprt[XPRT_ENTRIES];
|
extern struct xprt_ops *registered_xprt[XPRT_ENTRIES];
|
||||||
|
extern struct alpn_mux_list alpn_mux_list;
|
||||||
|
|
||||||
/* perform minimal intializations, report 0 in case of error, 1 if OK. */
|
/* perform minimal intializations, report 0 in case of error, 1 if OK. */
|
||||||
int init_connection();
|
int init_connection();
|
||||||
@ -702,6 +704,72 @@ static inline int conn_get_alpn(const struct connection *conn, const char **str,
|
|||||||
return conn->xprt->get_alpn(conn, str, len);
|
return conn->xprt->get_alpn(conn, str, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* registers alpn mux list <list>. Modifies the list element! */
|
||||||
|
static inline void alpn_register_mux(struct alpn_mux_list *list)
|
||||||
|
{
|
||||||
|
LIST_ADDQ(&alpn_mux_list.list, &list->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* unregisters alpn mux list <list> */
|
||||||
|
static inline void alpn_unregister_mux(struct alpn_mux_list *list)
|
||||||
|
{
|
||||||
|
LIST_DEL(&list->list);
|
||||||
|
LIST_INIT(&list->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns the first mux in the list matching the exact same token and
|
||||||
|
* compatible with the proxy's mode (http or tcp). Mode "health" has to be
|
||||||
|
* considered as TCP here. Ie passing "px->mode == PR_MODE_HTTP" is fine. Will
|
||||||
|
* fall back to the first compatible mux with empty ALPN name. May return null
|
||||||
|
* if the code improperly registered the default mux to use as a fallback.
|
||||||
|
*/
|
||||||
|
static inline const struct mux_ops *alpn_get_mux(const struct ist token, int http_mode)
|
||||||
|
{
|
||||||
|
struct alpn_mux_list *item;
|
||||||
|
const struct mux_ops *fallback = NULL;
|
||||||
|
|
||||||
|
http_mode = 1 << !!http_mode;
|
||||||
|
|
||||||
|
list_for_each_entry(item, &alpn_mux_list.list, list) {
|
||||||
|
if (!(item->mode & http_mode))
|
||||||
|
continue;
|
||||||
|
if (isteq(token, item->token))
|
||||||
|
return item->mux;
|
||||||
|
if (!istlen(item->token))
|
||||||
|
fallback = item->mux;
|
||||||
|
}
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finds the best mux for incoming connection <conn> and mode <http_mode> for
|
||||||
|
* the proxy. Null cannot be returned unless there's a serious bug somewhere
|
||||||
|
* else (no fallback mux registered).
|
||||||
|
*/
|
||||||
|
static inline const struct mux_ops *conn_find_best_mux(struct connection *conn, int http_mode)
|
||||||
|
{
|
||||||
|
const char *alpn_str;
|
||||||
|
int alpn_len;
|
||||||
|
|
||||||
|
if (!conn_get_alpn(conn, &alpn_str, &alpn_len))
|
||||||
|
alpn_len = 0;
|
||||||
|
|
||||||
|
return alpn_get_mux(ist2(alpn_str, alpn_len), http_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* finds the best mux for incoming connection <conn>, a proxy in and http mode
|
||||||
|
* <mode>, and installs it on the connection for direction <dir> (MUX_INBOUND/
|
||||||
|
* MUX_OUTBOUND). Returns < 0 on error.
|
||||||
|
*/
|
||||||
|
static inline int conn_install_best_mux(struct connection *conn, int mode, enum mux_dir dir)
|
||||||
|
{
|
||||||
|
const struct mux_ops *mux_ops;
|
||||||
|
|
||||||
|
mux_ops = conn_find_best_mux(conn, mode);
|
||||||
|
if (!mux_ops)
|
||||||
|
return -1;
|
||||||
|
return conn_install_mux(conn, mux_ops, dir);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _PROTO_CONNECTION_H */
|
#endif /* _PROTO_CONNECTION_H */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
|
||||||
#include <common/config.h>
|
#include <common/config.h>
|
||||||
|
#include <common/ist.h>
|
||||||
|
|
||||||
#include <types/listener.h>
|
#include <types/listener.h>
|
||||||
#include <types/obj_type.h>
|
#include <types/obj_type.h>
|
||||||
@ -331,6 +332,21 @@ struct connection {
|
|||||||
} addr; /* addresses of the remote side, client for producer and server for consumer */
|
} addr; /* addresses of the remote side, client for producer and server for consumer */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* ALPN token registration */
|
||||||
|
enum alpn_proxy_mode {
|
||||||
|
ALPN_MODE_NONE = 0,
|
||||||
|
ALPN_MODE_TCP = 1 << 0, // must not be changed!
|
||||||
|
ALPN_MODE_HTTP = 1 << 1, // must not be changed!
|
||||||
|
ALPN_MODE_ANY = ALPN_MODE_TCP | ALPN_MODE_HTTP,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct alpn_mux_list {
|
||||||
|
const struct ist token; /* token name and length. Empty is catch-all */
|
||||||
|
enum alpn_proxy_mode mode;
|
||||||
|
const struct mux_ops *mux;
|
||||||
|
struct list list;
|
||||||
|
};
|
||||||
|
|
||||||
/* proxy protocol v2 definitions */
|
/* proxy protocol v2 definitions */
|
||||||
#define PP2_SIGNATURE "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
|
#define PP2_SIGNATURE "\x0D\x0A\x0D\x0A\x00\x0D\x0A\x51\x55\x49\x54\x0A"
|
||||||
#define PP2_SIGNATURE_LEN 12
|
#define PP2_SIGNATURE_LEN 12
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
struct pool_head *pool2_connection;
|
struct pool_head *pool2_connection;
|
||||||
struct xprt_ops *registered_xprt[XPRT_ENTRIES] = { NULL, };
|
struct xprt_ops *registered_xprt[XPRT_ENTRIES] = { NULL, };
|
||||||
|
|
||||||
|
/* List head of all known muxes for ALPN */
|
||||||
|
struct alpn_mux_list alpn_mux_list = {
|
||||||
|
.list = LIST_HEAD_INIT(alpn_mux_list.list)
|
||||||
|
};
|
||||||
|
|
||||||
/* perform minimal intializations, report 0 in case of error, 1 if OK. */
|
/* perform minimal intializations, report 0 in case of error, 1 if OK. */
|
||||||
int init_connection()
|
int init_connection()
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user