Skip to content

Commit

Permalink
proxy: backend TLS support
Browse files Browse the repository at this point in the history
WIP. Connects, handshakes, and routes requests as of this commit. Needs
further work before mergeable.
  • Loading branch information
dormando committed May 24, 2024
1 parent 788f592 commit d5d81a5
Show file tree
Hide file tree
Showing 8 changed files with 640 additions and 15 deletions.
1 change: 1 addition & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ memcached_SOURCES += proto_proxy.c proto_proxy.h vendor/mcmc/mcmc.h \
proxy_luafgen.c \
proxy_config.c proxy_ring_hash.c \
proxy_internal.c \
proxy_tls.c proxy_tls.h \
md5.c md5.h
endif

Expand Down
12 changes: 12 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ AC_ARG_ENABLE(proxy,
AC_ARG_ENABLE(proxy-uring,
[AS_HELP_STRING([--enable-proxy-uring], [Enable proxy io_uring code EXPERIMENTAL])])

AC_ARG_ENABLE(proxy-tls,
[AS_HELP_STRING([--enable-proxy-tls], [Enable proxy io_uring code EXPERIMENTAL])])

AC_ARG_ENABLE(werror,
[AS_HELP_STRING([--enable-werror], [Enable -Werror])])

Expand Down Expand Up @@ -255,6 +258,14 @@ if test "x$enable_proxy_uring" = "xyes"; then
CPPFLAGS="-Ivendor/liburing/src/include $CPPFLAGS"
fi

if test "x$enable_proxy_tls" = "xyes"; then
if test "x$enable_tls" != "xyes"; then
AC_MSG_ERROR([--enable-proxy-tls requires --enable-tls])
else
AC_DEFINE([PROXY_TLS],1,[Set to nonzero if you want to enable proxy backend tls support])
fi
fi

if test "x$enable_large_client_flags" = "xyes"; then
AC_DEFINE([LARGE_CLIENT_FLAGS],1,[Set to nonzero if you want 64bit client flags])
fi
Expand All @@ -270,6 +281,7 @@ AM_CONDITIONAL([ENABLE_STATIC],[test "$enable_static" = "yes"])
AM_CONDITIONAL([DISABLE_UNIX_SOCKET],[test "$enable_unix_socket" = "no"])
AM_CONDITIONAL([ENABLE_PROXY],[test "$enable_proxy" = "yes"])
AM_CONDITIONAL([ENABLE_PROXY_URING],[test "$enable_proxy_uring" = "yes"])
AM_CONDITIONAL([ENABLE_PROXY_TLS],[test "$enable_proxy_tls" = "yes"])
AM_CONDITIONAL([LARGE_CLIENT_FLAGS],[test "$enable_large_client_flags" = "yes"])


Expand Down
1 change: 1 addition & 0 deletions proto_proxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,7 @@ void *proxy_init(bool use_uring, bool proxy_memprofile) {
ctx->tunables.backend_depth_limit = 0;
ctx->tunables.max_ustats = MAX_USTATS_DEFAULT;
ctx->tunables.use_iothread = false;
ctx->tunables.use_tls = false;

STAILQ_INIT(&ctx->manager_head);
lua_State *L = NULL;
Expand Down
14 changes: 14 additions & 0 deletions proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ struct proxy_tunables {
int max_ustats; // limit the ustats index.
bool tcp_keepalive;
bool use_iothread; // default for using the bg io thread.
bool use_tls; // whether or not be should use TLS
bool down; // backend is forced into a down/bad state.
};

Expand All @@ -228,6 +229,9 @@ typedef struct {
proxy_event_thread_t *proxy_io_thread;
uint64_t active_req_limit; // max total in-flight requests
uint64_t buffer_memory_limit; // max bytes for send/receive buffers.
#ifdef PROXY_TLS
void *tls_ctx;
#endif
pthread_mutex_t config_lock;
pthread_cond_t config_cond;
pthread_t config_tid;
Expand Down Expand Up @@ -389,6 +393,9 @@ struct mcp_backendconn_s {
int flap_count; // number of times we've "flapped" into bad state.
proxy_event_thread_t *event_thread; // event thread owning this backend.
void *client; // mcmc client
#ifdef PROXY_TLS
void *ssl;
#endif
io_head_t io_head; // stack of requests.
io_pending_proxy_t *io_next; // next request to write.
char *rbuf; // statically allocated read buffer.
Expand All @@ -404,6 +411,9 @@ struct mcp_backendconn_s {
bool validating; // in process of validating a new backend connection.
bool can_write; // recently got a WANT_WRITE or are connecting.
bool bad; // timed out, marked as bad.
#ifndef PROXY_TLS
bool ssl;
#endif
struct iovec write_iovs[BE_IOV_MAX]; // iovs to stage batched writes
};

Expand Down Expand Up @@ -439,6 +449,10 @@ struct proxy_event_thread_s {
eventfd_t event_counter;
eventfd_t beevent_counter;
bool use_uring;
#endif
#ifdef PROXY_TLS
char *tls_wbuf;
size_t tls_wbuf_size;
#endif
pthread_mutex_t mutex; // covers stack.
pthread_cond_t cond; // condition to wait on while stack drains.
Expand Down
46 changes: 46 additions & 0 deletions proxy_lua.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */

#include "proxy.h"
#include "proxy_tls.h"
#include "storage.h" // for stats call

// func prototype example:
Expand Down Expand Up @@ -452,6 +453,11 @@ static int mcplib_backend(lua_State *L) {
}
lua_pop(L, 1);

if (lua_getfield(L, 1, "tls") != LUA_TNIL) {
be->tunables.use_tls = lua_toboolean(L, -1);
}
lua_pop(L, 1);

if (lua_getfield(L, 1, "failurelimit") != LUA_TNIL) {
int limit = luaL_checkinteger(L, -1);
if (limit < 0) {
Expand Down Expand Up @@ -683,6 +689,16 @@ static mcp_backend_wrap_t *_mcplib_make_backendconn(lua_State *L, mcp_backend_la
STAT_UL(ctx);
bec->connect_flags = flags;

// FIXME: remove ifdef via an initialized checker? or
// mcp_tls_backend_init response code?
#ifdef PROXY_TLS
if (be->tunables.use_tls) {
proxy_lua_error(L, "TLS requested but not initialized: call mcp.init_tls()");
return NULL;
}
#endif
mcp_tls_backend_init(ctx, bec);

bec->event_thread = e;
}
pthread_mutex_lock(&e->mutex);
Expand Down Expand Up @@ -1119,6 +1135,34 @@ static int mcplib_backend_use_iothread(lua_State *L) {
return 0;
}

static int mcplib_backend_use_tls(lua_State *L) {
luaL_checktype(L, -1, LUA_TBOOLEAN);
int state = lua_toboolean(L, -1);
proxy_ctx_t *ctx = PROXY_GET_CTX(L);
#ifndef PROXY_TLS
if (state == 1) {
proxy_lua_error(L, "cannot set mcp.backend_use_tls: TLS support not compiled");
}
#endif
STAT_L(ctx);
ctx->tunables.use_tls = state;
STAT_UL(ctx);

return 0;
}

// TODO: error checking.
static int mcplib_init_tls(lua_State *L) {
#ifndef PROXY_TLS
proxy_lua_error(L, "cannot run mcp.init_tls: TLS support not compiled");
#else
proxy_ctx_t *ctx = PROXY_GET_CTX(L);
mcp_tls_init(ctx);
#endif

return 0;
}

static int mcplib_tcp_keepalive(lua_State *L) {
luaL_checktype(L, -1, LUA_TBOOLEAN);
int state = lua_toboolean(L, -1);
Expand Down Expand Up @@ -1765,6 +1809,8 @@ int proxy_register_libs(void *ctx, LIBEVENT_THREAD *t, void *state) {
{"backend_flap_backoff_ramp", mcplib_backend_flap_backoff_ramp},
{"backend_flap_backoff_max", mcplib_backend_flap_backoff_max},
{"backend_use_iothread", mcplib_backend_use_iothread},
{"backend_use_tls", mcplib_backend_use_tls},
{"init_tls", mcplib_init_tls},
{"tcp_keepalive", mcplib_tcp_keepalive},
{"active_req_limit", mcplib_active_req_limit},
{"buffer_memory_limit", mcplib_buffer_memory_limit},
Expand Down
Loading

0 comments on commit d5d81a5

Please sign in to comment.