12b15cb3dSCy Schubert /*
22b15cb3dSCy Schubert  * Copyright (c) 2009-2012 Niels Provos and Nick Mathewson
32b15cb3dSCy Schubert  *
42b15cb3dSCy Schubert  * Redistribution and use in source and binary forms, with or without
52b15cb3dSCy Schubert  * modification, are permitted provided that the following conditions
62b15cb3dSCy Schubert  * are met:
72b15cb3dSCy Schubert  * 1. Redistributions of source code must retain the above copyright
82b15cb3dSCy Schubert  *    notice, this list of conditions and the following disclaimer.
92b15cb3dSCy Schubert  * 2. Redistributions in binary form must reproduce the above copyright
102b15cb3dSCy Schubert  *    notice, this list of conditions and the following disclaimer in the
112b15cb3dSCy Schubert  *    documentation and/or other materials provided with the distribution.
122b15cb3dSCy Schubert  * 3. The name of the author may not be used to endorse or promote products
132b15cb3dSCy Schubert  *    derived from this software without specific prior written permission.
142b15cb3dSCy Schubert  *
152b15cb3dSCy Schubert  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
162b15cb3dSCy Schubert  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
172b15cb3dSCy Schubert  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
182b15cb3dSCy Schubert  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
192b15cb3dSCy Schubert  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
202b15cb3dSCy Schubert  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
212b15cb3dSCy Schubert  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
222b15cb3dSCy Schubert  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
232b15cb3dSCy Schubert  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
242b15cb3dSCy Schubert  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
252b15cb3dSCy Schubert  */
262b15cb3dSCy Schubert 
272b15cb3dSCy Schubert // Get rid of OSX 10.7 and greater deprecation warnings.
282b15cb3dSCy Schubert #if defined(__APPLE__) && defined(__clang__)
292b15cb3dSCy Schubert #pragma clang diagnostic ignored "-Wdeprecated-declarations"
302b15cb3dSCy Schubert #endif
312b15cb3dSCy Schubert 
322b15cb3dSCy Schubert #ifdef _WIN32
332b15cb3dSCy Schubert #include <winsock2.h>
342b15cb3dSCy Schubert #include <windows.h>
352b15cb3dSCy Schubert #endif
362b15cb3dSCy Schubert 
37*a466cc55SCy Schubert #include "util-internal.h"
38*a466cc55SCy Schubert 
392b15cb3dSCy Schubert #ifndef _WIN32
402b15cb3dSCy Schubert #include <sys/types.h>
412b15cb3dSCy Schubert #include <sys/socket.h>
422b15cb3dSCy Schubert #include <netinet/in.h>
432b15cb3dSCy Schubert #endif
442b15cb3dSCy Schubert 
452b15cb3dSCy Schubert #include "event2/util.h"
462b15cb3dSCy Schubert #include "event2/event.h"
472b15cb3dSCy Schubert #include "event2/bufferevent_ssl.h"
48*a466cc55SCy Schubert #include "event2/bufferevent_struct.h"
492b15cb3dSCy Schubert #include "event2/buffer.h"
502b15cb3dSCy Schubert #include "event2/listener.h"
512b15cb3dSCy Schubert 
522b15cb3dSCy Schubert #include "regress.h"
532b15cb3dSCy Schubert #include "tinytest.h"
542b15cb3dSCy Schubert #include "tinytest_macros.h"
552b15cb3dSCy Schubert 
562b15cb3dSCy Schubert #include <openssl/err.h>
572b15cb3dSCy Schubert #include <openssl/pem.h>
58*a466cc55SCy Schubert #include "openssl-compat.h"
592b15cb3dSCy Schubert 
602b15cb3dSCy Schubert #include <string.h>
61*a466cc55SCy Schubert #ifdef _WIN32
62*a466cc55SCy Schubert #include <io.h>
63*a466cc55SCy Schubert #define read _read
64*a466cc55SCy Schubert #define write _write
65*a466cc55SCy Schubert #else
66*a466cc55SCy Schubert #include <unistd.h>
67*a466cc55SCy Schubert #endif
682b15cb3dSCy Schubert 
69*a466cc55SCy Schubert /* A pre-generated key, to save the cost of doing an RSA key generation step
70*a466cc55SCy Schubert  * during the unit tests. It is published in this file, so you would have to
71*a466cc55SCy Schubert  * be very foolish to consider using it in your own code. */
722b15cb3dSCy Schubert static const char KEY[] =
732b15cb3dSCy Schubert     "-----BEGIN RSA PRIVATE KEY-----\n"
74*a466cc55SCy Schubert     "MIIEogIBAAKCAQEAtK07Ili0dkJb79m/sFmHoVJTWyLoveXex2yX/BtUzzcvZEOu\n"
75*a466cc55SCy Schubert     "QLon/++5YOA48kzZm5K9mIwZkZhui1ZgJ5Bjq0LGAWTZGIn+NXjLFshPYvTKpOCW\n"
76*a466cc55SCy Schubert     "uzL0Ir0LXMsBLYJQ5A4FomLNxs4I3H/dhDSGy/rSiJB1B4w2xNiwPK08/VL3zZqk\n"
77*a466cc55SCy Schubert     "V+GsSvGIIkzhTMbqPJy9K8pqyjwOU2pgORS794yXciTGxWYjTDzJPgQ35YMDATaG\n"
78*a466cc55SCy Schubert     "jr4HHo1zxU/Lj0pndSUK5rKLYxYQ3Uc8B3AVYDl9CP/GbOoQ4LBzS68JjcAUyp6i\n"
79*a466cc55SCy Schubert     "6NfXlc2D9S9XgqVqwI+JqgJs0eW/+zPY2UEDWwIDAQABAoIBAD2HzV66FOM9YDAD\n"
80*a466cc55SCy Schubert     "2RtGskEHV2nvLpIVadRCsFPkPvK+2X3s6rgSbbLkwh4y3lHuSCGKTNVZyQ9jeSos\n"
81*a466cc55SCy Schubert     "xVxT+Q2HFQW+gYyw2gj91TQyDY8mzKhv8AVaqff2p5r3a7RC8CdqexK9UVUGL9Bg\n"
82*a466cc55SCy Schubert     "H2F5vfpTtkVZ5PEoGDLblNFlMiMW/t1SobUeBVx+Msco/xqk9lFv1A9nnepGy0Gi\n"
83*a466cc55SCy Schubert     "D+i6YNGTBsX22YhoCZl/ICxCL8lgqPei4FvBr9dBVh/jQgjuUBm2jz55p2r7+7Aw\n"
84*a466cc55SCy Schubert     "khmXHReejoVokQ2+htgSgZNKlKuDy710ZpBqnDi8ynQi82Y2qCpyg/p/xcER54B6\n"
85*a466cc55SCy Schubert     "hSftaiECgYEA2RkSoxU+nWk+BClQEUZRi88QK5W/M8oo1DvUs36hvPFkw3Jk/gz0\n"
86*a466cc55SCy Schubert     "fgd5bnA+MXj0Fc0QHvbddPjIkyoI/evq9GPV+JYIuH5zabrlI3Jvya8q9QpAcEDO\n"
87*a466cc55SCy Schubert     "KkL/O09qXVEW52S6l05nh4PLejyI7aTyTIN5nbVLac/+M8MY/qOjZksCgYEA1Q1o\n"
88*a466cc55SCy Schubert     "L8kjSavU2xhQmSgZb9W62Do60sa3e73ljrDPoiyvbExldpSdziFYxHBD/Rep0ePf\n"
89*a466cc55SCy Schubert     "eVSGS3VSwevt9/jSGo2Oa83TYYns9agBm03oR/Go/DukESdI792NsEM+PRFypVNy\n"
90*a466cc55SCy Schubert     "AohWRLj0UU6DV+zLKp0VBavtx0ATeLFX0eN17TECgYBI2O/3Bz7uhQ0JSm+SjFz6\n"
91*a466cc55SCy Schubert     "o+2SInp5P2G57aWu4VQWWY3tQ2p+EQzNaWam10UXRrXoxtmc+ktPX9e2AgnoYoyB\n"
92*a466cc55SCy Schubert     "myqGcpnUhqHlnZAb999o9r1cYidDQ4uqhLauSTSwwXAFDzjJYsa8o03Y440y6QFh\n"
93*a466cc55SCy Schubert     "CVD6yYXXqLJs3g96CqDexwKBgAHxq1+0QCQt8zVElYewO/svQhMzBNJjic0RQIT6\n"
94*a466cc55SCy Schubert     "zAo4yij80XgxhvcYiszQEW6/xobpw2JCCS+rFGQ8mOFIXfJsFD6blDAxp/3d2JXo\n"
95*a466cc55SCy Schubert     "MhRl+hrDGI4ng5zcsqxHEMxR2m/zwPiQ8eiSn3gWdVBaEsiCwmxY00ScKxFQ3PJH\n"
96*a466cc55SCy Schubert     "Vw4hAoGAdZLd8KfjjG6lg7hfpVqavstqVi9LOgkHeCfdjn7JP+76kYrgLk/XdkrP\n"
97*a466cc55SCy Schubert     "N/BHhtFVFjOi/mTQfQ5YfZImkm/1ePBy7437DT8BDkOxspa50kK4HPggHnU64h1w\n"
98*a466cc55SCy Schubert     "lhdEOj7mAgHwGwwVZWOgs9Lq6vfztnSuhqjha1daESY6kDscPIQ=\n"
992b15cb3dSCy Schubert     "-----END RSA PRIVATE KEY-----\n";
1002b15cb3dSCy Schubert 
101*a466cc55SCy Schubert EVP_PKEY *
ssl_getkey(void)102*a466cc55SCy Schubert ssl_getkey(void)
1032b15cb3dSCy Schubert {
1042b15cb3dSCy Schubert 	EVP_PKEY *key;
1052b15cb3dSCy Schubert 	BIO *bio;
1062b15cb3dSCy Schubert 
1072b15cb3dSCy Schubert 	/* new read-only BIO backed by KEY. */
1082b15cb3dSCy Schubert 	bio = BIO_new_mem_buf((char*)KEY, -1);
1092b15cb3dSCy Schubert 	tt_assert(bio);
1102b15cb3dSCy Schubert 
1112b15cb3dSCy Schubert 	key = PEM_read_bio_PrivateKey(bio,NULL,NULL,NULL);
1122b15cb3dSCy Schubert 	BIO_free(bio);
1132b15cb3dSCy Schubert 	tt_assert(key);
1142b15cb3dSCy Schubert 
1152b15cb3dSCy Schubert 	return key;
1162b15cb3dSCy Schubert end:
1172b15cb3dSCy Schubert 	return NULL;
1182b15cb3dSCy Schubert }
1192b15cb3dSCy Schubert 
120*a466cc55SCy Schubert X509 *
ssl_getcert(EVP_PKEY * key)121*a466cc55SCy Schubert ssl_getcert(EVP_PKEY *key)
1222b15cb3dSCy Schubert {
1232b15cb3dSCy Schubert 	/* Dummy code to make a quick-and-dirty valid certificate with
1242b15cb3dSCy Schubert 	   OpenSSL.  Don't copy this code into your own program! It does a
1252b15cb3dSCy Schubert 	   number of things in a stupid and insecure way. */
1262b15cb3dSCy Schubert 	X509 *x509 = NULL;
1272b15cb3dSCy Schubert 	X509_NAME *name = NULL;
1282b15cb3dSCy Schubert 	int nid;
1292b15cb3dSCy Schubert 	time_t now = time(NULL);
1302b15cb3dSCy Schubert 
1312b15cb3dSCy Schubert 	tt_assert(key);
1322b15cb3dSCy Schubert 
1332b15cb3dSCy Schubert 	x509 = X509_new();
1342b15cb3dSCy Schubert 	tt_assert(x509);
1352b15cb3dSCy Schubert 	tt_assert(0 != X509_set_version(x509, 2));
1362b15cb3dSCy Schubert 	tt_assert(0 != ASN1_INTEGER_set(X509_get_serialNumber(x509),
1372b15cb3dSCy Schubert 		(long)now));
1382b15cb3dSCy Schubert 
1392b15cb3dSCy Schubert 	name = X509_NAME_new();
1402b15cb3dSCy Schubert 	tt_assert(name);
1412b15cb3dSCy Schubert 	nid = OBJ_txt2nid("commonName");
1422b15cb3dSCy Schubert 	tt_assert(NID_undef != nid);
1432b15cb3dSCy Schubert 	tt_assert(0 != X509_NAME_add_entry_by_NID(
1442b15cb3dSCy Schubert 		    name, nid, MBSTRING_ASC, (unsigned char*)"example.com",
1452b15cb3dSCy Schubert 		    -1, -1, 0));
1462b15cb3dSCy Schubert 
1472b15cb3dSCy Schubert 	X509_set_subject_name(x509, name);
1482b15cb3dSCy Schubert 	X509_set_issuer_name(x509, name);
149*a466cc55SCy Schubert 	X509_NAME_free(name);
1502b15cb3dSCy Schubert 
151f0574f5cSXin LI 	X509_time_adj(X509_getm_notBefore(x509), 0, &now);
152f0574f5cSXin LI 	now += 3600;
153f0574f5cSXin LI 	X509_time_adj(X509_getm_notAfter(x509), 0, &now);
1542b15cb3dSCy Schubert 	X509_set_pubkey(x509, key);
1552b15cb3dSCy Schubert 	tt_assert(0 != X509_sign(x509, key, EVP_sha1()));
1562b15cb3dSCy Schubert 
1572b15cb3dSCy Schubert 	return x509;
1582b15cb3dSCy Schubert end:
1592b15cb3dSCy Schubert 	X509_free(x509);
160*a466cc55SCy Schubert 	X509_NAME_free(name);
1612b15cb3dSCy Schubert 	return NULL;
1622b15cb3dSCy Schubert }
1632b15cb3dSCy Schubert 
1642b15cb3dSCy Schubert static int disable_tls_11_and_12 = 0;
1652b15cb3dSCy Schubert static SSL_CTX *the_ssl_ctx = NULL;
1662b15cb3dSCy Schubert 
167*a466cc55SCy Schubert SSL_CTX *
get_ssl_ctx(void)1682b15cb3dSCy Schubert get_ssl_ctx(void)
1692b15cb3dSCy Schubert {
1702b15cb3dSCy Schubert 	if (the_ssl_ctx)
1712b15cb3dSCy Schubert 		return the_ssl_ctx;
1722b15cb3dSCy Schubert 	the_ssl_ctx = SSL_CTX_new(SSLv23_method());
1732b15cb3dSCy Schubert 	if (!the_ssl_ctx)
1742b15cb3dSCy Schubert 		return NULL;
1752b15cb3dSCy Schubert 	if (disable_tls_11_and_12) {
1762b15cb3dSCy Schubert #ifdef SSL_OP_NO_TLSv1_2
1772b15cb3dSCy Schubert 		SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_2);
1782b15cb3dSCy Schubert #endif
1792b15cb3dSCy Schubert #ifdef SSL_OP_NO_TLSv1_1
1802b15cb3dSCy Schubert 		SSL_CTX_set_options(the_ssl_ctx, SSL_OP_NO_TLSv1_1);
1812b15cb3dSCy Schubert #endif
1822b15cb3dSCy Schubert 	}
1832b15cb3dSCy Schubert 	return the_ssl_ctx;
1842b15cb3dSCy Schubert }
1852b15cb3dSCy Schubert 
186*a466cc55SCy Schubert static int test_is_done;
187*a466cc55SCy Schubert static int n_connected;
188*a466cc55SCy Schubert static int got_close;
189*a466cc55SCy Schubert static int got_error;
190*a466cc55SCy Schubert static int got_timeout;
191*a466cc55SCy Schubert static int renegotiate_at = -1;
192*a466cc55SCy Schubert static int stop_when_connected;
193*a466cc55SCy Schubert static int pending_connect_events;
194*a466cc55SCy Schubert static struct event_base *exit_base;
195*a466cc55SCy Schubert static X509 *the_cert;
196*a466cc55SCy Schubert EVP_PKEY *the_key;
197*a466cc55SCy Schubert 
198*a466cc55SCy Schubert void
init_ssl(void)1992b15cb3dSCy Schubert init_ssl(void)
2002b15cb3dSCy Schubert {
201*a466cc55SCy Schubert #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || \
202*a466cc55SCy Schubert 	(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER < 0x20700000L)
2032b15cb3dSCy Schubert 	SSL_library_init();
2042b15cb3dSCy Schubert 	ERR_load_crypto_strings();
2052b15cb3dSCy Schubert 	SSL_load_error_strings();
2062b15cb3dSCy Schubert 	OpenSSL_add_all_algorithms();
207*a466cc55SCy Schubert 	if (SSLeay() != OPENSSL_VERSION_NUMBER) {
208*a466cc55SCy Schubert 		TT_DECLARE("WARN",
209*a466cc55SCy Schubert 			("Version mismatch for openssl: compiled with %lx but running with %lx",
210*a466cc55SCy Schubert 			(unsigned long)OPENSSL_VERSION_NUMBER, (unsigned long)SSLeay()));
2112b15cb3dSCy Schubert 	}
212*a466cc55SCy Schubert #endif
2132b15cb3dSCy Schubert }
2142b15cb3dSCy Schubert 
215*a466cc55SCy Schubert static void *
ssl_test_setup(const struct testcase_t * testcase)216*a466cc55SCy Schubert ssl_test_setup(const struct testcase_t *testcase)
217*a466cc55SCy Schubert {
218*a466cc55SCy Schubert 	init_ssl();
219*a466cc55SCy Schubert 
220*a466cc55SCy Schubert 	the_key = ssl_getkey();
221*a466cc55SCy Schubert 	EVUTIL_ASSERT(the_key);
222*a466cc55SCy Schubert 
223*a466cc55SCy Schubert 	the_cert = ssl_getcert(the_key);
224*a466cc55SCy Schubert 	EVUTIL_ASSERT(the_cert);
225*a466cc55SCy Schubert 
226*a466cc55SCy Schubert 	disable_tls_11_and_12 = 0;
227*a466cc55SCy Schubert 
228*a466cc55SCy Schubert 	return basic_test_setup(testcase);
229*a466cc55SCy Schubert }
230*a466cc55SCy Schubert static int
ssl_test_cleanup(const struct testcase_t * testcase,void * ptr)231*a466cc55SCy Schubert ssl_test_cleanup(const struct testcase_t *testcase, void *ptr)
232*a466cc55SCy Schubert {
233*a466cc55SCy Schubert 	int ret = basic_test_cleanup(testcase, ptr);
234*a466cc55SCy Schubert 	if (!ret) {
235*a466cc55SCy Schubert 		return ret;
236*a466cc55SCy Schubert 	}
237*a466cc55SCy Schubert 
238*a466cc55SCy Schubert 	test_is_done = 0;
239*a466cc55SCy Schubert 	n_connected = 0;
240*a466cc55SCy Schubert 	got_close = 0;
241*a466cc55SCy Schubert 	got_error = 0;
242*a466cc55SCy Schubert 	got_timeout = 0;
243*a466cc55SCy Schubert 	renegotiate_at = -1;
244*a466cc55SCy Schubert 	stop_when_connected = 0;
245*a466cc55SCy Schubert 	pending_connect_events = 0;
246*a466cc55SCy Schubert 	exit_base = NULL;
247*a466cc55SCy Schubert 
248*a466cc55SCy Schubert 	X509_free(the_cert);
249*a466cc55SCy Schubert 	EVP_PKEY_free(the_key);
250*a466cc55SCy Schubert 
251*a466cc55SCy Schubert 	SSL_CTX_free(the_ssl_ctx);
252*a466cc55SCy Schubert 	the_ssl_ctx = NULL;
253*a466cc55SCy Schubert 
254*a466cc55SCy Schubert 	return 1;
255*a466cc55SCy Schubert }
256*a466cc55SCy Schubert const struct testcase_setup_t ssl_setup = {
257*a466cc55SCy Schubert 	ssl_test_setup, ssl_test_cleanup
258*a466cc55SCy Schubert };
259*a466cc55SCy Schubert 
260*a466cc55SCy Schubert 
2612b15cb3dSCy Schubert /* ====================
2622b15cb3dSCy Schubert    Here's a simple test: we read a number from the input, increment it, and
2632b15cb3dSCy Schubert    reply, until we get to 1001.
2642b15cb3dSCy Schubert */
2652b15cb3dSCy Schubert 
266*a466cc55SCy Schubert enum regress_openssl_type
267*a466cc55SCy Schubert {
268*a466cc55SCy Schubert 	REGRESS_OPENSSL_SOCKETPAIR = 1,
269*a466cc55SCy Schubert 	REGRESS_OPENSSL_FILTER = 2,
270*a466cc55SCy Schubert 	REGRESS_OPENSSL_RENEGOTIATE = 4,
271*a466cc55SCy Schubert 	REGRESS_OPENSSL_OPEN = 8,
272*a466cc55SCy Schubert 	REGRESS_OPENSSL_DIRTY_SHUTDOWN = 16,
273*a466cc55SCy Schubert 	REGRESS_OPENSSL_FD = 32,
274*a466cc55SCy Schubert 
275*a466cc55SCy Schubert 	REGRESS_OPENSSL_CLIENT = 64,
276*a466cc55SCy Schubert 	REGRESS_OPENSSL_SERVER = 128,
277*a466cc55SCy Schubert 
278*a466cc55SCy Schubert 	REGRESS_OPENSSL_FREED = 256,
279*a466cc55SCy Schubert 	REGRESS_OPENSSL_TIMEOUT = 512,
280*a466cc55SCy Schubert 	REGRESS_OPENSSL_SLEEP = 1024,
281*a466cc55SCy Schubert 
282*a466cc55SCy Schubert 	REGRESS_OPENSSL_CLIENT_WRITE = 2048,
283*a466cc55SCy Schubert 
284*a466cc55SCy Schubert 	REGRESS_DEFERRED_CALLBACKS = 4096,
285*a466cc55SCy Schubert };
286*a466cc55SCy Schubert 
287*a466cc55SCy Schubert static void
bufferevent_openssl_check_fd(struct bufferevent * bev,int filter)288*a466cc55SCy Schubert bufferevent_openssl_check_fd(struct bufferevent *bev, int filter)
289*a466cc55SCy Schubert {
290*a466cc55SCy Schubert 	tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET);
291*a466cc55SCy Schubert 	tt_fd_op(bufferevent_setfd(bev, EVUTIL_INVALID_SOCKET), ==, 0);
292*a466cc55SCy Schubert 	if (filter) {
293*a466cc55SCy Schubert 		tt_fd_op(bufferevent_getfd(bev), !=, EVUTIL_INVALID_SOCKET);
294*a466cc55SCy Schubert 	} else {
295*a466cc55SCy Schubert 		tt_fd_op(bufferevent_getfd(bev), ==, EVUTIL_INVALID_SOCKET);
296*a466cc55SCy Schubert 	}
297*a466cc55SCy Schubert 
298*a466cc55SCy Schubert end:
299*a466cc55SCy Schubert 	;
300*a466cc55SCy Schubert }
301*a466cc55SCy Schubert static void
bufferevent_openssl_check_freed(struct bufferevent * bev)302*a466cc55SCy Schubert bufferevent_openssl_check_freed(struct bufferevent *bev)
303*a466cc55SCy Schubert {
304*a466cc55SCy Schubert 	tt_int_op(event_pending(&bev->ev_read, EVLIST_ALL, NULL), ==, 0);
305*a466cc55SCy Schubert 	tt_int_op(event_pending(&bev->ev_write, EVLIST_ALL, NULL), ==, 0);
306*a466cc55SCy Schubert 
307*a466cc55SCy Schubert end:
308*a466cc55SCy Schubert 	;
309*a466cc55SCy Schubert }
310*a466cc55SCy Schubert 
311*a466cc55SCy Schubert static void
free_on_cb(struct bufferevent * bev,void * ctx)312*a466cc55SCy Schubert free_on_cb(struct bufferevent *bev, void *ctx)
313*a466cc55SCy Schubert {
314*a466cc55SCy Schubert 	TT_BLATHER(("free_on_cb: %p", bev));
315*a466cc55SCy Schubert 	bufferevent_free(bev);
316*a466cc55SCy Schubert }
3172b15cb3dSCy Schubert 
3182b15cb3dSCy Schubert static void
respond_to_number(struct bufferevent * bev,void * ctx)3192b15cb3dSCy Schubert respond_to_number(struct bufferevent *bev, void *ctx)
3202b15cb3dSCy Schubert {
3212b15cb3dSCy Schubert 	struct evbuffer *b = bufferevent_get_input(bev);
3222b15cb3dSCy Schubert 	char *line;
3232b15cb3dSCy Schubert 	int n;
324*a466cc55SCy Schubert 
325*a466cc55SCy Schubert 	enum regress_openssl_type type;
326*a466cc55SCy Schubert 	type = (enum regress_openssl_type)ctx;
327*a466cc55SCy Schubert 
3282b15cb3dSCy Schubert 	line = evbuffer_readln(b, NULL, EVBUFFER_EOL_LF);
3292b15cb3dSCy Schubert 	if (! line)
3302b15cb3dSCy Schubert 		return;
3312b15cb3dSCy Schubert 	n = atoi(line);
3322b15cb3dSCy Schubert 	if (n <= 0)
3332b15cb3dSCy Schubert 		TT_FAIL(("Bad number: %s", line));
334a25439b6SCy Schubert 	free(line);
3352b15cb3dSCy Schubert 	TT_BLATHER(("The number was %d", n));
3362b15cb3dSCy Schubert 	if (n == 1001) {
3372b15cb3dSCy Schubert 		++test_is_done;
3382b15cb3dSCy Schubert 		bufferevent_free(bev); /* Should trigger close on other side. */
3392b15cb3dSCy Schubert 		return;
3402b15cb3dSCy Schubert 	}
341*a466cc55SCy Schubert 	if ((type & REGRESS_OPENSSL_CLIENT) && n == renegotiate_at) {
3422b15cb3dSCy Schubert 		SSL_renegotiate(bufferevent_openssl_get_ssl(bev));
3432b15cb3dSCy Schubert 	}
3442b15cb3dSCy Schubert 	++n;
3452b15cb3dSCy Schubert 	evbuffer_add_printf(bufferevent_get_output(bev),
3462b15cb3dSCy Schubert 	    "%d\n", n);
3472b15cb3dSCy Schubert 	TT_BLATHER(("Done reading; now writing."));
3482b15cb3dSCy Schubert 	bufferevent_enable(bev, EV_WRITE);
3492b15cb3dSCy Schubert 	bufferevent_disable(bev, EV_READ);
3502b15cb3dSCy Schubert }
3512b15cb3dSCy Schubert 
3522b15cb3dSCy Schubert static void
done_writing_cb(struct bufferevent * bev,void * ctx)3532b15cb3dSCy Schubert done_writing_cb(struct bufferevent *bev, void *ctx)
3542b15cb3dSCy Schubert {
3552b15cb3dSCy Schubert 	struct evbuffer *b = bufferevent_get_output(bev);
3562b15cb3dSCy Schubert 	if (evbuffer_get_length(b))
3572b15cb3dSCy Schubert 		return;
3582b15cb3dSCy Schubert 	TT_BLATHER(("Done writing."));
3592b15cb3dSCy Schubert 	bufferevent_disable(bev, EV_WRITE);
3602b15cb3dSCy Schubert 	bufferevent_enable(bev, EV_READ);
3612b15cb3dSCy Schubert }
3622b15cb3dSCy Schubert 
3632b15cb3dSCy Schubert static void
eventcb(struct bufferevent * bev,short what,void * ctx)3642b15cb3dSCy Schubert eventcb(struct bufferevent *bev, short what, void *ctx)
3652b15cb3dSCy Schubert {
366*a466cc55SCy Schubert 	X509 *peer_cert = NULL;
367*a466cc55SCy Schubert 	enum regress_openssl_type type;
368*a466cc55SCy Schubert 
369*a466cc55SCy Schubert 	type = (enum regress_openssl_type)ctx;
370*a466cc55SCy Schubert 
3712b15cb3dSCy Schubert 	TT_BLATHER(("Got event %d", (int)what));
3722b15cb3dSCy Schubert 	if (what & BEV_EVENT_CONNECTED) {
3732b15cb3dSCy Schubert 		SSL *ssl;
3742b15cb3dSCy Schubert 		++n_connected;
3752b15cb3dSCy Schubert 		ssl = bufferevent_openssl_get_ssl(bev);
3762b15cb3dSCy Schubert 		tt_assert(ssl);
3772b15cb3dSCy Schubert 		peer_cert = SSL_get_peer_certificate(ssl);
378*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_SERVER) {
3792b15cb3dSCy Schubert 			tt_assert(peer_cert == NULL);
3802b15cb3dSCy Schubert 		} else {
3812b15cb3dSCy Schubert 			tt_assert(peer_cert != NULL);
3822b15cb3dSCy Schubert 		}
3832b15cb3dSCy Schubert 		if (stop_when_connected) {
3842b15cb3dSCy Schubert 			if (--pending_connect_events == 0)
3852b15cb3dSCy Schubert 				event_base_loopexit(exit_base, NULL);
3862b15cb3dSCy Schubert 		}
387*a466cc55SCy Schubert 
388*a466cc55SCy Schubert 		if ((type & REGRESS_OPENSSL_CLIENT_WRITE) && (type & REGRESS_OPENSSL_CLIENT))
389*a466cc55SCy Schubert 			evbuffer_add_printf(bufferevent_get_output(bev), "1\n");
3902b15cb3dSCy Schubert 	} else if (what & BEV_EVENT_EOF) {
3912b15cb3dSCy Schubert 		TT_BLATHER(("Got a good EOF"));
3922b15cb3dSCy Schubert 		++got_close;
393*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_FD) {
394*a466cc55SCy Schubert 			bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
395*a466cc55SCy Schubert 		}
396*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_FREED) {
397*a466cc55SCy Schubert 			bufferevent_openssl_check_freed(bev);
398*a466cc55SCy Schubert 		}
3992b15cb3dSCy Schubert 		bufferevent_free(bev);
4002b15cb3dSCy Schubert 	} else if (what & BEV_EVENT_ERROR) {
4012b15cb3dSCy Schubert 		TT_BLATHER(("Got an error."));
4022b15cb3dSCy Schubert 		++got_error;
403*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_FD) {
404*a466cc55SCy Schubert 			bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
405*a466cc55SCy Schubert 		}
406*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_FREED) {
407*a466cc55SCy Schubert 			bufferevent_openssl_check_freed(bev);
408*a466cc55SCy Schubert 		}
409*a466cc55SCy Schubert 		bufferevent_free(bev);
410*a466cc55SCy Schubert 	} else if (what & BEV_EVENT_TIMEOUT) {
411*a466cc55SCy Schubert 		TT_BLATHER(("Got timeout."));
412*a466cc55SCy Schubert 		++got_timeout;
413*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_FD) {
414*a466cc55SCy Schubert 			bufferevent_openssl_check_fd(bev, type & REGRESS_OPENSSL_FILTER);
415*a466cc55SCy Schubert 		}
416*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_FREED) {
417*a466cc55SCy Schubert 			bufferevent_openssl_check_freed(bev);
418*a466cc55SCy Schubert 		}
4192b15cb3dSCy Schubert 		bufferevent_free(bev);
4202b15cb3dSCy Schubert 	}
421*a466cc55SCy Schubert 
4222b15cb3dSCy Schubert end:
423*a466cc55SCy Schubert 	if (peer_cert)
424*a466cc55SCy Schubert 		X509_free(peer_cert);
4252b15cb3dSCy Schubert }
4262b15cb3dSCy Schubert 
4272b15cb3dSCy Schubert 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,enum regress_openssl_type type)4282b15cb3dSCy Schubert open_ssl_bufevs(struct bufferevent **bev1_out, struct bufferevent **bev2_out,
4292b15cb3dSCy Schubert     struct event_base *base, int is_open, int flags, SSL *ssl1, SSL *ssl2,
430*a466cc55SCy Schubert     evutil_socket_t *fd_pair, struct bufferevent **underlying_pair,
431*a466cc55SCy Schubert     enum regress_openssl_type type)
4322b15cb3dSCy Schubert {
4332b15cb3dSCy Schubert 	int state1 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_CONNECTING;
4342b15cb3dSCy Schubert 	int state2 = is_open ? BUFFEREVENT_SSL_OPEN :BUFFEREVENT_SSL_ACCEPTING;
435*a466cc55SCy Schubert 	int dirty_shutdown = type & REGRESS_OPENSSL_DIRTY_SHUTDOWN;
4362b15cb3dSCy Schubert 	if (fd_pair) {
4372b15cb3dSCy Schubert 		*bev1_out = bufferevent_openssl_socket_new(
4382b15cb3dSCy Schubert 			base, fd_pair[0], ssl1, state1, flags);
4392b15cb3dSCy Schubert 		*bev2_out = bufferevent_openssl_socket_new(
4402b15cb3dSCy Schubert 			base, fd_pair[1], ssl2, state2, flags);
4412b15cb3dSCy Schubert 	} else {
4422b15cb3dSCy Schubert 		*bev1_out = bufferevent_openssl_filter_new(
4432b15cb3dSCy Schubert 			base, underlying_pair[0], ssl1, state1, flags);
4442b15cb3dSCy Schubert 		*bev2_out = bufferevent_openssl_filter_new(
4452b15cb3dSCy Schubert 			base, underlying_pair[1], ssl2, state2, flags);
4462b15cb3dSCy Schubert 
4472b15cb3dSCy Schubert 	}
4482b15cb3dSCy Schubert 	bufferevent_setcb(*bev1_out, respond_to_number, done_writing_cb,
449*a466cc55SCy Schubert 	    eventcb, (void*)(REGRESS_OPENSSL_CLIENT | (long)type));
4502b15cb3dSCy Schubert 	bufferevent_setcb(*bev2_out, respond_to_number, done_writing_cb,
451*a466cc55SCy Schubert 	    eventcb, (void*)(REGRESS_OPENSSL_SERVER | (long)type));
452*a466cc55SCy Schubert 
453*a466cc55SCy Schubert 	bufferevent_openssl_set_allow_dirty_shutdown(*bev1_out, dirty_shutdown);
454*a466cc55SCy Schubert 	bufferevent_openssl_set_allow_dirty_shutdown(*bev2_out, dirty_shutdown);
4552b15cb3dSCy Schubert }
4562b15cb3dSCy Schubert 
4572b15cb3dSCy Schubert static void
regress_bufferevent_openssl(void * arg)4582b15cb3dSCy Schubert regress_bufferevent_openssl(void *arg)
4592b15cb3dSCy Schubert {
4602b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
4612b15cb3dSCy Schubert 
4622b15cb3dSCy Schubert 	struct bufferevent *bev1, *bev2;
4632b15cb3dSCy Schubert 	SSL *ssl1, *ssl2;
4642b15cb3dSCy Schubert 	int flags = BEV_OPT_DEFER_CALLBACKS;
4652b15cb3dSCy Schubert 	struct bufferevent *bev_ll[2] = { NULL, NULL };
4662b15cb3dSCy Schubert 	evutil_socket_t *fd_pair = NULL;
4672b15cb3dSCy Schubert 
468*a466cc55SCy Schubert 	enum regress_openssl_type type;
469*a466cc55SCy Schubert 	type = (enum regress_openssl_type)data->setup_data;
4702b15cb3dSCy Schubert 
471*a466cc55SCy Schubert 	if (type & REGRESS_OPENSSL_RENEGOTIATE) {
472*a466cc55SCy Schubert 		if (OPENSSL_VERSION_NUMBER >= 0x10001000 &&
473*a466cc55SCy Schubert 		    OPENSSL_VERSION_NUMBER <  0x1000104f) {
4742b15cb3dSCy Schubert 			/* 1.0.1 up to 1.0.1c has a bug where TLS1.1 and 1.2
4752b15cb3dSCy Schubert 			 * can't renegotiate with themselves. Disable. */
4762b15cb3dSCy Schubert 			disable_tls_11_and_12 = 1;
4772b15cb3dSCy Schubert 		}
4782b15cb3dSCy Schubert 		renegotiate_at = 600;
4792b15cb3dSCy Schubert 	}
4802b15cb3dSCy Schubert 
4812b15cb3dSCy Schubert 	ssl1 = SSL_new(get_ssl_ctx());
4822b15cb3dSCy Schubert 	ssl2 = SSL_new(get_ssl_ctx());
4832b15cb3dSCy Schubert 
484*a466cc55SCy Schubert 	SSL_use_certificate(ssl2, the_cert);
485*a466cc55SCy Schubert 	SSL_use_PrivateKey(ssl2, the_key);
4862b15cb3dSCy Schubert 
487*a466cc55SCy Schubert 	if (!(type & REGRESS_OPENSSL_OPEN))
4882b15cb3dSCy Schubert 		flags |= BEV_OPT_CLOSE_ON_FREE;
4892b15cb3dSCy Schubert 
490*a466cc55SCy Schubert 	if (!(type & REGRESS_OPENSSL_FILTER)) {
491*a466cc55SCy Schubert 		tt_assert(type & REGRESS_OPENSSL_SOCKETPAIR);
4922b15cb3dSCy Schubert 		fd_pair = data->pair;
4932b15cb3dSCy Schubert 	} else {
4942b15cb3dSCy Schubert 		bev_ll[0] = bufferevent_socket_new(data->base, data->pair[0],
4952b15cb3dSCy Schubert 		    BEV_OPT_CLOSE_ON_FREE);
4962b15cb3dSCy Schubert 		bev_ll[1] = bufferevent_socket_new(data->base, data->pair[1],
4972b15cb3dSCy Schubert 		    BEV_OPT_CLOSE_ON_FREE);
4982b15cb3dSCy Schubert 	}
4992b15cb3dSCy Schubert 
5002b15cb3dSCy Schubert 	open_ssl_bufevs(&bev1, &bev2, data->base, 0, flags, ssl1, ssl2,
501*a466cc55SCy Schubert 	    fd_pair, bev_ll, type);
5022b15cb3dSCy Schubert 
503*a466cc55SCy Schubert 	if (!(type & REGRESS_OPENSSL_FILTER)) {
504*a466cc55SCy Schubert 		tt_fd_op(bufferevent_getfd(bev1), ==, data->pair[0]);
5052b15cb3dSCy Schubert 	} else {
5062b15cb3dSCy Schubert 		tt_ptr_op(bufferevent_get_underlying(bev1), ==, bev_ll[0]);
5072b15cb3dSCy Schubert 	}
5082b15cb3dSCy Schubert 
509*a466cc55SCy Schubert 	if (type & REGRESS_OPENSSL_OPEN) {
5102b15cb3dSCy Schubert 		pending_connect_events = 2;
5112b15cb3dSCy Schubert 		stop_when_connected = 1;
5122b15cb3dSCy Schubert 		exit_base = data->base;
5132b15cb3dSCy Schubert 		event_base_dispatch(data->base);
5142b15cb3dSCy Schubert 		/* Okay, now the renegotiation is done.  Make new
5152b15cb3dSCy Schubert 		 * bufferevents to test opening in BUFFEREVENT_SSL_OPEN */
5162b15cb3dSCy Schubert 		flags |= BEV_OPT_CLOSE_ON_FREE;
5172b15cb3dSCy Schubert 		bufferevent_free(bev1);
5182b15cb3dSCy Schubert 		bufferevent_free(bev2);
5192b15cb3dSCy Schubert 		bev1 = bev2 = NULL;
5202b15cb3dSCy Schubert 		open_ssl_bufevs(&bev1, &bev2, data->base, 1, flags, ssl1, ssl2,
521*a466cc55SCy Schubert 		    fd_pair, bev_ll, type);
5222b15cb3dSCy Schubert 	}
5232b15cb3dSCy Schubert 
524*a466cc55SCy Schubert 	if (!(type & REGRESS_OPENSSL_TIMEOUT)) {
5252b15cb3dSCy Schubert 		bufferevent_enable(bev1, EV_READ|EV_WRITE);
5262b15cb3dSCy Schubert 		bufferevent_enable(bev2, EV_READ|EV_WRITE);
5272b15cb3dSCy Schubert 
528*a466cc55SCy Schubert 		if (!(type & REGRESS_OPENSSL_CLIENT_WRITE))
5292b15cb3dSCy Schubert 			evbuffer_add_printf(bufferevent_get_output(bev1), "1\n");
5302b15cb3dSCy Schubert 
5312b15cb3dSCy Schubert 		event_base_dispatch(data->base);
5322b15cb3dSCy Schubert 
5332b15cb3dSCy Schubert 		tt_assert(test_is_done == 1);
5342b15cb3dSCy Schubert 		tt_assert(n_connected == 2);
5352b15cb3dSCy Schubert 
536*a466cc55SCy Schubert 		/* We don't handle shutdown properly yet */
537*a466cc55SCy Schubert 		if (type & REGRESS_OPENSSL_DIRTY_SHUTDOWN) {
5382b15cb3dSCy Schubert 			tt_int_op(got_close, ==, 1);
5392b15cb3dSCy Schubert 			tt_int_op(got_error, ==, 0);
540*a466cc55SCy Schubert 		} else {
541*a466cc55SCy Schubert 			tt_int_op(got_error, ==, 1);
542*a466cc55SCy Schubert 		}
543*a466cc55SCy Schubert 		tt_int_op(got_timeout, ==, 0);
544*a466cc55SCy Schubert 	} else {
545*a466cc55SCy Schubert 		struct timeval t = { 2, 0 };
546*a466cc55SCy Schubert 
547*a466cc55SCy Schubert 		bufferevent_enable(bev1, EV_READ|EV_WRITE);
548*a466cc55SCy Schubert 		bufferevent_disable(bev2, EV_READ|EV_WRITE);
549*a466cc55SCy Schubert 
550*a466cc55SCy Schubert 		bufferevent_set_timeouts(bev1, &t, &t);
551*a466cc55SCy Schubert 
552*a466cc55SCy Schubert 		if (!(type & REGRESS_OPENSSL_CLIENT_WRITE))
553*a466cc55SCy Schubert 			evbuffer_add_printf(bufferevent_get_output(bev1), "1\n");
554*a466cc55SCy Schubert 
555*a466cc55SCy Schubert 		event_base_dispatch(data->base);
556*a466cc55SCy Schubert 
557*a466cc55SCy Schubert 		tt_assert(test_is_done == 0);
558*a466cc55SCy Schubert 		tt_assert(n_connected == 0);
559*a466cc55SCy Schubert 
560*a466cc55SCy Schubert 		tt_int_op(got_close, ==, 0);
561*a466cc55SCy Schubert 		tt_int_op(got_error, ==, 0);
562*a466cc55SCy Schubert 		tt_int_op(got_timeout, ==, 1);
563*a466cc55SCy Schubert 
564*a466cc55SCy Schubert 		bufferevent_free(bev2);
565*a466cc55SCy Schubert 	}
566*a466cc55SCy Schubert 
5672b15cb3dSCy Schubert end:
5682b15cb3dSCy Schubert 	return;
5692b15cb3dSCy Schubert }
5702b15cb3dSCy Schubert 
5712b15cb3dSCy Schubert static void
acceptcb_deferred(evutil_socket_t fd,short events,void * arg)572*a466cc55SCy Schubert acceptcb_deferred(evutil_socket_t fd, short events, void *arg)
573*a466cc55SCy Schubert {
574*a466cc55SCy Schubert 	struct bufferevent *bev = arg;
575*a466cc55SCy Schubert 	bufferevent_enable(bev, EV_READ|EV_WRITE);
576*a466cc55SCy Schubert }
577*a466cc55SCy Schubert static void
acceptcb(struct evconnlistener * listener,evutil_socket_t fd,struct sockaddr * addr,int socklen,void * arg)5782b15cb3dSCy Schubert acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
5792b15cb3dSCy Schubert     struct sockaddr *addr, int socklen, void *arg)
5802b15cb3dSCy Schubert {
5812b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
5822b15cb3dSCy Schubert 	struct bufferevent *bev;
583*a466cc55SCy Schubert 	enum regress_openssl_type type;
5842b15cb3dSCy Schubert 	SSL *ssl = SSL_new(get_ssl_ctx());
5852b15cb3dSCy Schubert 
586*a466cc55SCy Schubert 	type = (enum regress_openssl_type)data->setup_data;
587*a466cc55SCy Schubert 
588*a466cc55SCy Schubert 	SSL_use_certificate(ssl, the_cert);
589*a466cc55SCy Schubert 	SSL_use_PrivateKey(ssl, the_key);
5902b15cb3dSCy Schubert 
5912b15cb3dSCy Schubert 	bev = bufferevent_openssl_socket_new(
592*a466cc55SCy Schubert 		data->base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING,
5932b15cb3dSCy Schubert 		BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
594*a466cc55SCy Schubert 	tt_assert(bev);
5952b15cb3dSCy Schubert 
5962b15cb3dSCy Schubert 	bufferevent_setcb(bev, respond_to_number, NULL, eventcb,
597*a466cc55SCy Schubert 	    (void*)(REGRESS_OPENSSL_SERVER));
5982b15cb3dSCy Schubert 
599*a466cc55SCy Schubert 	if (type & REGRESS_OPENSSL_SLEEP) {
600*a466cc55SCy Schubert 		struct timeval when = { 1, 0 };
601*a466cc55SCy Schubert 		event_base_once(data->base, -1, EV_TIMEOUT,
602*a466cc55SCy Schubert 		    acceptcb_deferred, bev, &when);
603*a466cc55SCy Schubert 		bufferevent_disable(bev, EV_READ|EV_WRITE);
604*a466cc55SCy Schubert 	} else {
6052b15cb3dSCy Schubert 		bufferevent_enable(bev, EV_READ|EV_WRITE);
606*a466cc55SCy Schubert 	}
6072b15cb3dSCy Schubert 
6082b15cb3dSCy Schubert 	/* Only accept once, then disable ourself. */
6092b15cb3dSCy Schubert 	evconnlistener_disable(listener);
610*a466cc55SCy Schubert 
611*a466cc55SCy Schubert end:
612*a466cc55SCy Schubert 	;
613*a466cc55SCy Schubert }
614*a466cc55SCy Schubert 
615*a466cc55SCy Schubert struct rwcount
616*a466cc55SCy Schubert {
617*a466cc55SCy Schubert 	evutil_socket_t fd;
618*a466cc55SCy Schubert 	size_t read;
619*a466cc55SCy Schubert 	size_t write;
620*a466cc55SCy Schubert };
621*a466cc55SCy Schubert static int
bio_rwcount_new(BIO * b)622*a466cc55SCy Schubert bio_rwcount_new(BIO *b)
623*a466cc55SCy Schubert {
624*a466cc55SCy Schubert 	BIO_set_init(b, 0);
625*a466cc55SCy Schubert 	BIO_set_data(b, NULL);
626*a466cc55SCy Schubert 	return 1;
627*a466cc55SCy Schubert }
628*a466cc55SCy Schubert static int
bio_rwcount_free(BIO * b)629*a466cc55SCy Schubert bio_rwcount_free(BIO *b)
630*a466cc55SCy Schubert {
631*a466cc55SCy Schubert 	TT_BLATHER(("bio_rwcount_free: %p", b));
632*a466cc55SCy Schubert 	if (!b)
633*a466cc55SCy Schubert 		return 0;
634*a466cc55SCy Schubert 	if (BIO_get_shutdown(b)) {
635*a466cc55SCy Schubert 		BIO_set_init(b, 0);
636*a466cc55SCy Schubert 		BIO_set_data(b, NULL);
637*a466cc55SCy Schubert 	}
638*a466cc55SCy Schubert 	return 1;
639*a466cc55SCy Schubert }
640*a466cc55SCy Schubert static int
bio_rwcount_read(BIO * b,char * out,int outlen)641*a466cc55SCy Schubert bio_rwcount_read(BIO *b, char *out, int outlen)
642*a466cc55SCy Schubert {
643*a466cc55SCy Schubert 	struct rwcount *rw = BIO_get_data(b);
644*a466cc55SCy Schubert 	ev_ssize_t ret = recv(rw->fd, out, outlen, 0);
645*a466cc55SCy Schubert 	++rw->read;
646*a466cc55SCy Schubert 	if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
647*a466cc55SCy Schubert 		BIO_set_retry_read(b);
648*a466cc55SCy Schubert 	}
649*a466cc55SCy Schubert 	return ret;
650*a466cc55SCy Schubert }
651*a466cc55SCy Schubert static int
bio_rwcount_write(BIO * b,const char * in,int inlen)652*a466cc55SCy Schubert bio_rwcount_write(BIO *b, const char *in, int inlen)
653*a466cc55SCy Schubert {
654*a466cc55SCy Schubert 	struct rwcount *rw = BIO_get_data(b);
655*a466cc55SCy Schubert 	ev_ssize_t ret = send(rw->fd, in, inlen, 0);
656*a466cc55SCy Schubert 	++rw->write;
657*a466cc55SCy Schubert 	if (ret == -1 && EVUTIL_ERR_RW_RETRIABLE(EVUTIL_SOCKET_ERROR())) {
658*a466cc55SCy Schubert 		BIO_set_retry_write(b);
659*a466cc55SCy Schubert 	}
660*a466cc55SCy Schubert 	return ret;
661*a466cc55SCy Schubert }
662*a466cc55SCy Schubert static long
bio_rwcount_ctrl(BIO * b,int cmd,long num,void * ptr)663*a466cc55SCy Schubert bio_rwcount_ctrl(BIO *b, int cmd, long num, void *ptr)
664*a466cc55SCy Schubert {
665*a466cc55SCy Schubert 	struct rwcount *rw = BIO_get_data(b);
666*a466cc55SCy Schubert 	long ret = 0;
667*a466cc55SCy Schubert 	switch (cmd) {
668*a466cc55SCy Schubert 	case BIO_C_GET_FD:
669*a466cc55SCy Schubert 		ret = rw->fd;
670*a466cc55SCy Schubert 		break;
671*a466cc55SCy Schubert 	case BIO_CTRL_GET_CLOSE:
672*a466cc55SCy Schubert 		ret = BIO_get_shutdown(b);
673*a466cc55SCy Schubert 		break;
674*a466cc55SCy Schubert 	case BIO_CTRL_SET_CLOSE:
675*a466cc55SCy Schubert 		BIO_set_shutdown(b, (int)num);
676*a466cc55SCy Schubert 		break;
677*a466cc55SCy Schubert 	case BIO_CTRL_PENDING:
678*a466cc55SCy Schubert 		ret = 0;
679*a466cc55SCy Schubert 		break;
680*a466cc55SCy Schubert 	case BIO_CTRL_WPENDING:
681*a466cc55SCy Schubert 		ret = 0;
682*a466cc55SCy Schubert 		break;
683*a466cc55SCy Schubert 	case BIO_CTRL_DUP:
684*a466cc55SCy Schubert 	case BIO_CTRL_FLUSH:
685*a466cc55SCy Schubert 		ret = 1;
686*a466cc55SCy Schubert 		break;
687*a466cc55SCy Schubert 	}
688*a466cc55SCy Schubert 	return ret;
689*a466cc55SCy Schubert }
690*a466cc55SCy Schubert static int
bio_rwcount_puts(BIO * b,const char * s)691*a466cc55SCy Schubert bio_rwcount_puts(BIO *b, const char *s)
692*a466cc55SCy Schubert {
693*a466cc55SCy Schubert 	return bio_rwcount_write(b, s, strlen(s));
694*a466cc55SCy Schubert }
695*a466cc55SCy Schubert #define BIO_TYPE_LIBEVENT_RWCOUNT 0xff1
696*a466cc55SCy Schubert static BIO_METHOD *methods_rwcount;
697*a466cc55SCy Schubert 
698*a466cc55SCy Schubert static BIO_METHOD *
BIO_s_rwcount(void)699*a466cc55SCy Schubert BIO_s_rwcount(void)
700*a466cc55SCy Schubert {
701*a466cc55SCy Schubert 	if (methods_rwcount == NULL) {
702*a466cc55SCy Schubert 		methods_rwcount = BIO_meth_new(BIO_TYPE_LIBEVENT_RWCOUNT, "rwcount");
703*a466cc55SCy Schubert 		if (methods_rwcount == NULL)
704*a466cc55SCy Schubert 			return NULL;
705*a466cc55SCy Schubert 		BIO_meth_set_write(methods_rwcount, bio_rwcount_write);
706*a466cc55SCy Schubert 		BIO_meth_set_read(methods_rwcount, bio_rwcount_read);
707*a466cc55SCy Schubert 		BIO_meth_set_puts(methods_rwcount, bio_rwcount_puts);
708*a466cc55SCy Schubert 		BIO_meth_set_ctrl(methods_rwcount, bio_rwcount_ctrl);
709*a466cc55SCy Schubert 		BIO_meth_set_create(methods_rwcount, bio_rwcount_new);
710*a466cc55SCy Schubert 		BIO_meth_set_destroy(methods_rwcount, bio_rwcount_free);
711*a466cc55SCy Schubert 	}
712*a466cc55SCy Schubert 	return methods_rwcount;
713*a466cc55SCy Schubert }
714*a466cc55SCy Schubert static BIO *
BIO_new_rwcount(int close_flag)715*a466cc55SCy Schubert BIO_new_rwcount(int close_flag)
716*a466cc55SCy Schubert {
717*a466cc55SCy Schubert 	BIO *result;
718*a466cc55SCy Schubert 	if (!(result = BIO_new(BIO_s_rwcount())))
719*a466cc55SCy Schubert 		return NULL;
720*a466cc55SCy Schubert 	BIO_set_init(result, 1);
721*a466cc55SCy Schubert 	BIO_set_data(result,  NULL);
722*a466cc55SCy Schubert 	BIO_set_shutdown(result, !!close_flag);
723*a466cc55SCy Schubert 	return result;
7242b15cb3dSCy Schubert }
7252b15cb3dSCy Schubert 
7262b15cb3dSCy Schubert static void
regress_bufferevent_openssl_connect(void * arg)7272b15cb3dSCy Schubert regress_bufferevent_openssl_connect(void *arg)
7282b15cb3dSCy Schubert {
7292b15cb3dSCy Schubert 	struct basic_test_data *data = arg;
7302b15cb3dSCy Schubert 
7312b15cb3dSCy Schubert 	struct event_base *base = data->base;
7322b15cb3dSCy Schubert 
7332b15cb3dSCy Schubert 	struct evconnlistener *listener;
7342b15cb3dSCy Schubert 	struct bufferevent *bev;
7352b15cb3dSCy Schubert 	struct sockaddr_in sin;
7362b15cb3dSCy Schubert 	struct sockaddr_storage ss;
7372b15cb3dSCy Schubert 	ev_socklen_t slen;
738*a466cc55SCy Schubert 	SSL *ssl;
739*a466cc55SCy Schubert 	struct rwcount rw = { -1, 0, 0 };
740*a466cc55SCy Schubert 	enum regress_openssl_type type;
7412b15cb3dSCy Schubert 
742*a466cc55SCy Schubert 	type = (enum regress_openssl_type)data->setup_data;
7432b15cb3dSCy Schubert 
7442b15cb3dSCy Schubert 	memset(&sin, 0, sizeof(sin));
7452b15cb3dSCy Schubert 	sin.sin_family = AF_INET;
7462b15cb3dSCy Schubert 	sin.sin_addr.s_addr = htonl(0x7f000001);
7472b15cb3dSCy Schubert 
7482b15cb3dSCy Schubert 	memset(&ss, 0, sizeof(ss));
7492b15cb3dSCy Schubert 	slen = sizeof(ss);
7502b15cb3dSCy Schubert 
7512b15cb3dSCy Schubert 	listener = evconnlistener_new_bind(base, acceptcb, data,
7522b15cb3dSCy Schubert 	    LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
7532b15cb3dSCy Schubert 	    -1, (struct sockaddr *)&sin, sizeof(sin));
7542b15cb3dSCy Schubert 
7552b15cb3dSCy Schubert 	tt_assert(listener);
7562b15cb3dSCy Schubert 	tt_assert(evconnlistener_get_fd(listener) >= 0);
7572b15cb3dSCy Schubert 
758*a466cc55SCy Schubert 	ssl = SSL_new(get_ssl_ctx());
759*a466cc55SCy Schubert 	tt_assert(ssl);
760*a466cc55SCy Schubert 
7612b15cb3dSCy Schubert 	bev = bufferevent_openssl_socket_new(
762*a466cc55SCy Schubert 		data->base, -1, ssl,
7632b15cb3dSCy Schubert 		BUFFEREVENT_SSL_CONNECTING,
7642b15cb3dSCy Schubert 		BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS);
7652b15cb3dSCy Schubert 	tt_assert(bev);
7662b15cb3dSCy Schubert 
767*a466cc55SCy Schubert 	bufferevent_setcb(bev, respond_to_number, free_on_cb, eventcb,
768*a466cc55SCy Schubert 	    (void*)(REGRESS_OPENSSL_CLIENT));
7692b15cb3dSCy Schubert 
7702b15cb3dSCy Schubert 	tt_assert(getsockname(evconnlistener_get_fd(listener),
7712b15cb3dSCy Schubert 		(struct sockaddr*)&ss, &slen) == 0);
7722b15cb3dSCy Schubert 	tt_assert(slen == sizeof(struct sockaddr_in));
7732b15cb3dSCy Schubert 	tt_int_op(((struct sockaddr*)&ss)->sa_family, ==, AF_INET);
7742b15cb3dSCy Schubert 
7752b15cb3dSCy Schubert 	tt_assert(0 ==
7762b15cb3dSCy Schubert 	    bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen));
777*a466cc55SCy Schubert 	/* Possible only when we have fd, since be_openssl can and will overwrite
778*a466cc55SCy Schubert 	 * bio otherwise before */
779*a466cc55SCy Schubert 	if (type & REGRESS_OPENSSL_SLEEP) {
780*a466cc55SCy Schubert 		BIO *bio;
781*a466cc55SCy Schubert 
782*a466cc55SCy Schubert 		rw.fd = bufferevent_getfd(bev);
783*a466cc55SCy Schubert 		bio = BIO_new_rwcount(0);
784*a466cc55SCy Schubert 		tt_assert(bio);
785*a466cc55SCy Schubert 		BIO_set_data(bio, &rw);
786*a466cc55SCy Schubert 		SSL_set_bio(ssl, bio, bio);
787*a466cc55SCy Schubert 	}
7882b15cb3dSCy Schubert 	evbuffer_add_printf(bufferevent_get_output(bev), "1\n");
7892b15cb3dSCy Schubert 	bufferevent_enable(bev, EV_READ|EV_WRITE);
7902b15cb3dSCy Schubert 
7912b15cb3dSCy Schubert 	event_base_dispatch(base);
792*a466cc55SCy Schubert 
793*a466cc55SCy Schubert 	tt_int_op(rw.read, <=, 100);
794*a466cc55SCy Schubert 	tt_int_op(rw.write, <=, 100);
7952b15cb3dSCy Schubert end:
796*a466cc55SCy Schubert 	evconnlistener_free(listener);
797*a466cc55SCy Schubert }
798*a466cc55SCy Schubert 
799*a466cc55SCy Schubert struct wm_context
800*a466cc55SCy Schubert {
801*a466cc55SCy Schubert 	int server;
802*a466cc55SCy Schubert 	int flags;
803*a466cc55SCy Schubert 	struct evbuffer *data;
804*a466cc55SCy Schubert 	size_t to_read;
805*a466cc55SCy Schubert 	size_t wm_high;
806*a466cc55SCy Schubert 	size_t limit;
807*a466cc55SCy Schubert 	size_t get;
808*a466cc55SCy Schubert 	struct bufferevent *bev;
809*a466cc55SCy Schubert 	struct wm_context *neighbour;
810*a466cc55SCy Schubert };
811*a466cc55SCy Schubert static void
wm_transfer(struct bufferevent * bev,void * arg)812*a466cc55SCy Schubert wm_transfer(struct bufferevent *bev, void *arg)
813*a466cc55SCy Schubert {
814*a466cc55SCy Schubert 	struct wm_context *ctx = arg;
815*a466cc55SCy Schubert 	struct evbuffer *in  = bufferevent_get_input(bev);
816*a466cc55SCy Schubert 	struct evbuffer *out = bufferevent_get_output(bev);
817*a466cc55SCy Schubert 	size_t len = evbuffer_get_length(in);
818*a466cc55SCy Schubert 	size_t drain = len < ctx->to_read ? len : ctx->to_read;
819*a466cc55SCy Schubert 
820*a466cc55SCy Schubert 	if (ctx->get >= ctx->limit) {
821*a466cc55SCy Schubert 		TT_BLATHER(("wm_transfer-%s(%p): break",
822*a466cc55SCy Schubert 			ctx->server ? "server" : "client", bev));
823*a466cc55SCy Schubert 		bufferevent_setcb(bev, NULL, NULL, NULL, NULL);
824*a466cc55SCy Schubert 		bufferevent_disable(bev, EV_READ);
825*a466cc55SCy Schubert 		if (ctx->neighbour->get >= ctx->neighbour->limit) {
826*a466cc55SCy Schubert 			event_base_loopbreak(bufferevent_get_base(bev));
827*a466cc55SCy Schubert 		}
828*a466cc55SCy Schubert 	} else {
829*a466cc55SCy Schubert 		ctx->get += drain;
830*a466cc55SCy Schubert 		evbuffer_drain(in, drain);
831*a466cc55SCy Schubert 	}
832*a466cc55SCy Schubert 
833*a466cc55SCy Schubert 	TT_BLATHER(("wm_transfer-%s(%p): "
834*a466cc55SCy Schubert 		"in: " EV_SIZE_FMT ", "
835*a466cc55SCy Schubert 		"out: " EV_SIZE_FMT ", "
836*a466cc55SCy Schubert 		"got: " EV_SIZE_FMT "",
837*a466cc55SCy Schubert 		ctx->server ? "server" : "client", bev,
838*a466cc55SCy Schubert 		evbuffer_get_length(in),
839*a466cc55SCy Schubert 		evbuffer_get_length(out),
840*a466cc55SCy Schubert 		ctx->get));
841*a466cc55SCy Schubert 
842*a466cc55SCy Schubert 	evbuffer_add_buffer_reference(out, ctx->data);
843*a466cc55SCy Schubert }
844*a466cc55SCy Schubert static void
wm_eventcb(struct bufferevent * bev,short what,void * arg)845*a466cc55SCy Schubert wm_eventcb(struct bufferevent *bev, short what, void *arg)
846*a466cc55SCy Schubert {
847*a466cc55SCy Schubert 	struct wm_context *ctx = arg;
848*a466cc55SCy Schubert 	TT_BLATHER(("wm_eventcb-%s(%p): %i",
849*a466cc55SCy Schubert 		ctx->server ? "server" : "client", bev, what));
850*a466cc55SCy Schubert 	if (what & BEV_EVENT_CONNECTED) {
851*a466cc55SCy Schubert 	} else {
852*a466cc55SCy Schubert 		ctx->get = 0;
853*a466cc55SCy Schubert 	}
854*a466cc55SCy Schubert }
855*a466cc55SCy Schubert static void
wm_acceptcb(struct evconnlistener * listener,evutil_socket_t fd,struct sockaddr * addr,int socklen,void * arg)856*a466cc55SCy Schubert wm_acceptcb(struct evconnlistener *listener, evutil_socket_t fd,
857*a466cc55SCy Schubert     struct sockaddr *addr, int socklen, void *arg)
858*a466cc55SCy Schubert {
859*a466cc55SCy Schubert 	struct wm_context *ctx = arg;
860*a466cc55SCy Schubert 	struct bufferevent *bev;
861*a466cc55SCy Schubert 	struct event_base *base = evconnlistener_get_base(listener);
862*a466cc55SCy Schubert 	SSL *ssl = SSL_new(get_ssl_ctx());
863*a466cc55SCy Schubert 
864*a466cc55SCy Schubert 	SSL_use_certificate(ssl, the_cert);
865*a466cc55SCy Schubert 	SSL_use_PrivateKey(ssl, the_key);
866*a466cc55SCy Schubert 
867*a466cc55SCy Schubert 	bev = bufferevent_openssl_socket_new(
868*a466cc55SCy Schubert 		base, fd, ssl, BUFFEREVENT_SSL_ACCEPTING, ctx->flags);
869*a466cc55SCy Schubert 
870*a466cc55SCy Schubert 	TT_BLATHER(("wm_transfer-%s(%p): accept",
871*a466cc55SCy Schubert 		ctx->server ? "server" : "client", bev));
872*a466cc55SCy Schubert 
873*a466cc55SCy Schubert 	bufferevent_setwatermark(bev, EV_READ, 0, ctx->wm_high);
874*a466cc55SCy Schubert 	bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, ctx);
875*a466cc55SCy Schubert 	bufferevent_enable(bev, EV_READ|EV_WRITE);
876*a466cc55SCy Schubert 	ctx->bev = bev;
877*a466cc55SCy Schubert 
878*a466cc55SCy Schubert 	/* Only accept once, then disable ourself. */
879*a466cc55SCy Schubert 	evconnlistener_disable(listener);
880*a466cc55SCy Schubert }
881*a466cc55SCy Schubert static void
regress_bufferevent_openssl_wm(void * arg)882*a466cc55SCy Schubert regress_bufferevent_openssl_wm(void *arg)
883*a466cc55SCy Schubert {
884*a466cc55SCy Schubert 	struct basic_test_data *data = arg;
885*a466cc55SCy Schubert 	struct event_base *base = data->base;
886*a466cc55SCy Schubert 
887*a466cc55SCy Schubert 	struct evconnlistener *listener;
888*a466cc55SCy Schubert 	struct bufferevent *bev;
889*a466cc55SCy Schubert 	struct sockaddr_in sin;
890*a466cc55SCy Schubert 	struct sockaddr_storage ss;
891*a466cc55SCy Schubert 	enum regress_openssl_type type =
892*a466cc55SCy Schubert 		(enum regress_openssl_type)data->setup_data;
893*a466cc55SCy Schubert 	int bev_flags = BEV_OPT_CLOSE_ON_FREE;
894*a466cc55SCy Schubert 	ev_socklen_t slen;
895*a466cc55SCy Schubert 	SSL *ssl;
896*a466cc55SCy Schubert 	struct wm_context client, server;
897*a466cc55SCy Schubert 	char *payload;
898*a466cc55SCy Schubert 	size_t payload_len = 1<<10;
899*a466cc55SCy Schubert 	size_t wm_high = 5<<10;
900*a466cc55SCy Schubert 
901*a466cc55SCy Schubert 	memset(&sin, 0, sizeof(sin));
902*a466cc55SCy Schubert 	sin.sin_family = AF_INET;
903*a466cc55SCy Schubert 	sin.sin_addr.s_addr = htonl(0x7f000001);
904*a466cc55SCy Schubert 
905*a466cc55SCy Schubert 	memset(&ss, 0, sizeof(ss));
906*a466cc55SCy Schubert 	slen = sizeof(ss);
907*a466cc55SCy Schubert 
908*a466cc55SCy Schubert 	if (type & REGRESS_DEFERRED_CALLBACKS)
909*a466cc55SCy Schubert 		bev_flags |= BEV_OPT_DEFER_CALLBACKS;
910*a466cc55SCy Schubert 
911*a466cc55SCy Schubert 	memset(&client, 0, sizeof(client));
912*a466cc55SCy Schubert 	memset(&server, 0, sizeof(server));
913*a466cc55SCy Schubert 	client.server = 0;
914*a466cc55SCy Schubert 	server.server = 1;
915*a466cc55SCy Schubert 	client.flags = server.flags = bev_flags;
916*a466cc55SCy Schubert 	client.data = evbuffer_new();
917*a466cc55SCy Schubert 	server.data = evbuffer_new();
918*a466cc55SCy Schubert 	payload = calloc(1, payload_len);
919*a466cc55SCy Schubert 	memset(payload, 'A', payload_len);
920*a466cc55SCy Schubert 	evbuffer_add(server.data, payload, payload_len);
921*a466cc55SCy Schubert 	evbuffer_add(client.data, payload, payload_len);
922*a466cc55SCy Schubert 	client.wm_high = server.wm_high = wm_high;
923*a466cc55SCy Schubert 	client.limit = server.limit = wm_high<<3;
924*a466cc55SCy Schubert 	client.to_read = server.to_read = payload_len>>1;
925*a466cc55SCy Schubert 
926*a466cc55SCy Schubert 	TT_BLATHER(("openssl_wm: "
927*a466cc55SCy Schubert 		"payload_len = " EV_SIZE_FMT ", "
928*a466cc55SCy Schubert 		"wm_high = " EV_SIZE_FMT ", "
929*a466cc55SCy Schubert 		"limit = " EV_SIZE_FMT ", "
930*a466cc55SCy Schubert 		"to_read: " EV_SIZE_FMT "",
931*a466cc55SCy Schubert 		payload_len,
932*a466cc55SCy Schubert 		wm_high,
933*a466cc55SCy Schubert 		server.limit,
934*a466cc55SCy Schubert 		server.to_read));
935*a466cc55SCy Schubert 
936*a466cc55SCy Schubert 	listener = evconnlistener_new_bind(base, wm_acceptcb, &server,
937*a466cc55SCy Schubert 	    LEV_OPT_CLOSE_ON_FREE|LEV_OPT_REUSEABLE,
938*a466cc55SCy Schubert 	    -1, (struct sockaddr *)&sin, sizeof(sin));
939*a466cc55SCy Schubert 
940*a466cc55SCy Schubert 	tt_assert(listener);
941*a466cc55SCy Schubert 	tt_assert(evconnlistener_get_fd(listener) >= 0);
942*a466cc55SCy Schubert 
943*a466cc55SCy Schubert 	ssl = SSL_new(get_ssl_ctx());
944*a466cc55SCy Schubert 	tt_assert(ssl);
945*a466cc55SCy Schubert 
946*a466cc55SCy Schubert 	if (type & REGRESS_OPENSSL_FILTER) {
947*a466cc55SCy Schubert 		bev = bufferevent_socket_new(data->base, -1, client.flags);
948*a466cc55SCy Schubert 		tt_assert(bev);
949*a466cc55SCy Schubert 		bev = bufferevent_openssl_filter_new(
950*a466cc55SCy Schubert 			base, bev, ssl, BUFFEREVENT_SSL_CONNECTING, client.flags);
951*a466cc55SCy Schubert 	} else {
952*a466cc55SCy Schubert 		bev = bufferevent_openssl_socket_new(
953*a466cc55SCy Schubert 			data->base, -1, ssl,
954*a466cc55SCy Schubert 			BUFFEREVENT_SSL_CONNECTING,
955*a466cc55SCy Schubert 			client.flags);
956*a466cc55SCy Schubert 	}
957*a466cc55SCy Schubert 	tt_assert(bev);
958*a466cc55SCy Schubert 	client.bev = bev;
959*a466cc55SCy Schubert 
960*a466cc55SCy Schubert 	server.neighbour = &client;
961*a466cc55SCy Schubert 	client.neighbour = &server;
962*a466cc55SCy Schubert 
963*a466cc55SCy Schubert 	bufferevent_setwatermark(bev, EV_READ, 0, client.wm_high);
964*a466cc55SCy Schubert 	bufferevent_setcb(bev, wm_transfer, NULL, wm_eventcb, &client);
965*a466cc55SCy Schubert 
966*a466cc55SCy Schubert 	tt_assert(getsockname(evconnlistener_get_fd(listener),
967*a466cc55SCy Schubert 		(struct sockaddr*)&ss, &slen) == 0);
968*a466cc55SCy Schubert 
969*a466cc55SCy Schubert 	tt_assert(!bufferevent_socket_connect(bev, (struct sockaddr*)&ss, slen));
970*a466cc55SCy Schubert 	tt_assert(!evbuffer_add_buffer_reference(bufferevent_get_output(bev), client.data));
971*a466cc55SCy Schubert 	tt_assert(!bufferevent_enable(bev, EV_READ|EV_WRITE));
972*a466cc55SCy Schubert 
973*a466cc55SCy Schubert 	event_base_dispatch(base);
974*a466cc55SCy Schubert 
975*a466cc55SCy Schubert 	tt_int_op(client.get, ==, client.limit);
976*a466cc55SCy Schubert 	tt_int_op(server.get, ==, server.limit);
977*a466cc55SCy Schubert 
978*a466cc55SCy Schubert end:
979*a466cc55SCy Schubert 	free(payload);
980*a466cc55SCy Schubert 	evbuffer_free(client.data);
981*a466cc55SCy Schubert 	evbuffer_free(server.data);
982*a466cc55SCy Schubert 	evconnlistener_free(listener);
983*a466cc55SCy Schubert 	bufferevent_free(client.bev);
984*a466cc55SCy Schubert 	bufferevent_free(server.bev);
985*a466cc55SCy Schubert 
986*a466cc55SCy Schubert 	/* XXX: by some reason otherise there is a leak */
987*a466cc55SCy Schubert 	if (!(type & REGRESS_OPENSSL_FILTER))
988*a466cc55SCy Schubert 		event_base_loop(base, EVLOOP_ONCE);
9892b15cb3dSCy Schubert }
9902b15cb3dSCy Schubert 
9912b15cb3dSCy Schubert struct testcase_t ssl_testcases[] = {
992*a466cc55SCy Schubert #define T(a) ((void *)(a))
993*a466cc55SCy Schubert 	{ "bufferevent_socketpair", regress_bufferevent_openssl,
994*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_SOCKETPAIR) },
995*a466cc55SCy Schubert 	{ "bufferevent_socketpair_write_after_connect", regress_bufferevent_openssl,
996*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
997*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR|REGRESS_OPENSSL_CLIENT_WRITE) },
9982b15cb3dSCy Schubert 	{ "bufferevent_filter", regress_bufferevent_openssl,
999*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup, T(REGRESS_OPENSSL_FILTER) },
1000*a466cc55SCy Schubert 	{ "bufferevent_filter_write_after_connect", regress_bufferevent_openssl,
1001*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1002*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_FILTER|REGRESS_OPENSSL_CLIENT_WRITE) },
10032b15cb3dSCy Schubert 	{ "bufferevent_renegotiate_socketpair", regress_bufferevent_openssl,
1004*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1005*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE) },
10062b15cb3dSCy Schubert 	{ "bufferevent_renegotiate_filter", regress_bufferevent_openssl,
1007*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1008*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE) },
10092b15cb3dSCy Schubert 	{ "bufferevent_socketpair_startopen", regress_bufferevent_openssl,
1010*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1011*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN) },
10122b15cb3dSCy Schubert 	{ "bufferevent_filter_startopen", regress_bufferevent_openssl,
1013*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1014*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN) },
1015*a466cc55SCy Schubert 
1016*a466cc55SCy Schubert 	{ "bufferevent_socketpair_dirty_shutdown", regress_bufferevent_openssl,
1017*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1018*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
1019*a466cc55SCy Schubert 	{ "bufferevent_filter_dirty_shutdown", regress_bufferevent_openssl,
1020*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1021*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
1022*a466cc55SCy Schubert 	{ "bufferevent_renegotiate_socketpair_dirty_shutdown",
1023*a466cc55SCy Schubert 	  regress_bufferevent_openssl,
1024*a466cc55SCy Schubert 	  TT_ISOLATED,
1025*a466cc55SCy Schubert 	  &ssl_setup,
1026*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
1027*a466cc55SCy Schubert 	{ "bufferevent_renegotiate_filter_dirty_shutdown",
1028*a466cc55SCy Schubert 	  regress_bufferevent_openssl,
1029*a466cc55SCy Schubert 	  TT_ISOLATED,
1030*a466cc55SCy Schubert 	  &ssl_setup,
1031*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_RENEGOTIATE | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
1032*a466cc55SCy Schubert 	{ "bufferevent_socketpair_startopen_dirty_shutdown",
1033*a466cc55SCy Schubert 	  regress_bufferevent_openssl,
1034*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1035*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
1036*a466cc55SCy Schubert 	{ "bufferevent_filter_startopen_dirty_shutdown",
1037*a466cc55SCy Schubert 	  regress_bufferevent_openssl,
1038*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1039*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_OPEN | REGRESS_OPENSSL_DIRTY_SHUTDOWN) },
1040*a466cc55SCy Schubert 
1041*a466cc55SCy Schubert 	{ "bufferevent_socketpair_fd", regress_bufferevent_openssl,
1042*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1043*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FD) },
1044*a466cc55SCy Schubert 	{ "bufferevent_socketpair_freed", regress_bufferevent_openssl,
1045*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1046*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED) },
1047*a466cc55SCy Schubert 	{ "bufferevent_socketpair_freed_fd", regress_bufferevent_openssl,
1048*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1049*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
1050*a466cc55SCy Schubert 	{ "bufferevent_filter_freed_fd", regress_bufferevent_openssl,
1051*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1052*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_FILTER | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
1053*a466cc55SCy Schubert 
1054*a466cc55SCy Schubert 	{ "bufferevent_socketpair_timeout", regress_bufferevent_openssl,
1055*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1056*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT) },
1057*a466cc55SCy Schubert 	{ "bufferevent_socketpair_timeout_freed_fd", regress_bufferevent_openssl,
1058*a466cc55SCy Schubert 	  TT_ISOLATED, &ssl_setup,
1059*a466cc55SCy Schubert 	  T(REGRESS_OPENSSL_SOCKETPAIR | REGRESS_OPENSSL_TIMEOUT | REGRESS_OPENSSL_FREED | REGRESS_OPENSSL_FD) },
10602b15cb3dSCy Schubert 
10612b15cb3dSCy Schubert 	{ "bufferevent_connect", regress_bufferevent_openssl_connect,
1062*a466cc55SCy Schubert 	  TT_FORK|TT_NEED_BASE, &ssl_setup, NULL },
1063*a466cc55SCy Schubert 	{ "bufferevent_connect_sleep", regress_bufferevent_openssl_connect,
1064*a466cc55SCy Schubert 	  TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_SLEEP) },
1065*a466cc55SCy Schubert 
1066*a466cc55SCy Schubert 	{ "bufferevent_wm", regress_bufferevent_openssl_wm,
1067*a466cc55SCy Schubert 	  TT_FORK|TT_NEED_BASE, &ssl_setup, NULL },
1068*a466cc55SCy Schubert 	{ "bufferevent_wm_filter", regress_bufferevent_openssl_wm,
1069*a466cc55SCy Schubert 	  TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER) },
1070*a466cc55SCy Schubert 	{ "bufferevent_wm_defer", regress_bufferevent_openssl_wm,
1071*a466cc55SCy Schubert 	  TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_DEFERRED_CALLBACKS) },
1072*a466cc55SCy Schubert 	{ "bufferevent_wm_filter_defer", regress_bufferevent_openssl_wm,
1073*a466cc55SCy Schubert 	  TT_FORK|TT_NEED_BASE, &ssl_setup, T(REGRESS_OPENSSL_FILTER|REGRESS_DEFERRED_CALLBACKS) },
1074*a466cc55SCy Schubert 
1075*a466cc55SCy Schubert #undef T
10762b15cb3dSCy Schubert 
10772b15cb3dSCy Schubert 	END_OF_TESTCASES,
10782b15cb3dSCy Schubert };
1079