Do not re-initialize TLS context every connection
This commit is contained in:
@@ -22,12 +22,12 @@ etcd_state_client_t::~etcd_state_client_t()
|
|||||||
stop_ws_keepalive();
|
stop_ws_keepalive();
|
||||||
if (etcd_watch_ws)
|
if (etcd_watch_ws)
|
||||||
{
|
{
|
||||||
http_close(etcd_watch_ws);
|
http_destroy(etcd_watch_ws);
|
||||||
etcd_watch_ws = NULL;
|
etcd_watch_ws = NULL;
|
||||||
}
|
}
|
||||||
if (keepalive_client)
|
if (keepalive_client)
|
||||||
{
|
{
|
||||||
http_close(keepalive_client);
|
http_destroy(keepalive_client);
|
||||||
keepalive_client = NULL;
|
keepalive_client = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -98,7 +98,7 @@ void etcd_state_client_t::etcd_call_oneshot(std::string etcd_address, std::strin
|
|||||||
json11::Json data;
|
json11::Json data;
|
||||||
response->parse_json_response(err, data);
|
response->parse_json_response(err, data);
|
||||||
callback(err, data);
|
callback(err, data);
|
||||||
http_close(http_cli);
|
http_destroy(http_cli);
|
||||||
};
|
};
|
||||||
http_request(http_cli, etcd_address, req, { .timeout = timeout, .ssl = ssl, .ssl_ca = etcd_ca }, cb);
|
http_request(http_cli, etcd_address, req, { .timeout = timeout, .ssl = ssl, .ssl_ca = etcd_ca }, cb);
|
||||||
}
|
}
|
||||||
@@ -348,17 +348,16 @@ void etcd_state_client_t::start_etcd_watcher()
|
|||||||
}
|
}
|
||||||
etcd_watches_initialised = 0;
|
etcd_watches_initialised = 0;
|
||||||
ws_alive = 1;
|
ws_alive = 1;
|
||||||
if (etcd_watch_ws)
|
|
||||||
{
|
|
||||||
http_close(etcd_watch_ws);
|
|
||||||
etcd_watch_ws = NULL;
|
|
||||||
}
|
|
||||||
if (this->log_level > 1)
|
if (this->log_level > 1)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Trying to connect to etcd websocket at %s, watch from revision %ju/%ju/%ju\n", etcd_address.c_str(),
|
fprintf(stderr, "Trying to connect to etcd websocket at %s, watch from revision %ju/%ju/%ju\n", etcd_address.c_str(),
|
||||||
etcd_watch_revision_config, etcd_watch_revision_osd, etcd_watch_revision_pg);
|
etcd_watch_revision_config, etcd_watch_revision_osd, etcd_watch_revision_pg);
|
||||||
}
|
}
|
||||||
etcd_watch_ws = open_websocket(tfd, etcd_address, etcd_api_path+"/watch", { .timeout = etcd_slow_timeout, .ssl = ssl, .ssl_ca = etcd_ca },
|
if (!etcd_watch_ws)
|
||||||
|
etcd_watch_ws = http_init(tfd);
|
||||||
|
else
|
||||||
|
http_close(etcd_watch_ws);
|
||||||
|
open_websocket(etcd_watch_ws, etcd_address, etcd_api_path+"/watch", { .timeout = etcd_slow_timeout, .ssl = ssl, .ssl_ca = etcd_ca },
|
||||||
[this, cur_addr = selected_etcd_address](const http_response_t *msg)
|
[this, cur_addr = selected_etcd_address](const http_response_t *msg)
|
||||||
{
|
{
|
||||||
if (msg->body.length())
|
if (msg->body.length())
|
||||||
@@ -402,7 +401,6 @@ void etcd_state_client_t::start_etcd_watcher()
|
|||||||
fprintf(stderr, "Revisions before %ju were compacted by etcd, reloading state\n",
|
fprintf(stderr, "Revisions before %ju were compacted by etcd, reloading state\n",
|
||||||
data["result"]["compact_revision"].uint64_value());
|
data["result"]["compact_revision"].uint64_value());
|
||||||
http_close(etcd_watch_ws);
|
http_close(etcd_watch_ws);
|
||||||
etcd_watch_ws = NULL;
|
|
||||||
etcd_watch_revision_config = etcd_watch_revision_osd = etcd_watch_revision_pg = 0;
|
etcd_watch_revision_config = etcd_watch_revision_osd = etcd_watch_revision_pg = 0;
|
||||||
on_reload_hook();
|
on_reload_hook();
|
||||||
}
|
}
|
||||||
@@ -479,11 +477,6 @@ void etcd_state_client_t::start_etcd_watcher()
|
|||||||
fprintf(stderr, "Disconnected from etcd %s\n", cur_addr.c_str());
|
fprintf(stderr, "Disconnected from etcd %s\n", cur_addr.c_str());
|
||||||
if (cur_addr == selected_etcd_address)
|
if (cur_addr == selected_etcd_address)
|
||||||
selected_etcd_address = "";
|
selected_etcd_address = "";
|
||||||
if (etcd_watch_ws)
|
|
||||||
{
|
|
||||||
http_close(etcd_watch_ws);
|
|
||||||
etcd_watch_ws = NULL;
|
|
||||||
}
|
|
||||||
if (etcd_watches_initialised == 0)
|
if (etcd_watches_initialised == 0)
|
||||||
{
|
{
|
||||||
// Connection not established, retry in <etcd_quick_timeout>
|
// Connection not established, retry in <etcd_quick_timeout>
|
||||||
@@ -560,11 +553,6 @@ void etcd_state_client_t::start_ws_keepalive()
|
|||||||
{
|
{
|
||||||
fprintf(stderr, "Websocket ping failed, disconnecting from etcd %s\n", selected_etcd_address.c_str());
|
fprintf(stderr, "Websocket ping failed, disconnecting from etcd %s\n", selected_etcd_address.c_str());
|
||||||
}
|
}
|
||||||
if (etcd_watch_ws)
|
|
||||||
{
|
|
||||||
http_close(etcd_watch_ws);
|
|
||||||
etcd_watch_ws = NULL;
|
|
||||||
}
|
|
||||||
start_etcd_watcher();
|
start_etcd_watcher();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+29
-23
@@ -114,9 +114,13 @@ http_co_t *http_init(timerfd_manager_t *tfd)
|
|||||||
return handler;
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
http_co_t* open_websocket(timerfd_manager_t *tfd, const std::string & host, const std::string & path,
|
void open_websocket(http_co_t *handler, const std::string & host, const std::string & path,
|
||||||
const http_options_t & options, std::function<void(const http_response_t *msg)> response_callback)
|
const http_options_t & options, std::function<void(const http_response_t *msg)> response_callback)
|
||||||
{
|
{
|
||||||
|
if (handler->state == HTTP_CO_KEEPALIVE && (handler->connected_host != host || handler->ssl != options.ssl))
|
||||||
|
handler->close_connection();
|
||||||
|
if (handler->state != HTTP_CO_KEEPALIVE && handler->state != HTTP_CO_CLOSED)
|
||||||
|
throw std::runtime_error("Attempt to open websocket on a keepalive stream");
|
||||||
std::string request = "GET "+path+" HTTP/1.1\r\n"
|
std::string request = "GET "+path+" HTTP/1.1\r\n"
|
||||||
"Host: "+host+"\r\n"
|
"Host: "+host+"\r\n"
|
||||||
"Upgrade: websocket\r\n"
|
"Upgrade: websocket\r\n"
|
||||||
@@ -124,9 +128,6 @@ http_co_t* open_websocket(timerfd_manager_t *tfd, const std::string & host, cons
|
|||||||
"Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"
|
"Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==\r\n"
|
||||||
"Sec-WebSocket-Version: 13\r\n"
|
"Sec-WebSocket-Version: 13\r\n"
|
||||||
"\r\n";
|
"\r\n";
|
||||||
http_co_t *handler = new http_co_t();
|
|
||||||
handler->tfd = tfd;
|
|
||||||
handler->state = HTTP_CO_CLOSED;
|
|
||||||
handler->host = host;
|
handler->host = host;
|
||||||
handler->request_timeout = options.timeout < 0 ? -1 : (options.timeout == 0 ? DEFAULT_TIMEOUT : options.timeout);
|
handler->request_timeout = options.timeout < 0 ? -1 : (options.timeout == 0 ? DEFAULT_TIMEOUT : options.timeout);
|
||||||
handler->want_streaming = false;
|
handler->want_streaming = false;
|
||||||
@@ -135,8 +136,11 @@ http_co_t* open_websocket(timerfd_manager_t *tfd, const std::string & host, cons
|
|||||||
handler->ssl_ca = options.ssl_ca;
|
handler->ssl_ca = options.ssl_ca;
|
||||||
handler->request = request;
|
handler->request = request;
|
||||||
handler->response_callback = response_callback;
|
handler->response_callback = response_callback;
|
||||||
|
handler->ws_outbox = "";
|
||||||
|
handler->response = "";
|
||||||
|
handler->sent = 0;
|
||||||
|
handler->parsed = {};
|
||||||
handler->start_ws_connection();
|
handler->start_ws_connection();
|
||||||
return handler;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_request(http_co_t *handler, const std::string & host, const std::string & request,
|
void http_request(http_co_t *handler, const std::string & host, const std::string & request,
|
||||||
@@ -249,11 +253,16 @@ void http_co_t::post_message(uint8_t type, const std::string & msg)
|
|||||||
stackout();
|
stackout();
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_close(http_co_t *handler)
|
void http_destroy(http_co_t *handler)
|
||||||
{
|
{
|
||||||
handler->end();
|
handler->end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void http_close(http_co_t *handler)
|
||||||
|
{
|
||||||
|
handler->close_connection();
|
||||||
|
}
|
||||||
|
|
||||||
void http_response_t::parse_json_response(std::string & error, json11::Json & r) const
|
void http_response_t::parse_json_response(std::string & error, json11::Json & r) const
|
||||||
{
|
{
|
||||||
if (this->error != "")
|
if (this->error != "")
|
||||||
@@ -285,20 +294,14 @@ void http_response_t::parse_json_response(std::string & error, json11::Json & r)
|
|||||||
|
|
||||||
http_co_t::~http_co_t()
|
http_co_t::~http_co_t()
|
||||||
{
|
{
|
||||||
|
close_connection();
|
||||||
#ifdef WITH_OPENSSL
|
#ifdef WITH_OPENSSL
|
||||||
ssl_bio = NULL;
|
|
||||||
if (ssl_cli)
|
|
||||||
{
|
|
||||||
SSL_free(ssl_cli);
|
|
||||||
ssl_cli = NULL;
|
|
||||||
}
|
|
||||||
if (ssl_ctx)
|
if (ssl_ctx)
|
||||||
{
|
{
|
||||||
SSL_CTX_free(ssl_ctx);
|
SSL_CTX_free(ssl_ctx);
|
||||||
ssl_ctx = NULL;
|
ssl_ctx = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
close_connection();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_co_t::close_connection()
|
void http_co_t::close_connection()
|
||||||
@@ -319,9 +322,9 @@ void http_co_t::close_connection()
|
|||||||
{
|
{
|
||||||
// Frees client and bios at once
|
// Frees client and bios at once
|
||||||
SSL_free(ssl_cli);
|
SSL_free(ssl_cli);
|
||||||
ssl_bio = NULL;
|
|
||||||
ssl_cli = NULL;
|
ssl_cli = NULL;
|
||||||
}
|
}
|
||||||
|
ssl_bio = NULL;
|
||||||
#endif
|
#endif
|
||||||
state = HTTP_CO_CLOSED;
|
state = HTTP_CO_CLOSED;
|
||||||
connected_host = "";
|
connected_host = "";
|
||||||
@@ -377,16 +380,19 @@ void http_co_t::start_connection()
|
|||||||
// https://wiki.openssl.org/index.php/Hostname_validation
|
// https://wiki.openssl.org/index.php/Hostname_validation
|
||||||
if (ssl)
|
if (ssl)
|
||||||
{
|
{
|
||||||
ssl_ctx = SSL_CTX_new(TLS_method());
|
|
||||||
if (!ssl_ctx)
|
if (!ssl_ctx)
|
||||||
goto init_err;
|
{
|
||||||
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
|
ssl_ctx = SSL_CTX_new(TLS_method());
|
||||||
if (!SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_2_VERSION))
|
if (!ssl_ctx)
|
||||||
goto init_err;
|
goto init_err;
|
||||||
if ((ssl_ca != "")
|
SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL);
|
||||||
? !SSL_CTX_load_verify_locations(ssl_ctx, ssl_ca.c_str(), NULL)
|
if (!SSL_CTX_set_min_proto_version(ssl_ctx, TLS1_2_VERSION))
|
||||||
: !SSL_CTX_set_default_verify_paths(ssl_ctx))
|
goto init_err;
|
||||||
goto init_err;
|
if ((ssl_ca != "")
|
||||||
|
? !SSL_CTX_load_verify_locations(ssl_ctx, ssl_ca.c_str(), NULL)
|
||||||
|
: !SSL_CTX_set_default_verify_paths(ssl_ctx))
|
||||||
|
goto init_err;
|
||||||
|
}
|
||||||
ssl_bio = BIO_new(BIO_s_socket());
|
ssl_bio = BIO_new(BIO_s_socket());
|
||||||
if (!ssl_bio)
|
if (!ssl_bio)
|
||||||
goto init_err;
|
goto init_err;
|
||||||
|
|||||||
@@ -44,9 +44,10 @@ struct http_response_t
|
|||||||
struct http_co_t;
|
struct http_co_t;
|
||||||
|
|
||||||
http_co_t* http_init(timerfd_manager_t *tfd);
|
http_co_t* http_init(timerfd_manager_t *tfd);
|
||||||
http_co_t* open_websocket(timerfd_manager_t *tfd, const std::string & host, const std::string & path,
|
void open_websocket(http_co_t *handler, const std::string & host, const std::string & path,
|
||||||
const http_options_t & options, std::function<void(const http_response_t *msg)> on_message);
|
const http_options_t & options, std::function<void(const http_response_t *msg)> on_message);
|
||||||
void http_request(http_co_t *handler, const std::string & host, const std::string & request,
|
void http_request(http_co_t *handler, const std::string & host, const std::string & request,
|
||||||
const http_options_t & options, std::function<void(const http_response_t *response)> response_callback);
|
const http_options_t & options, std::function<void(const http_response_t *response)> response_callback);
|
||||||
void http_post_message(http_co_t *handler, uint8_t type, const std::string & msg);
|
void http_post_message(http_co_t *handler, uint8_t type, const std::string & msg);
|
||||||
void http_close(http_co_t *co);
|
void http_close(http_co_t *co);
|
||||||
|
void http_destroy(http_co_t *co);
|
||||||
|
|||||||
Reference in New Issue
Block a user