mirror of
https://github.com/libevent/libevent.git
synced 2025-01-31 09:12:55 +08:00
Merge branch 'test-regress-be-openssl-v2'
This patchset is a bunch of regression tests for bufferevent openssl layer, some of them already show some bugs, that bugs will be fixed in the next patches. * test-regress-be-openssl-v2: test/regress_ssl: check events fd/pending after timeout triggered test/regress_ssl: cover case when server didn't up (failed with timeout) test/regress_ssl: covert that we can't change fd with underlying test/regress_ssl: cover that events (read/write) at finish not pending test/regress_ssl: cover fd manipulations test/regress_ssl: convert open_ssl_bufevs() to mask test/regress_ssl: convert client/server to mask too test/regress_ssl: cover "allow_dirty_shutdown" test/regress_ssl: convert regress_bufferevent_openssl() to bitmask
This commit is contained in:
commit
af85ecfccc
@ -43,6 +43,7 @@
|
||||
#include "event2/util.h"
|
||||
#include "event2/event.h"
|
||||
#include "event2/bufferevent_ssl.h"
|
||||
#include "event2/bufferevent_struct.h"
|
||||
#include "event2/buffer.h"
|
||||
#include "event2/listener.h"
|
||||
|
||||
@ -177,17 +178,63 @@ static int test_is_done = 0;
|
||||
static int n_connected = 0;
|
||||
static int got_close = 0;
|
||||
static int got_error = 0;
|
||||
static int got_timeout = 0;
|
||||
static int renegotiate_at = -1;
|
||||
static int stop_when_connected = 0;
|
||||
static int pending_connect_events = 0;
|
||||
static struct event_base *exit_base = NULL;
|
||||
|
||||
enum regress_openssl_type
|
||||
{
|
||||
REGRESS_OPENSSL_SOCKETPAIR = 1,
|
||||
REGRESS_OPENSSL_FILTER = 2,
|
||||
REGRESS_OPENSSL_RENEGOTIATE = 4,
|
||||
REGRESS_OPENSSL_OPEN = 8,
|
||||
REGRESS_OPENSSL_DIRTY_SHUTDOWN = 16,
|
||||
REGRESS_OPENSSL_FD = 32,
|
||||
|
||||
REGRESS_OPENSSL_CLIENT = 64,
|
||||
REGRESS_OPENSSL_SERVER = 128,
|
||||
|
||||
REGRESS_OPENSSL_FREED = 256,
|
||||
REGRESS_OPENSSL_TIMEOUT = 512,
|
||||
};
|
||||
|
||||
static void
|
||||
bufferevent_openssl_check_fd(struct bufferevent *bev, int filter)
|
||||
{
|
||||
if (filter) {
|
||||
tt_int_op(bufferevent_getfd(bev), ==, -1);
|
||||
tt_int_op(bufferevent_setfd(bev, -1), ==, -1);
|
||||
} else {
|
||||
tt_int_op(bufferevent_getfd(bev), !=, -1);
|
||||
tt_int_op(bufferevent_setfd(bev, -1), ==, 0);
|
||||
}
|
||||
tt_int_op(bufferevent_getfd(bev), ==, -1);
|
||||
|
||||
end:
|
||||
;
|
||||
}
|
||||
static void
|
||||
bufferevent_openssl_check_freed(struct bufferevent *bev)
|
||||
{
|
||||
tt_int_op(event_pending(&bev->ev_read, EVLIST_ALL, NULL), ==, 0);
|
||||
tt_int_op(event_pending(&bev->ev_write, EVLIST_ALL, NULL), ==, 0);
|
||||
|
||||
end:
|
||||
;
|
||||
}
|
||||
|
||||
static void
|
||||
respond_to_number(struct bufferevent *bev, void *ctx)
|
||||
{
|
||||
struct evbuffer *b = bufferevent_get_input(bev);
|
||||
char *line;
|
||||
int n;
|
||||
|
||||
enum regress_openssl_type type;
|
||||
type = (enum regress_openssl_type)ctx;
|
||||
|
||||
line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF);
|
||||
if (! line)
|
||||
return;
|
||||
@ -201,7 +248,7 @@ respond_to_number(struct bufferevent *bev, void *ctx)
|
||||
bufferevent_free(bev); /* Should trigger close on other side. */
|
||||
return;
|
||||
}
|
||||
if (!strcmp(ctx, "client") && n == renegotiate_at) {
|
||||
if ((type & REGRESS_OPENSSL_CLIENT) && n == renegotiate_at) {
|
||||
SSL_renegotiate(bufferevent_openssl_get_ssl(bev));
|
||||
}
|
||||
++n;
|
||||
@ -226,6 +273,9 @@ done_writing_cb(struct bufferevent *bev, void *ctx)
|
||||
static void
|
||||
eventcb(struct bufferevent *bev, short what, void *ctx)
|
||||
{
|
||||
enum regress_openssl_type type;
|
||||
type = (enum regress_openssl_type)ctx;
|
||||
|
||||
TT_BLATHER(("Got event %d", (int)what));
|
||||
if (what & BEV_EVENT_CONNECTED) {
|
||||
SSL *ssl;
|
||||
@ -234,7 +284,7 @@ eventcb(struct bufferevent *bev, short what, void *ctx)
|
||||
ssl = bufferevent_openssl_get_ssl(bev);
|
||||
tt_assert(ssl);
|
||||
peer_cert = SSL_get_peer_certificate(ssl);
|
||||
if (0==strcmp(ctx, "server")) {
|
||||
if (type & REGRESS_OPENSSL_SERVER) {
|
||||
tt_assert(peer_cert == NULL);
|
||||
} else {
|
||||
tt_assert(peer_cert != NULL);
|
||||
@ -246,10 +296,32 @@ eventcb(struct bufferevent *bev, short what, void *ctx)
|
||||
} else if (what & BEV_EVENT_EOF) {
|
||||
TT_BLATHER(("Got a good EOF"));
|
||||
++got_close;
|
||||
if (type & REGRESS_OPENSSL_FD) {
|
||||
bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
|
||||
}
|
||||
if (type & REGRESS_OPENSSL_FREED) {
|
||||
bufferevent_openssl_check_freed(bev);
|
||||
}
|
||||
bufferevent_free(bev);
|
||||
} else if (what & BEV_EVENT_ERROR) {
|
||||
TT_BLATHER(("Got an error."));
|
||||
++got_error;
|
||||
if (type & REGRESS_OPENSSL_FD) {
|
||||
bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
|
||||
}
|
||||
if (type & REGRESS_OPENSSL_FREED) {
|
||||
bufferevent_openssl_check_freed(bev);
|
||||
}
|
||||
bufferevent_free(bev);
|
||||
} else if (what & BEV_EVENT_TIMEOUT) {
|
||||
TT_BLATHER(("Got timeout."));
|
||||
++got_timeout;
|
||||
if (type & REGRESS_OPENSSL_FD) {
|
||||
bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
|
||||
}
|
||||
if (type & REGRESS_OPENSSL_FREED) {
|
||||
bufferevent_openssl_check_freed(bev);
|
||||
}
|
||||
bufferevent_free(bev);
|
||||
}
|
||||
end:
|
||||
@ -259,7 +331,8 @@ end:
|
||||
static void
|
||||
open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out,
|
||||
struct event_base *base, int is_open, int flags, SSL *ssl1, SSL *ssl2,
|
||||
evutil_socket_t *fd_pair, struct bufferevent **underlying_pair)
|
||||
evutil_socket_t *fd_pair, struct bufferevent **underlying_pair,
|
||||
enum regress_openssl_type type)
|
||||
{
|
||||
int state1 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_CONNECTING;
|
||||
int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING;
|
||||
@ -276,9 +349,13 @@ open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out,
|
||||
|
||||
}
|
||||
bufferevent_setcb(*bev1_out, respond_to_number, done_writing_cb,
|
||||
eventcb, (void*)"client");
|
||||
eventcb, (void*)(REGRESS_OPENSSL_CLIENT | (long)type));
|
||||
bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb,
|
||||
eventcb, (void*)"server");
|
||||
eventcb, (void*)(REGRESS_OPENSSL_SERVER | (long)type));
|
||||
|
||||
int dirty_shutdown = type & REGRESS_OPENSSL_DIRTY_SHUTDOWN;
|
||||
bufferevent_openssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown);
|
||||
bufferevent_openssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -290,18 +367,19 @@ regress_bufferevent_openssl(void *arg)
|
||||
SSL *ssl1, *ssl2;
|
||||
X509 *cert = getcert();
|
||||
EVP_PKEY *key = getkey();
|
||||
const int start_open = strstr((char*)data->setup_data, "open")!=NULL;
|
||||
const int filter = strstr((char*)data->setup_data, "filter")!=NULL;
|
||||
int flags = BEV_OPT_DEFER_CALLBACKS;
|
||||
struct bufferevent *bev_ll[2] = { NULL, NULL };
|
||||
evutil_socket_t *fd_pair = NULL;
|
||||
|
||||
enum regress_openssl_type type;
|
||||
type = (enum regress_openssl_type)data->setup_data;
|
||||
|
||||
tt_assert(cert);
|
||||
tt_assert(key);
|
||||
|
||||
init_ssl();
|
||||
|
||||
if (strstr((char*)data->setup_data, "renegotiate")) {
|
||||
if (type & REGRESS_OPENSSL_RENEGOTIATE) {
|
||||
if (SSLeay() >= 0x10001000 &&
|
||||
SSLeay() < 0x1000104f) {
|
||||
/* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2
|
||||
@ -317,11 +395,11 @@ regress_bufferevent_openssl(void *arg)
|
||||
SSL_use_certificate(ssl2, cert);
|
||||
SSL_use_PrivateKey(ssl2, key);
|
||||
|
||||
if (! start_open)
|
||||
if (!(type & REGRESS_OPENSSL_OPEN))
|
||||
flags |= BEV_OPT_CLOSE_ON_FREE;
|
||||
|
||||
if (!filter) {
|
||||
tt_assert(strstr((char*)data->setup_data, "socketpair"));
|
||||
if (!(type & REGRESS_OPENSSL_FILTER)) {
|
||||
tt_assert(type & REGRESS_OPENSSL_SOCKETPAIR);
|
||||
fd_pair = data->pair;
|
||||
} else {
|
||||
bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0],
|
||||
@ -331,15 +409,15 @@ regress_bufferevent_openssl(void *arg)
|
||||
}
|
||||
|
||||
open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2,
|
||||
fd_pair, bev_ll);
|
||||
fd_pair, bev_ll, type);
|
||||
|
||||
if (!filter) {
|
||||
if (!(type & REGRESS_OPENSSL_FILTER)) {
|
||||
tt_int_op(bufferevent_getfd(bev1), ==, data->pair[0]);
|
||||
} else {
|
||||
tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]);
|
||||
}
|
||||
|
||||
if (start_open) {
|
||||
if (type & REGRESS_OPENSSL_OPEN) {
|
||||
pending_connect_events = 2;
|
||||
stop_when_connected = 1;
|
||||
exit_base = data->base;
|
||||
@ -351,23 +429,47 @@ regress_bufferevent_openssl(void *arg)
|
||||
bufferevent_free(bev2);
|
||||
bev1 = bev2 = NULL;
|
||||
open_ssl_bufevs(&bev1, &bev2, data->base, 1, flags, ssl1, ssl2,
|
||||
fd_pair, bev_ll);
|
||||
fd_pair, bev_ll, type);
|
||||
}
|
||||
|
||||
bufferevent_enable(bev1, EV_READ|EV_WRITE);
|
||||
bufferevent_enable(bev2, EV_READ|EV_WRITE);
|
||||
if (!(type & REGRESS_OPENSSL_TIMEOUT)) {
|
||||
bufferevent_enable(bev1, EV_READ|EV_WRITE);
|
||||
bufferevent_enable(bev2, EV_READ|EV_WRITE);
|
||||
|
||||
evbuffer_add_printf(bufferevent_get_output(bev1), "1\n");
|
||||
evbuffer_add_printf(bufferevent_get_output(bev1), "1\n");
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
event_base_dispatch(data->base);
|
||||
|
||||
tt_assert(test_is_done == 1);
|
||||
tt_assert(n_connected == 2);
|
||||
tt_assert(test_is_done == 1);
|
||||
tt_assert(n_connected == 2);
|
||||
|
||||
/* We don't handle shutdown properly yet.
|
||||
tt_int_op(got_close, ==, 1);
|
||||
tt_int_op(got_error, ==, 0);
|
||||
*/
|
||||
/* We don't handle shutdown properly yet */
|
||||
if (type & REGRESS_OPENSSL_DIRTY_SHUTDOWN) {
|
||||
tt_int_op(got_close, ==, 1);
|
||||
tt_int_op(got_error, ==, 0);
|
||||
} else {
|
||||
tt_int_op(got_error, ==, 1);
|
||||
}
|
||||
tt_int_op(got_timeout, ==, 0);
|
||||
} else {
|
||||
struct timeval t = { 2 };
|
||||
|
||||
bufferevent_enable(bev1, EV_READ|EV_WRITE);
|
||||
bufferevent_disable(bev2, EV_READ|EV_WRITE);
|
||||
|
||||
bufferevent_set_timeouts(bev1, &t, &t);
|
||||
|
||||
evbuffer_add_printf(bufferevent_get_output(bev1), "1\n");
|
||||
|
||||
event_base_dispatch(data->base);
|
||||
|
||||
tt_assert(test_is_done == 0);
|
||||
tt_assert(n_connected == 0);
|
||||
|
||||
tt_int_op(got_close, ==, 0);
|
||||
tt_int_op(got_error, ==, 0);
|
||||
tt_int_op(got_timeout, ==, 1);
|
||||
}
|
||||
end:
|
||||
return;
|
||||
}
|
||||
@ -391,7 +493,7 @@ acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
|
||||
BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
|
||||
|
||||
bufferevent_setcb(bev, respond_to_number, NULL, eventcb,
|
||||
(void*)"server");
|
||||
(void*)(REGRESS_OPENSSL_SERVER));
|
||||
|
||||
bufferevent_enable(bev, EV_READ|EV_WRITE);
|
||||
|
||||
@ -435,7 +537,7 @@ regress_bufferevent_openssl_connect(void *arg)
|
||||
tt_assert(bev);
|
||||
|
||||
bufferevent_setcb(bev, respond_to_number, NULL, eventcb,
|
||||
(void*)"client");
|
||||
(void*)(REGRESS_OPENSSL_CLIENT));
|
||||
|
||||
tt_assert(getsockname(evconnlistener_get_fd(listener),
|
||||
(struct sockaddr*)&ss, &slen) == 0);
|
||||
@ -453,22 +555,69 @@ end:
|
||||
}
|
||||
|
||||
struct testcase_t ssl_testcases[] = {
|
||||
|
||||
{ "bufferevent_socketpair", regress_bufferevent_openssl, TT_ISOLATED,
|
||||
&basic_setup, (void*)"socketpair" },
|
||||
#define T(a) ((void *)(a))
|
||||
{ "bufferevent_socketpair", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_SOCKETPAIR) },
|
||||
{ "bufferevent_filter", regress_bufferevent_openssl,
|
||||
TT_ISOLATED,
|
||||
&basic_setup, (void*)"filter" },
|
||||
TT_ISOLATED, &basic_setup, T(REGRESS_OPENSSL_FILTER) },
|
||||
{ "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl,
|
||||
TT_ISOLATED,
|
||||
&basic_setup, (void*)"socketpair renegotiate" },
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE) },
|
||||
{ "bufferevent_renegotiate_filter", regress_bufferevent_openssl,
|
||||
TT_ISOLATED,
|
||||
&basic_setup, (void*)"filter renegotiate" },
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE) },
|
||||
{ "bufferevent_socketpair_startopen", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup, (void*)"socketpair open" },
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN) },
|
||||
{ "bufferevent_filter_startopen", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup, (void*)"filter open" },
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN) },
|
||||
|
||||
{ "bufferevent_socketpair_dirty_shutdown", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_filter_dirty_shutdown", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_renegotiate_socketpair_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED,
|
||||
&basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_renegotiate_filter_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED,
|
||||
&basic_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_socketpair_startopen_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
{ "bufferevent_filter_startopen_dirty_shutdown",
|
||||
regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
|
||||
|
||||
{ "bufferevent_socketpair_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FD) },
|
||||
{ "bufferevent_socketpair_freed", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED) },
|
||||
{ "bufferevent_socketpair_freed_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
|
||||
{ "bufferevent_filter_freed_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
|
||||
|
||||
{ "bufferevent_socketpair_timeout", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT) },
|
||||
{ "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl,
|
||||
TT_ISOLATED, &basic_setup,
|
||||
T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
|
||||
#undef T
|
||||
|
||||
{ "bufferevent_connect", regress_bufferevent_openssl_connect,
|
||||
TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
|
||||
|
Loading…
x
Reference in New Issue
Block a user