diff --git a/common/include/tfe_proxy.h b/common/include/tfe_proxy.h index 63b71c3..2f4a7d0 100644 --- a/common/include/tfe_proxy.h +++ b/common/include/tfe_proxy.h @@ -6,6 +6,7 @@ struct tfe_proxy; unsigned int tfe_proxy_get_work_thread_count(); struct event_base * tfe_proxy_get_work_thread_evbase(unsigned int thread_id); struct evdns_base* tfe_proxy_get_work_thread_dnsbase(unsigned int thread_id); +struct evhttp_connection* tfe_proxy_get_work_thread_evhttp(unsigned int thread_id); struct event_base * tfe_proxy_get_gc_evbase(void); screen_stat_handle_t tfe_proxy_get_fs_handle(void); diff --git a/common/include/tfe_rpc.h b/common/include/tfe_rpc.h index 0348ed0..a6116c3 100644 --- a/common/include/tfe_rpc.h +++ b/common/include/tfe_rpc.h @@ -26,5 +26,5 @@ enum TFE_RPC_METHOD struct tfe_rpc_response_result* tfe_rpc_release(void* result); void tfe_rpc_async_ask(struct future* f, const char* url, enum TFE_RPC_METHOD method, enum TFE_RPC_FLAG flag, - const char* data, int data_len, struct event_base * evbase, struct evdns_base* dnsbase); + char* data, int data_len, struct event_base * evbase, struct evdns_base* dnsbase, struct evhttp_connection *evhttp); diff --git a/common/src/tfe_rpc.cpp b/common/src/tfe_rpc.cpp index bd2b673..1e922fd 100644 --- a/common/src/tfe_rpc.cpp +++ b/common/src/tfe_rpc.cpp @@ -42,9 +42,6 @@ int read_header_done_cb(struct evhttp_request* response, void* arg) static void tfe_rpc_promise_free_ctx(void* ctx) { - struct tfe_rpc_ctx* _ctx=(struct tfe_rpc_ctx*)ctx; - evhttp_connection_free(_ctx->connection); - _ctx->connection=NULL; free(ctx); ctx = NULL; return; @@ -182,7 +179,7 @@ char* get_request_url(struct evhttp_uri* uri, size_t url_len) } //data is for POST. if method is GET, data should be NULL -void tfe_rpc_async_ask(struct future* f, const char* url, enum TFE_RPC_METHOD method, enum TFE_RPC_FLAG flag, const char* data, int data_len, struct event_base * evbase, struct evdns_base* dnsbase) +void tfe_rpc_async_ask(struct future* f, const char* url, enum TFE_RPC_METHOD method, enum TFE_RPC_FLAG flag, char* data, int data_len, struct event_base * evbase, struct evdns_base* dnsbase, struct evhttp_connection *evhttp) { const char* host=NULL; int port=0; @@ -211,14 +208,14 @@ void tfe_rpc_async_ask(struct future* f, const char* url, enum TFE_RPC_METHOD me if(port < 0) { port = 80; - } - - ctx->connection = evhttp_connection_base_new(evbase, dnsbase, host, port); + } + ctx->connection = evhttp; if (!ctx->connection) { _wrapped_promise_failed(p, FUTURE_ERROR_EXCEPTION, "create connection failed!"); goto error_out; } + evhttp_connection_set_closecb(ctx->connection, connection_close_cb, evbase); request = evhttp_request_new(get_response_cb, (void*)p); //evhttp_request_set_header_cb(request, read_header_done_cb); @@ -228,6 +225,7 @@ void tfe_rpc_async_ask(struct future* f, const char* url, enum TFE_RPC_METHOD me } evhttp_request_set_error_cb(request, request_error_cb); evhttp_add_header(evhttp_request_get_output_headers(request), "Host", host); + evhttp_add_header(evhttp_request_get_output_headers(request), "Connection", "keep-alive"); url_len = strlen(url); request_url = get_request_url(uri, url_len); //printf("request url is %s\n", request_url); @@ -249,12 +247,14 @@ void tfe_rpc_async_ask(struct future* f, const char* url, enum TFE_RPC_METHOD me _wrapped_promise_failed(p, FUTURE_ERROR_EXCEPTION, "method is invalid!"); goto error_out; } + free(data); free(request_url); evhttp_uri_free(uri); return; error_out: if(uri) evhttp_uri_free(uri); + if(data) free(data); promise_dettach_ctx(p); tfe_rpc_promise_free_ctx(ctx); return; diff --git a/platform/include/internal/key_keeper.h b/platform/include/internal/key_keeper.h index a328a33..f3305ab 100644 --- a/platform/include/internal/key_keeper.h +++ b/platform/include/internal/key_keeper.h @@ -25,9 +25,10 @@ struct keyring* key_keeper_release_keyring(future_result_t* result); void key_keeper_free_keyring(struct keyring* cert); +struct evhttp_connection* key_keeper_evhttp_init(struct event_base * evbase, struct evdns_base* dnsbase, struct key_keeper * key_keeper_handler); void key_keeper_async_ask(struct future * f, struct key_keeper * keeper, const char* sni, int keyring_id, - X509 * origin_cert, int is_cert_valid, struct event_base * evbase, struct evdns_base* dnsbase); + X509 * origin_cert, int is_cert_valid, struct event_base * evbase, struct evdns_base* dnsbase, struct evhttp_connection *evhttp); void key_keeper_statistic(struct key_keeper *keeper, struct key_keeper_stat* result); diff --git a/platform/include/internal/platform.h b/platform/include/internal/platform.h index f7abbbd..eb0a222 100644 --- a/platform/include/internal/platform.h +++ b/platform/include/internal/platform.h @@ -15,8 +15,9 @@ struct tfe_thread_ctx struct event_base * evbase; struct evdns_base* dnsbase; + struct evhttp_connection* evhttp; unsigned char running; - + unsigned int nr_modules; const struct tfe_plugin * modules; }; diff --git a/platform/include/internal/ssl_stream_core.h b/platform/include/internal/ssl_stream_core.h index 399b13a..ae03aa1 100644 --- a/platform/include/internal/ssl_stream_core.h +++ b/platform/include/internal/ssl_stream_core.h @@ -20,7 +20,7 @@ enum ssl_stream_error struct ssl_mgr; struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section, struct event_base * ev_base_gc, - void * logger); + struct key_keeper * key_keeper, void * logger); void ssl_manager_set_new_upstream_cb(struct ssl_mgr * mgr, ssl_stream_new_hook* new_upstream_cb, void* u_para); void ssl_manager_destroy(struct ssl_mgr * mgr); unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir dir, struct ssl_mgr* mgr); diff --git a/platform/src/key_keeper.cpp b/platform/src/key_keeper.cpp index f3e0e43..c353af9 100644 --- a/platform/src/key_keeper.cpp +++ b/platform/src/key_keeper.cpp @@ -455,6 +455,13 @@ void key_keeper_destroy(struct key_keeper *keeper) return; } +struct evhttp_connection* key_keeper_evhttp_init(struct event_base * evbase, struct evdns_base* dnsbase, struct key_keeper * key_keeper_handler) +{ + char *cert_store_host = key_keeper_handler->cert_store_host; + unsigned int cert_store_port =key_keeper_handler->cert_store_port; + return evhttp_connection_base_new(evbase, dnsbase, cert_store_host, cert_store_port); +} + struct key_keeper* key_keeper_init(const char * profile, const char* section, void* logger) { struct key_keeper* keeper = ALLOC(struct key_keeper, 1); @@ -565,7 +572,7 @@ char* url_escape(char* url) return _url; } -void key_keeper_async_ask(struct future * f, struct key_keeper * keeper, const char* sni, int keyring_id, X509 * origin_cert, int is_cert_valid, struct event_base * evbase, struct evdns_base* dnsbase) +void key_keeper_async_ask(struct future * f, struct key_keeper * keeper, const char* sni, int keyring_id, X509 * origin_cert, int is_cert_valid, struct event_base * evbase, struct evdns_base* dnsbase, struct evhttp_connection *evhttp) { struct promise* p = future_to_promise(f); unsigned int len = 0; @@ -602,13 +609,6 @@ void key_keeper_async_ask(struct future * f, struct key_keeper * keeper, const c promise_failed(p, FUTURE_ERROR_EXCEPTION, "transform origin_cert to pem failed"); return; } - char* escaped_origin_cert_pem = url_escape(origin_cert_pem); - free(origin_cert_pem); - if(escaped_origin_cert_pem == NULL) - { - promise_failed(p, FUTURE_ERROR_EXCEPTION, "url escape failed"); - break; - } struct future* f_certstore_rpc = future_create("crt_store", certstore_rpc_on_succ, certstore_rpc_on_fail, p); ctx->f_certstore_rpc = f_certstore_rpc; char *url = NULL; @@ -616,17 +616,16 @@ void key_keeper_async_ask(struct future * f, struct key_keeper * keeper, const c //keyring_id = 1; if(sni == NULL || sni[0] == '\0') { - asprintf(&url, "http://%s:%d/ca?keyring_id=%d&is_valid=%d&origin_cert=%s", - keeper->cert_store_host, keeper->cert_store_port, keyring_id, is_cert_valid, escaped_origin_cert_pem); + asprintf(&url, "http://%s:%d/ca?keyring_id=%d&is_valid=%d", + keeper->cert_store_host, keeper->cert_store_port, keyring_id, is_cert_valid); } else { - asprintf(&url, "http://%s:%d/ca?keyring_id=%d&sni=%s&is_valid=%d&origin_cert=%s", - keeper->cert_store_host, keeper->cert_store_port, keyring_id, sni, is_cert_valid, escaped_origin_cert_pem); + asprintf(&url, "http://%s:%d/ca?keyring_id=%d&sni=%s&is_valid=%d", + keeper->cert_store_host, keeper->cert_store_port, keyring_id, sni, is_cert_valid); } TFE_LOG_DEBUG(keeper->logger, "CertStore query: %.100s", url); - curl_free(escaped_origin_cert_pem); - tfe_rpc_async_ask(f_certstore_rpc, url, GET, DONE_CB, NULL, 0, evbase, dnsbase); + tfe_rpc_async_ask(f_certstore_rpc, url, POST, DONE_CB, origin_cert_pem, strlen(origin_cert_pem), evbase, dnsbase, evhttp); free(url); break; } diff --git a/platform/src/proxy.cpp b/platform/src/proxy.cpp index 74ddd43..90a653b 100644 --- a/platform/src/proxy.cpp +++ b/platform/src/proxy.cpp @@ -44,7 +44,7 @@ #include #include #include - +#include /* Breakpad */ #include #include @@ -243,6 +243,7 @@ void tfe_proxy_work_thread_create_ctx(struct tfe_proxy * proxy) proxy->work_threads[i]->thread_id = i; proxy->work_threads[i]->evbase = event_base_new(); proxy->work_threads[i]->dnsbase = evdns_base_new(proxy->work_threads[i]->evbase, EVDNS_BASE_INITIALIZE_NAMESERVERS); + proxy->work_threads[i]->evhttp = key_keeper_evhttp_init(proxy->work_threads[i]->evbase, proxy->work_threads[i]->dnsbase, proxy->key_keeper_handler); } return; } @@ -657,8 +658,12 @@ int main(int argc, char * argv[]) g_default_proxy->gcev = event_new(g_default_proxy->evbase, -1, EV_PERSIST, __gc_handler_cb, g_default_proxy); CHECK_OR_EXIT(g_default_proxy->gcev, "Failed at creating GC event. Exit. "); + /* KEY_KEEP INIT */ + g_default_proxy->key_keeper_handler = key_keeper_init(main_profile, "key_keeper", g_default_logger); + CHECK_OR_EXIT(g_default_proxy->key_keeper_handler, "Failed at init Key keeper. Exit."); + /* SSL INIT */ - g_default_proxy->ssl_mgr_handler = ssl_manager_init(main_profile, "ssl", g_default_proxy->evbase, g_default_logger); + g_default_proxy->ssl_mgr_handler = ssl_manager_init(main_profile, "ssl", g_default_proxy->evbase, g_default_proxy->key_keeper_handler, g_default_logger); CHECK_OR_EXIT(g_default_proxy->ssl_mgr_handler, "Failed at init SSL manager. Exit."); for (size_t i = 0; i < (sizeof(signals) / sizeof(int)); i++) @@ -719,11 +724,17 @@ struct event_base * tfe_proxy_get_work_thread_evbase(unsigned int thread_id) assert(thread_id < g_default_proxy->nr_work_threads); return g_default_proxy->work_threads[thread_id]->evbase; } + struct evdns_base* tfe_proxy_get_work_thread_dnsbase(unsigned int thread_id) { assert(thread_id < g_default_proxy->nr_work_threads); return g_default_proxy->work_threads[thread_id]->dnsbase; +} +struct evhttp_connection* tfe_proxy_get_work_thread_evhttp(unsigned int thread_id) +{ + assert(thread_id < g_default_proxy->nr_work_threads); + return g_default_proxy->work_threads[thread_id]->evhttp; } struct event_base * tfe_proxy_get_gc_evbase(void) diff --git a/platform/src/ssl_stream.cpp b/platform/src/ssl_stream.cpp index 952ab9f..2f72c69 100644 --- a/platform/src/ssl_stream.cpp +++ b/platform/src/ssl_stream.cpp @@ -609,8 +609,8 @@ void ssl_manager_destroy(struct ssl_mgr * mgr) } -struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section, - struct event_base * ev_base_gc, void * logger) +struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section, + struct event_base * ev_base_gc, struct key_keeper * key_keeper, void * logger) { unsigned int stek_group_num = 0; unsigned int stek_rotation_time = 0; @@ -705,14 +705,8 @@ struct ssl_mgr * ssl_manager_init(const char * ini_profile, const char * section mgr->svc_fail_as_proto_err_cnt, mgr->svc_succ_as_app_not_pinning_cnt, mgr->svc_cnt_time_window); - - mgr->key_keeper = key_keeper_init(ini_profile, "key_keeper", logger); - if (mgr->key_keeper == NULL) - { - TFE_LOG_ERROR(logger, "Certificate Manager initiate failed."); - goto error_out; - } - + + mgr->key_keeper = key_keeper; MESA_load_profile_uint_def(ini_profile, section, "trusted_cert_load_local", &(mgr->trusted_cert_load_local), 1); @@ -1958,6 +1952,7 @@ void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct ctx->tcp_stream = tcp_stream; struct event_base * evbase=tfe_proxy_get_work_thread_evbase(tcp_stream->thread_id); struct evdns_base* dnsbase=tfe_proxy_get_work_thread_dnsbase(tcp_stream->thread_id); + struct evhttp_connection *evhttp=tfe_proxy_get_work_thread_evhttp(tcp_stream->thread_id); if (upstream != NULL) { @@ -1972,7 +1967,7 @@ void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct ctx->f_ask_keyring = future_create("ask_kyr",ask_keyring_on_succ, ask_keyring_on_fail, p); ctx->is_origin_crt_verify_passed = upstream->up_parts.is_server_cert_verify_passed; key_keeper_async_ask(ctx->f_ask_keyring, mgr->key_keeper, sni, upstream->up_parts.keyring_id, ctx->origin_crt, ctx->is_origin_crt_verify_passed, - evbase, dnsbase); + evbase, dnsbase, evhttp); return; } diff --git a/plugin/protocol/http2/src/http2_stream.cpp b/plugin/protocol/http2/src/http2_stream.cpp index cf8593b..6c68c0c 100644 --- a/plugin/protocol/http2/src/http2_stream.cpp +++ b/plugin/protocol/http2/src/http2_stream.cpp @@ -831,6 +831,7 @@ nghttp2_frame_submit_built_req(struct tfe_h2_stream *h2_stream_info, nghttp2_nv hdrs[h2_header->nvlen]; /*Adapt Http uri Settings**/ + nghttp2_session_set_next_stream_id(h2_stream_info->as_client, h2_session->ngh2_stream_id); stream_id = nghttp2_submit_request(h2_stream_info->as_client, NULL, tfe_h2_header_modify_field(h2_header, hdrs, ":path", plugin_built_req->url_storage), h2_header->nvlen, &data_prd, h2_session); @@ -1626,8 +1627,8 @@ nghttp2_server_frame_submit_header(struct tfe_h2_stream *h2_stream_info, } nghttp2_nv hdrs[headers->nvlen]; xret = nghttp2_submit_headers(h2_stream_info->as_server, headers->flag, - h2_session->ngh2_stream_id, NULL, tfe_h2_header_convert_nv(headers, hdrs), - headers->nvlen, h2_session); + h2_session->ngh2_stream_id, NULL, tfe_h2_header_convert_nv(headers, hdrs), + headers->nvlen, h2_session); if (xret < 0){ printf("Fatal headers error: %s\n", nghttp2_strerror(xret)); } @@ -1780,8 +1781,6 @@ nghttp2_client_frame_submit_header(struct tfe_h2_stream *h2_stream_info, downstream_create_resp(h2_session, h2_stream_info->as_client, h2_stream_info->as_server, h2_stream_info->tf_stream, h2_stream_info->thread_id); /*Adapt inconsistent client and server stream ids ***/ - nghttp2_session_set_next_stream_id(h2_stream_info->as_client, h2_session->ngh2_stream_id); - if (h2_session->plugin_built_resp) { stream_action = nghttp2_submit_built_response(h2_stream_info, h2_session); @@ -1802,10 +1801,13 @@ nghttp2_client_frame_submit_header(struct tfe_h2_stream *h2_stream_info, return stream_action; } } - nghttp2_nv hdrs[headers->nvlen]; + nghttp2_nv hdrs[headers->nvlen]; + /**Register the stream id as -1 and read the next stream id */ + nghttp2_session_set_next_stream_id(h2_stream_info->as_client, h2_session->ngh2_stream_id); stream_id = nghttp2_submit_headers(h2_stream_info->as_client, headers->flag, - -1, NULL, tfe_h2_header_modify_field(headers, hdrs, ":path", req->url_storage), + -1, NULL, tfe_h2_header_modify_field(headers, hdrs, ":path", req->url_storage), headers->nvlen, h2_session); + if (stream_id < 0){ TFE_LOG_ERROR(logger()->handle, "Could not submit request: %s", nghttp2_strerror(stream_id)); @@ -1837,7 +1839,7 @@ nghttp2_client_submit_header(struct tfe_h2_stream *h2_stream_info, int32_t strea req = h2_session->req; fill_req_spec_from_handle(h2_session->req); - h2_stream_info->as_client->last_sent_stream_id = MIN(h2_stream_info->as_client->last_sent_stream_id, stream_id) - 1; + //h2_stream_info->as_client->last_sent_stream_id = MIN(h2_stream_info->as_client->last_sent_stream_id, stream_id) - 1; req->event_cb(req, EV_HTTP_REQ_HDR, NULL, 0, req->event_cb_user);