|
|
|
|
@@ -185,7 +185,7 @@ struct ssl_upstream_parts
|
|
|
|
|
int apln_enabled;
|
|
|
|
|
int keyring_id;
|
|
|
|
|
struct ssl_chello * client_hello;
|
|
|
|
|
int is_server_cert_verify_passed;
|
|
|
|
|
int is_server_cert_verify_passed;
|
|
|
|
|
};
|
|
|
|
|
struct ssl_downstream_parts
|
|
|
|
|
{
|
|
|
|
|
@@ -203,10 +203,14 @@ struct ssl_stream
|
|
|
|
|
};
|
|
|
|
|
int ssl_min_version, ssl_max_version, negotiated_version;
|
|
|
|
|
const unsigned char* alpn_selected; //reference to SSL_ALPN_HTTP_2/SSL_ALPN_HTTP_1_1
|
|
|
|
|
struct tfe_stream* tcp_stream;
|
|
|
|
|
uint64_t connect_latency_ms;
|
|
|
|
|
|
|
|
|
|
struct ssl_stream* peer;
|
|
|
|
|
socklen_t addrlen;
|
|
|
|
|
struct sockaddr_storage addr;
|
|
|
|
|
struct __ssl_stream_debug _do_not_use;
|
|
|
|
|
enum ssl_stream_error error;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -230,16 +234,17 @@ struct ssl_connect_server_ctx
|
|
|
|
|
|
|
|
|
|
evutil_socket_t fd_upstream;
|
|
|
|
|
evutil_socket_t fd_downstream;
|
|
|
|
|
unsigned int thread_id;
|
|
|
|
|
|
|
|
|
|
struct tfe_stream* tcp_stream;
|
|
|
|
|
|
|
|
|
|
struct future * f_peek_chello;
|
|
|
|
|
struct timespec start,end;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct ssl_connect_client_ctx
|
|
|
|
|
{
|
|
|
|
|
unsigned int thread_id;
|
|
|
|
|
int keyring_id;
|
|
|
|
|
struct ssl_stream * origin_ssl;
|
|
|
|
|
struct tfe_stream* tcp_stream;
|
|
|
|
|
struct ssl_stream * peer;
|
|
|
|
|
X509 * origin_crt;
|
|
|
|
|
int is_origin_crt_verify_passed;
|
|
|
|
|
struct ssl_mgr * ssl_mgr;
|
|
|
|
|
@@ -307,7 +312,18 @@ int sslver_str2num(const char * version_str)
|
|
|
|
|
|
|
|
|
|
return sslversion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const char* ssl_stream_get_error_string(enum ssl_stream_error error)
|
|
|
|
|
{
|
|
|
|
|
const char* ssl_err_str[__SSL_STREAM_R_MAX];
|
|
|
|
|
ssl_err_str[SSL_STREAM_R_NO_ERROR]="OK";
|
|
|
|
|
ssl_err_str[SSL_STREAM_R_SERVER_CLOSED]="server-side closed";
|
|
|
|
|
ssl_err_str[SSL_STREAM_R_CLIENT_CLOSED]="client-side closed";
|
|
|
|
|
ssl_err_str[SSL_STREAM_R_CONNECT_SERVER_TIMEOUT]="server-side timeout";
|
|
|
|
|
ssl_err_str[SSL_STREAM_R_CONNECT_CLIENT_TIMEOUT]="client-side timeout";
|
|
|
|
|
ssl_err_str[SSL_STREAM_R_SERVER_PROTOCOL_ERROR]="server-side protocol errors";
|
|
|
|
|
ssl_err_str[SSL_STREAM_R_CLIENT_PROTOCOL_ERROR]="client-side protocol errors";
|
|
|
|
|
return ssl_err_str[error];
|
|
|
|
|
}
|
|
|
|
|
/*
|
|
|
|
|
* Garbage collection handler.
|
|
|
|
|
*/
|
|
|
|
|
@@ -463,7 +479,7 @@ struct ssl_chello * ssl_peek_result_release_chello(future_result_t * result)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enum tfe_conn_dir dir,
|
|
|
|
|
struct ssl_chello * client_hello, struct keyring * kyr, struct ssl_stream * peer)
|
|
|
|
|
struct ssl_chello * client_hello, struct keyring * kyr, struct ssl_stream * peer, struct tfe_stream* tcp_stream)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
UNUSED int ret = 0;
|
|
|
|
|
@@ -475,7 +491,7 @@ struct ssl_stream * ssl_stream_new(struct ssl_mgr * mgr, evutil_socket_t fd, enu
|
|
|
|
|
s_stream->ssl_max_version=mgr->ssl_max_version;
|
|
|
|
|
s_stream->ssl_min_version=mgr->ssl_min_version;
|
|
|
|
|
s_stream->peer=peer;
|
|
|
|
|
|
|
|
|
|
s_stream->tcp_stream=tcp_stream;
|
|
|
|
|
ret = getpeername(fd, (struct sockaddr *) (&s_stream->addr), &(s_stream->addrlen));
|
|
|
|
|
switch (dir)
|
|
|
|
|
{
|
|
|
|
|
@@ -1098,6 +1114,21 @@ unsigned long ssl_stream_log_error(struct bufferevent * bev, enum tfe_conn_dir d
|
|
|
|
|
return ret_sslerr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void ssl_stream_set_cmsg_string(struct ssl_stream* stream, enum tfe_cmsg_tlv_type type, const char* value_str)
|
|
|
|
|
{
|
|
|
|
|
struct tfe_cmsg* cmsg=tfe_stream_get0_cmsg(stream->tcp_stream);
|
|
|
|
|
int ret=tfe_cmsg_set(cmsg, type, (const unsigned char*)value_str, (uint16_t)strlen(value_str));
|
|
|
|
|
assert(ret==0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
static void ssl_stream_set_cmsg_integer(struct ssl_stream* stream, enum tfe_cmsg_tlv_type type, uint64_t value_int)
|
|
|
|
|
{
|
|
|
|
|
struct tfe_cmsg* cmsg=tfe_stream_get0_cmsg(stream->tcp_stream);
|
|
|
|
|
int ret=tfe_cmsg_set(cmsg, type, (const unsigned char*)&value_int, (uint16_t)sizeof(value_int));
|
|
|
|
|
assert(ret==0);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Callback for meta events on the up- and downstream connection bufferevents.
|
|
|
|
|
* Called when EOF has been reached, a connection has been made, and on errors.
|
|
|
|
|
@@ -1114,8 +1145,7 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
SSL_SESSION * ssl_sess = NULL;
|
|
|
|
|
char error_str[TFE_STRING_MAX];
|
|
|
|
|
const char* sni=s_upstream->client_hello->sni?s_upstream->client_hello->sni:"null";
|
|
|
|
|
long jiffies_ms;
|
|
|
|
|
char* addr_string=NULL;
|
|
|
|
|
uint64_t jiffies_ms;
|
|
|
|
|
unsigned long sslerr=0;
|
|
|
|
|
if (events & BEV_EVENT_ERROR)
|
|
|
|
|
{
|
|
|
|
|
@@ -1126,20 +1156,17 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
s_upstream->svc_status.has_protocol_errors=1;
|
|
|
|
|
ssl_service_cache_write(mgr->svc_cache, s_stream->up_parts.client_hello, &(s_stream->up_parts.svc_status));
|
|
|
|
|
}
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "connect to original server failed : sni=%s", sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
|
|
|
|
|
s_stream->error=SSL_STREAM_R_SERVER_PROTOCOL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
else if(events & BEV_EVENT_EOF)
|
|
|
|
|
{
|
|
|
|
|
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "original server closed : sni=%s", sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
|
|
|
|
|
s_stream->error=SSL_STREAM_R_SERVER_CLOSED;
|
|
|
|
|
}
|
|
|
|
|
else if(events & BEV_EVENT_TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "timeout : sni=%s", sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_TIMEOUT, error_str);
|
|
|
|
|
ATOMIC_INC(&(ctx->mgr->stat_val[SSL_UP_ERR]));
|
|
|
|
|
s_stream->error=SSL_STREAM_R_CONNECT_SERVER_TIMEOUT;
|
|
|
|
|
}
|
|
|
|
|
else if(events & BEV_EVENT_CONNECTED)
|
|
|
|
|
{
|
|
|
|
|
@@ -1149,11 +1176,10 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
jiffies_ms=(ctx->end.tv_sec-ctx->start.tv_sec)*1000+(ctx->end.tv_nsec-ctx->start.tv_nsec)/1000000;
|
|
|
|
|
if(jiffies_ms>LATENCY_WARNING_THRESHOLD_MS)
|
|
|
|
|
{
|
|
|
|
|
addr_string=tfe_string_addr_create_by_fd(ctx->fd_upstream, CONN_DIR_UPSTREAM);
|
|
|
|
|
TFE_LOG_ERROR(mgr->logger, "Warning: ssl connect server latency %ld ms: addr=%s, sni=%s", jiffies_ms, addr_string, sni);
|
|
|
|
|
free(addr_string);
|
|
|
|
|
addr_string=NULL;
|
|
|
|
|
TFE_LOG_ERROR(mgr->logger, "Warning: ssl connect server latency %ld ms: addr=%s, sni=%s", jiffies_ms, s_stream->tcp_stream->str_stream_info, sni);
|
|
|
|
|
}
|
|
|
|
|
s_stream->connect_latency_ms=jiffies_ms;
|
|
|
|
|
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_UPSTREAM_LATENCY, jiffies_ms);
|
|
|
|
|
|
|
|
|
|
if(!SSL_session_reused(s_stream->ssl))
|
|
|
|
|
{
|
|
|
|
|
@@ -1169,7 +1195,8 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
s_upstream->svc_status.is_ct=s_upstream->verify_result.is_ct;
|
|
|
|
|
s_upstream->svc_status.is_ev=s_upstream->verify_result.is_ev;
|
|
|
|
|
ssl_service_cache_write(mgr->svc_cache, s_upstream->client_hello, &(s_upstream->svc_status));
|
|
|
|
|
TFE_LOG_DEBUG(mgr->logger, "SNI: %s hostmatch:%d, ct:%d, ev:%d",
|
|
|
|
|
TFE_LOG_DEBUG(mgr->logger, "stream:%s sni:%s hostmatch:%d, ct:%d, ev:%d",
|
|
|
|
|
s_stream->tcp_stream->str_stream_info,
|
|
|
|
|
s_upstream->client_hello->sni,
|
|
|
|
|
s_upstream->verify_result.is_hostmatched,
|
|
|
|
|
s_upstream->verify_result.is_ct,
|
|
|
|
|
@@ -1226,8 +1253,16 @@ static void ssl_server_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
s_stream->negotiated_version=SSL_version(s_stream->ssl);
|
|
|
|
|
ssl_stream_set_cmsg_string(s_stream, TFE_CMSG_SSL_UPSTREAM_VERSION, SSL_get_version(s_stream->ssl));
|
|
|
|
|
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_CERT_VERIFY, s_upstream->is_server_cert_verify_passed);
|
|
|
|
|
promise_success(p, ctx);
|
|
|
|
|
}
|
|
|
|
|
if(s_stream->error)
|
|
|
|
|
{
|
|
|
|
|
ssl_stream_set_cmsg_string(s_stream, TFE_CMSG_SSL_ERROR, ssl_stream_get_error_string(s_stream->error));
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "%s, sni=%s", ssl_stream_get_error_string(s_stream->error), sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
|
|
|
|
|
}
|
|
|
|
|
wrap_ssl_connect_server_ctx_free(ctx);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -1236,7 +1271,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
|
|
|
|
{
|
|
|
|
|
struct promise * p = (struct promise *) user;
|
|
|
|
|
struct ssl_connect_server_ctx* ctx = (struct ssl_connect_server_ctx *) promise_get_ctx(p);
|
|
|
|
|
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(ctx->thread_id);
|
|
|
|
|
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(ctx->tcp_stream->thread_id);
|
|
|
|
|
struct ssl_stream* s_stream=NULL;
|
|
|
|
|
struct ssl_chello* chello = ssl_peek_result_release_chello(result);//chello has been saved in ssl_stream.
|
|
|
|
|
if(chello->sni==NULL)
|
|
|
|
|
@@ -1246,7 +1281,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
|
|
|
|
int ret=0;
|
|
|
|
|
struct ssl_service_status* svc_status=NULL;
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &(ctx->start));
|
|
|
|
|
s_stream= ssl_stream_new(ctx->mgr, ctx->fd_upstream, CONN_DIR_UPSTREAM, chello, NULL, NULL);
|
|
|
|
|
s_stream= ssl_stream_new(ctx->mgr, ctx->fd_upstream, CONN_DIR_UPSTREAM, chello, NULL, NULL, ctx->tcp_stream);
|
|
|
|
|
svc_status=&s_stream->up_parts.svc_status;
|
|
|
|
|
ret=ssl_service_cache_read(ctx->mgr->svc_cache, chello, svc_status);
|
|
|
|
|
if(ret==1)
|
|
|
|
|
@@ -1259,6 +1294,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
|
|
|
|
svc_status->is_ct,
|
|
|
|
|
svc_status->is_ev);
|
|
|
|
|
}
|
|
|
|
|
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_PINNING_STATE, svc_status->pinning_status);
|
|
|
|
|
if(ctx->mgr->on_new_upstream_cb)
|
|
|
|
|
{
|
|
|
|
|
s_stream->up_parts.action=ctx->mgr->on_new_upstream_cb(s_stream, ctx->mgr->upstream_cb_param);
|
|
|
|
|
@@ -1267,6 +1303,7 @@ static void peek_chello_on_succ(future_result_t * result, void * user)
|
|
|
|
|
{
|
|
|
|
|
s_stream->up_parts.action=SSL_ACTION_INTERCEPT;
|
|
|
|
|
}
|
|
|
|
|
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_INTERCEPT_STATE, s_stream->up_parts.action);
|
|
|
|
|
ctx->s_stream = s_stream;
|
|
|
|
|
if(s_stream->up_parts.action==SSL_ACTION_PASSTHROUGH)
|
|
|
|
|
{
|
|
|
|
|
@@ -1301,7 +1338,7 @@ static void peek_chello_on_fail(enum e_future_error err, const char * what, void
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ssl_async_upstream_create(struct future * f, struct ssl_mgr * mgr, evutil_socket_t fd_upstream,
|
|
|
|
|
evutil_socket_t fd_downstream, unsigned int thread_id)
|
|
|
|
|
evutil_socket_t fd_downstream, struct tfe_stream* tcp_stream)
|
|
|
|
|
{
|
|
|
|
|
struct promise * p = future_to_promise(f);
|
|
|
|
|
struct ssl_connect_server_ctx * ctx = ALLOC(struct ssl_connect_server_ctx, 1);
|
|
|
|
|
@@ -1315,10 +1352,10 @@ void ssl_async_upstream_create(struct future * f, struct ssl_mgr * mgr, evutil_s
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_EXCEPTION, "upstream fd closed");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(thread_id);
|
|
|
|
|
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(tcp_stream->thread_id);
|
|
|
|
|
ctx->fd_downstream = fd_downstream;
|
|
|
|
|
ctx->fd_upstream = fd_upstream;
|
|
|
|
|
ctx->thread_id = thread_id;
|
|
|
|
|
ctx->tcp_stream = tcp_stream;
|
|
|
|
|
ctx->mgr = mgr;
|
|
|
|
|
promise_set_ctx(p, ctx, wrap_ssl_connect_server_ctx_free);
|
|
|
|
|
|
|
|
|
|
@@ -1689,12 +1726,11 @@ static void ssl_client_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
struct ssl_connect_client_ctx * ctx = (struct ssl_connect_client_ctx *) promise_dettach_ctx(p);
|
|
|
|
|
|
|
|
|
|
struct ssl_stream * s_stream = ctx->downstream;
|
|
|
|
|
struct ssl_upstream_parts* s_upstream= &(ctx->origin_ssl->up_parts);
|
|
|
|
|
struct ssl_upstream_parts* s_upstream= &(ctx->peer->up_parts);
|
|
|
|
|
struct ssl_mgr* mgr=s_stream->mgr;
|
|
|
|
|
char* addr_string=NULL;
|
|
|
|
|
const char* sni=s_upstream->client_hello->sni?s_upstream->client_hello->sni:"null";
|
|
|
|
|
char error_str[TFE_STRING_MAX]={0};
|
|
|
|
|
long jiffies_ms=0;
|
|
|
|
|
uint64_t jiffies_ms=0;
|
|
|
|
|
unsigned long sslerr=0;
|
|
|
|
|
if (events & BEV_EVENT_ERROR)
|
|
|
|
|
{
|
|
|
|
|
@@ -1705,6 +1741,7 @@ static void ssl_client_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
s_upstream->verify_result.is_hostmatched)
|
|
|
|
|
{
|
|
|
|
|
s_upstream->svc_status.pinning_status=PINNING_ST_PINNING;
|
|
|
|
|
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_PINNING_STATE, PINNING_ST_PINNING);
|
|
|
|
|
ssl_service_cache_write(mgr->svc_cache, s_upstream->client_hello, &s_upstream->svc_status);
|
|
|
|
|
}
|
|
|
|
|
else if(sslerr>0 && sslerr!=SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN)
|
|
|
|
|
@@ -1712,8 +1749,7 @@ static void ssl_client_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
s_upstream->svc_status.has_protocol_errors=1;
|
|
|
|
|
ssl_service_cache_write(mgr->svc_cache, s_upstream->client_hello, &s_upstream->svc_status);
|
|
|
|
|
}
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "connect to client failed : sni=%s", sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
|
|
|
|
|
s_stream->error=SSL_STREAM_R_CLIENT_PROTOCOL_ERROR;
|
|
|
|
|
}
|
|
|
|
|
else if(events & BEV_EVENT_EOF)
|
|
|
|
|
{
|
|
|
|
|
@@ -1721,16 +1757,15 @@ static void ssl_client_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
if(s_upstream->verify_result.is_hostmatched && s_upstream->is_server_cert_verify_passed )
|
|
|
|
|
{
|
|
|
|
|
s_upstream->svc_status.pinning_status=PINNING_ST_MAYBE_PINNING;
|
|
|
|
|
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_PINNING_STATE, PINNING_ST_MAYBE_PINNING);
|
|
|
|
|
ssl_service_cache_write(mgr->svc_cache, s_stream->peer->up_parts.client_hello, &(s_stream->peer->up_parts.svc_status));
|
|
|
|
|
}
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "client side closed : sni=%s", sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
|
|
|
|
|
s_stream->error=SSL_STREAM_R_CLIENT_CLOSED;
|
|
|
|
|
}
|
|
|
|
|
else if(events & BEV_EVENT_TIMEOUT)
|
|
|
|
|
{
|
|
|
|
|
ATOMIC_INC(&(mgr->stat_val[SSL_DOWN_ERR]));
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "timeout : sni=%s", sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_TIMEOUT, error_str);
|
|
|
|
|
s_stream->error=SSL_STREAM_R_CONNECT_CLIENT_TIMEOUT;
|
|
|
|
|
}
|
|
|
|
|
else if(events & BEV_EVENT_CONNECTED)
|
|
|
|
|
{
|
|
|
|
|
@@ -1739,21 +1774,29 @@ static void ssl_client_connected_eventcb(struct bufferevent * bev, short events,
|
|
|
|
|
jiffies_ms=(ctx->end.tv_sec-ctx->start.tv_sec)*1000+(ctx->end.tv_nsec-ctx->start.tv_nsec)/1000000;
|
|
|
|
|
if(jiffies_ms>LATENCY_WARNING_THRESHOLD_MS)
|
|
|
|
|
{
|
|
|
|
|
addr_string=tfe_string_addr_create_by_fd(ctx->fd_downstream, CONN_DIR_DOWNSTREAM);
|
|
|
|
|
TFE_LOG_ERROR(mgr->logger, "Warning: ssl connect client latency %ld ms: addr=%s, sni=%s", jiffies_ms, addr_string, sni);
|
|
|
|
|
free(addr_string);
|
|
|
|
|
addr_string=NULL;
|
|
|
|
|
TFE_LOG_ERROR(mgr->logger, "Warning: ssl connect client latency %ld ms: addr=%s, sni=%s", jiffies_ms, s_stream->tcp_stream->str_stream_info, sni);
|
|
|
|
|
}
|
|
|
|
|
s_stream->connect_latency_ms=jiffies_ms;
|
|
|
|
|
ssl_stream_set_cmsg_integer(s_stream, TFE_CMSG_SSL_DOWNSTREAM_LATENCY, jiffies_ms);
|
|
|
|
|
bufferevent_disable(ctx->bev_down, EV_READ | EV_WRITE);
|
|
|
|
|
bufferevent_setcb(ctx->bev_down, NULL, NULL, NULL, NULL); //leave a clean bev for on_success
|
|
|
|
|
|
|
|
|
|
if(mgr->log_master_key)
|
|
|
|
|
{
|
|
|
|
|
log_ssl_master_key(ctx->downstream->ssl, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, mgr->fp_master_key);
|
|
|
|
|
log_ssl_master_key(s_stream->ssl, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, mgr->fp_master_key);
|
|
|
|
|
}
|
|
|
|
|
ctx->downstream->negotiated_version=SSL_version(ctx->downstream->ssl);
|
|
|
|
|
s_stream->negotiated_version=SSL_version(s_stream->ssl);
|
|
|
|
|
ssl_stream_set_cmsg_string(s_stream, TFE_CMSG_SSL_DOWNSTREAM_VERSION, SSL_get_version(s_stream->ssl));
|
|
|
|
|
promise_success(p, ctx);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if(s_stream->error)
|
|
|
|
|
{
|
|
|
|
|
ssl_stream_set_cmsg_string(s_stream, TFE_CMSG_SSL_ERROR, ssl_stream_get_error_string(s_stream->error));
|
|
|
|
|
snprintf(error_str, sizeof(error_str), "%s : sni=%s", ssl_stream_get_error_string(s_stream->error), sni);
|
|
|
|
|
promise_failed(p, FUTURE_ERROR_EXCEPTION, error_str);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ssl_connect_client_ctx_free(ctx);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -1765,13 +1808,13 @@ void ask_keyring_on_succ(void * result, void * user)
|
|
|
|
|
|
|
|
|
|
struct keyring * kyr = NULL;
|
|
|
|
|
struct ssl_mgr * mgr = ctx->ssl_mgr;
|
|
|
|
|
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(ctx->thread_id);
|
|
|
|
|
struct event_base* evbase=tfe_proxy_get_work_thread_evbase(ctx->tcp_stream->thread_id);
|
|
|
|
|
|
|
|
|
|
kyr = key_keeper_release_keyring(result); //kyr will be freed at ssl downstream closing.
|
|
|
|
|
|
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, &(ctx->start));
|
|
|
|
|
ctx->downstream = ssl_stream_new(mgr, ctx->fd_downstream, CONN_DIR_DOWNSTREAM, NULL,
|
|
|
|
|
kyr, ctx->origin_ssl);
|
|
|
|
|
kyr, ctx->peer, ctx->tcp_stream);
|
|
|
|
|
downstream_ossl_init(ctx->downstream);
|
|
|
|
|
ctx->bev_down = bufferevent_openssl_socket_new(evbase, ctx->fd_downstream, ctx->downstream->ssl,
|
|
|
|
|
BUFFEREVENT_SSL_ACCEPTING, BEV_OPT_DEFER_CALLBACKS | BEV_OPT_THREADSAFE);
|
|
|
|
|
@@ -1798,22 +1841,21 @@ void ask_keyring_on_fail(enum e_future_error error, const char * what, void * us
|
|
|
|
|
* Create a SSL stream for the incoming connection, based on the upstream.
|
|
|
|
|
*/
|
|
|
|
|
void ssl_async_downstream_create(struct future * f, struct ssl_mgr * mgr, struct ssl_stream * upstream,
|
|
|
|
|
evutil_socket_t fd_downstream, unsigned int thread_id)
|
|
|
|
|
evutil_socket_t fd_downstream, struct tfe_stream* tcp_stream)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
assert(upstream->dir == CONN_DIR_UPSTREAM);
|
|
|
|
|
const char* sni=NULL;
|
|
|
|
|
struct ssl_connect_client_ctx * ctx = ALLOC(struct ssl_connect_client_ctx, 1);
|
|
|
|
|
ctx->keyring_id = upstream->up_parts.keyring_id;
|
|
|
|
|
struct ssl_connect_client_ctx * ctx = ALLOC(struct ssl_connect_client_ctx, 1);
|
|
|
|
|
ctx->ssl_mgr = mgr;
|
|
|
|
|
ctx->fd_downstream = fd_downstream;
|
|
|
|
|
ctx->thread_id = thread_id;
|
|
|
|
|
struct event_base * evbase=tfe_proxy_get_work_thread_evbase(thread_id);
|
|
|
|
|
struct evdns_base* dnsbase=tfe_proxy_get_work_thread_dnsbase(thread_id);
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
if (upstream != NULL)
|
|
|
|
|
{
|
|
|
|
|
ctx->origin_ssl = upstream;
|
|
|
|
|
ctx->peer = upstream;
|
|
|
|
|
ctx->origin_crt = SSL_get_peer_certificate(upstream->ssl);
|
|
|
|
|
sni=upstream->up_parts.client_hello->sni;
|
|
|
|
|
}
|
|
|
|
|
@@ -1823,7 +1865,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, ctx->keyring_id, ctx->origin_crt, ctx->is_origin_crt_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);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -2035,9 +2077,12 @@ int ssl_stream_set_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val)
|
|
|
|
|
int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT opt_type, int *opt_val)
|
|
|
|
|
{
|
|
|
|
|
struct ssl_service_status* svc=&upstream->up_parts.svc_status;
|
|
|
|
|
struct tfe_cmsg *cmsg=NULL;
|
|
|
|
|
int ret=0;
|
|
|
|
|
uint16_t out_size=0;
|
|
|
|
|
switch(opt_type)
|
|
|
|
|
{
|
|
|
|
|
case SSL_STREAM_OPT_IS_EV_CERT:
|
|
|
|
|
@@ -2055,11 +2100,16 @@ int ssl_stream_get_integer_opt(struct ssl_stream *upstream, enum SSL_STREAM_OPT
|
|
|
|
|
case SSL_STREAM_OPT_HAS_PROTOCOL_ERRORS:
|
|
|
|
|
*opt_val=svc->has_protocol_errors;
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SSL_STREAM_OPT_INTERCEPT_POLICY_ID:
|
|
|
|
|
cmsg=tfe_stream_get0_cmsg(upstream->tcp_stream);
|
|
|
|
|
ret=tfe_cmsg_get_value(cmsg, TFE_CMSG_POLICY_ID, (unsigned char*)opt_val, sizeof(*opt_val), &out_size);
|
|
|
|
|
assert(ret==0);
|
|
|
|
|
assert(out_size==sizeof(*opt_val));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return 0;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|