增加cast async result的工具函数。
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
|
||||
#include <tfe_stream.h>
|
||||
#include <tfe_utils.h>
|
||||
#include <tfe_future.h>
|
||||
@@ -26,19 +27,18 @@
|
||||
#include <cert.h>
|
||||
#include <ssl.h>
|
||||
|
||||
struct peek_sni_ctx
|
||||
struct peek_client_hello_ctx
|
||||
{
|
||||
/* ssl */
|
||||
|
||||
unsigned char sni_peek_retries; /* max 64 SNI parse retries */
|
||||
char* sni;
|
||||
|
||||
struct event* ev;
|
||||
struct event_base* evbase;
|
||||
|
||||
};
|
||||
|
||||
void peek_sni_ctx_free(void* ctx)
|
||||
void peek_client_hello_ctx_free(void* ctx)
|
||||
{
|
||||
struct peek_sni_ctx * _ctx=(struct peek_sni_ctx *)ctx;
|
||||
struct peek_client_hello_ctx * _ctx=(struct peek_client_hello_ctx *)ctx;
|
||||
event_free(_ctx->ev);
|
||||
_ctx->ev = NULL;
|
||||
free(_ctx->sni);
|
||||
@@ -46,13 +46,40 @@ void peek_sni_ctx_free(void* ctx)
|
||||
free(_ctx);
|
||||
return;
|
||||
}
|
||||
struct ssl_client_hello* ssl_get_peek_result(void* result)
|
||||
{
|
||||
struct ssl_client_hello* p=(struct ssl_client_hello* )result, *copy=NULL;
|
||||
copy=ALLOC(struct ssl_client_hello*,1);
|
||||
if(p!=NULL)
|
||||
{
|
||||
copy->sni=tfe_strdup(p->sni);
|
||||
copy->cipher_suites=tfe_strdup(p->cipher_suites);
|
||||
copy->version=p->version;
|
||||
}
|
||||
return copy;
|
||||
}
|
||||
void ssl_free_peek_result(struct ssl_client_hello* p)
|
||||
{
|
||||
if(p==NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
free(p->sni);
|
||||
p->sni=NULL;
|
||||
free(p->cipher_suites);
|
||||
p->cipher_suites=NULL;
|
||||
p->cipher_suites=NULL;
|
||||
free(p);
|
||||
return;
|
||||
}
|
||||
|
||||
static void peek_sni_cb(evutil_socket_t fd, short what, void * arg)
|
||||
static void peek_client_hello_cb(evutil_socket_t fd, short what, void * arg)
|
||||
{
|
||||
struct promise* promise=(struct promise*)arg;
|
||||
struct peek_sni_ctx* ctx= (struct peek_sni_ctx*)promise->ctx;
|
||||
|
||||
|
||||
struct peek_client_hello_ctx* ctx= (struct peek_client_hello_ctx*)promise->ctx;
|
||||
|
||||
struct ssl_client_hello *result=NULL;
|
||||
memset(&result, 0, sizeof(result));
|
||||
char* sni=NULL;
|
||||
unsigned char buf[1024];
|
||||
ssize_t n=0;
|
||||
@@ -62,19 +89,20 @@ static void peek_sni_cb(evutil_socket_t fd, short what, void * arg)
|
||||
n = recv(fd, buf, sizeof(buf), MSG_PEEK);
|
||||
if (n == -1)
|
||||
{
|
||||
goto promise_failed;
|
||||
TFE_LOG_ERROR("Error peeking on fd, aborting connection\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (n == 0)
|
||||
goto promise_failed;
|
||||
{
|
||||
goto failed;
|
||||
|
||||
rv = ssl_tls_clienthello_parse(buf, n, 0, &chello, &ctx->sni);
|
||||
}
|
||||
result=ssl_get_peek_result(NULL);
|
||||
//todo: parse version and cipher suites.
|
||||
rv = ssl_tls_clienthello_parse(buf, n, 0, &chello, &result->sni);
|
||||
if ((rv == 1) && !chello)
|
||||
{
|
||||
goto promise_failed;
|
||||
TFE_LOG_ERROR("Peeking did not yield a (truncated) ClientHello message, aborting connection\n");
|
||||
goto failed;
|
||||
}
|
||||
|
||||
@@ -90,32 +118,37 @@ static void peek_sni_cb(evutil_socket_t fd, short what, void * arg)
|
||||
* reading now. We use 25 * 0.2 s = 5 s timeout. */
|
||||
struct timeval retry_delay = {0, 100};
|
||||
|
||||
ctx->ev = event_new(ctx->evbase, fd, 0, peek_sni_cb, promise);
|
||||
event_free(ctx->ev);
|
||||
ctx->ev = event_new(ctx->evbase, fd, 0, peek_client_hello_cb, promise);
|
||||
assert(ctx->ev!=NULL);
|
||||
event_add(ctx->ev, &retry_delay);
|
||||
return;
|
||||
}
|
||||
promise_set_ctx(promise, NULL, NULL);
|
||||
promise->f.cb_success(ctx->sni,promise->f.user);
|
||||
peek_sni_ctx_free(ctx);
|
||||
|
||||
|
||||
promise_dettach_ctx(promise);
|
||||
promise_success(promise, result);
|
||||
ssl_free_peek_result(result);
|
||||
peek_client_hello_ctx_free(ctx);
|
||||
|
||||
promise_failed:
|
||||
promise->f.cb_failed(FUTURE_ERROR_EXCEPTION,"too many tries",promise->f.user);
|
||||
peek_sni_ctx_free(ctx);
|
||||
promise_set_ctx(promise, NULL,NULL);
|
||||
return;
|
||||
failed:
|
||||
promise_failed(promise,FUTURE_ERROR_EXCEPTION,"too many tries");
|
||||
peek_client_hello_ctx_free(ctx);
|
||||
promise_dettach_ctx(promise);
|
||||
ssl_free_peek_result(result);
|
||||
|
||||
return;
|
||||
}
|
||||
void ssl_async_peek_sni( struct future* future, evutil_socket_t fd, struct event_base *evbase)
|
||||
|
||||
|
||||
void ssl_async_peek_client_hello(struct future* future, evutil_socket_t fd, struct event_base *evbase)
|
||||
{
|
||||
struct event * ev=NULL;
|
||||
struct peek_sni_ctx* ctx=ALLOC(struct peek_sni_ctx, 1);
|
||||
ctx->ev = event_new(evbase, fd, EV_READ, peek_sni_cb, p);
|
||||
struct promise* p=future_to_promise(future);
|
||||
|
||||
struct peek_client_hello_ctx* ctx=ALLOC(struct peek_client_hello_ctx, 1);
|
||||
ctx->ev = event_new(evbase, fd, EV_READ, peek_client_hello_cb, p);
|
||||
promise_set_ctx(p, ctx,peek_sni_ctx_free);
|
||||
event_add(evbase, NULL);
|
||||
promise_set_ctx(p, ctx, peek_client_hello_ctx_free);
|
||||
|
||||
return;
|
||||
@@ -166,8 +199,7 @@ static void ssl_connect_origin_eventcb(struct bufferevent * bev, short events, v
|
||||
ssl_connect_origin_ctx_free(ctx);
|
||||
return
|
||||
}
|
||||
void ssl_async_connect_origin(struct future* future, evutil_socket_t fd, const char* sni,
|
||||
struct event_base *evbase, struct tfe_config *opts)
|
||||
|
||||
void ssl_async_connect_origin(struct future* future, const struct ssl_client_hello* client_hello, evutil_socket_t fd, const char* sni, struct event_base *evbase)
|
||||
{
|
||||
struct promise* p=future_to_promise(future);
|
||||
@@ -827,7 +859,8 @@ static int pxy_ossl_servername_cb(SSL * ssl, UNUSED int * al, void * arg)
|
||||
/*
|
||||
* Create new SSL context for outgoing connections to the original destination.
|
||||
* If hostname sni is provided, use it for Server Name Indication.
|
||||
static SSL* upstream_ssl_create(tfe_config*opts, const char* sni)
|
||||
*/
|
||||
|
||||
static SSL* upstream_ssl_create(const struct ssl_client_hello* client_hello, int sslversion, const char* sni, MESA_htable_handle* dsess_cache)
|
||||
{
|
||||
SSL_CTX* sslctx=NULL;
|
||||
|
||||
Reference in New Issue
Block a user