Skip to content

Commit

Permalink
shutdown/free stuff
Browse files Browse the repository at this point in the history
does allow reconnecting now, with caveats.
  • Loading branch information
dormando committed May 22, 2024
1 parent ce19ba1 commit 1c570a6
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 4 deletions.
2 changes: 2 additions & 0 deletions proxy_network.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ static void _cleanup_backend(mcp_backend_t *be) {
// - assert on empty queue
assert(STAILQ_EMPTY(&bec->io_head));

mcp_tls_shutdown(bec);
mcmc_disconnect(bec->client);

if (bec->bad) {
Expand Down Expand Up @@ -912,6 +913,7 @@ static void _reset_bad_backend(struct mcp_backendconn_s *be, enum proxy_be_failu
_stop_write_event(be);
_stop_main_event(be);
_stop_timeout_event(be);
mcp_tls_shutdown(be);
mcmc_disconnect(be->client);
// we leave the main event alone, because be_failed() always overwrites.

Expand Down
49 changes: 45 additions & 4 deletions proxy_tls.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,28 +59,69 @@ int mcp_tls_backend_init(proxy_ctx_t *ctx, struct mcp_backendconn_s *be) {
return MCP_TLS_OK;
}

int mcp_tls_shutdown(struct mcp_backendconn_s *be) {
if (!be->ssl) {
return MCP_TLS_OK;
}

// TODO: This may need to be called multiple times to "properly" shutdown
// a session. However we only ever call this when a backend is dead or not
// in used anymore. Unclear if checking for WANT_READ|WRITE is worth
// doing.
SSL_shutdown(be->ssl);

return MCP_TLS_OK;
}

int mcp_tls_cleanup(struct mcp_backendconn_s *be) {
if (!be->ssl) {
return MCP_TLS_OK;
}

SSL_free(be->ssl);
be->ssl = NULL;
return MCP_TLS_OK;
}

// Contrary to the name of this function, the underlying tcp socket must
// already be connected.
int mcp_tls_connect(struct mcp_backendconn_s *be) {
// TODO: check return code. can fail if BIO fails to alloc.
SSL_set_fd(be->ssl, mcmc_fd(be->client));

// TODO:
// if the backend is changing TLS version or some similar issue, we will
// be unable to reconnect as the SSL object "Caches" some information
// about the previous request (why doesn't clear work then???)
// This will normally be fine, but we should detect severe errors here and
// decide if we should free and re-alloc the SSL object.
// Allocating the SSL object can be pretty slow, so we should at least
// attempt to do not do this.
// Related: https://github.com/openssl/openssl/issues/20286
SSL_clear(be->ssl);
ERR_clear_error();
int n = SSL_connect(be->ssl);
int ret = MCP_TLS_OK;
// TODO: complete error handling.
if (n == 1) {
// Successfully established and handshake complete.
} else if (n == 0) {
return ret;
}

int err = SSL_get_error(be->ssl, n);
if (n == 0) {
// Not successsful, but shut down normally.
ERR_clear_error();
ret = MCP_TLS_ERR;
} else if (n < 0) {
// Not successful. Check for temporary error.

// clear all errors in case of other junk.
if (err == SSL_ERROR_WANT_READ ||
err == SSL_ERROR_WANT_WRITE) {
ret = MCP_TLS_OK;
} else {
ret = MCP_TLS_ERR;
}
ERR_clear_error();
ret = MCP_TLS_ERR;
}

return ret;
Expand Down
4 changes: 4 additions & 0 deletions proxy_tls.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ enum mcp_tls_ret {
#ifdef PROXY_TLS
int mcp_tls_init(proxy_ctx_t *ctx);
int mcp_tls_backend_init(proxy_ctx_t *ctx, struct mcp_backendconn_s *be);
int mcp_tls_shutdown(struct mcp_backendconn_s *be);
int mcp_tls_cleanup(struct mcp_backendconn_s *be);
int mcp_tls_connect(struct mcp_backendconn_s *be);
int mcp_tls_handshake(struct mcp_backendconn_s *be);
int mcp_tls_send_validate(struct mcp_backendconn_s *be);
Expand All @@ -25,6 +27,8 @@ int mcp_tls_writev(struct mcp_backendconn_s *be, int iovcnt);
#else
#define mcp_tls_init(ctx)
#define mcp_tls_backend_init(ctx, be)
#define mcp_tls_shutdown(be);
#define mcp_tls_cleanup(be);
#define mcp_tls_connect(be)
#define mcp_tls_handshake(be) 0
#define mcp_tls_send_validate(be) 0
Expand Down

0 comments on commit 1c570a6

Please sign in to comment.