Commit 1a046cd2 authored by kelsey's avatar kelsey
Browse files

Primarily modifications related to containered alerts and discovery

Additionally, maintenance work on connection handling and code structure
parent d20fa8ce
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@ lib_LTLIBRARIES = \
libtlmsp_cfg_la_SOURCES = \
libtlmsp_cfg_la_SOURCES = \
	libtlmsp-cfg/api.c \
	libtlmsp-cfg/api.c \
	libtlmsp-cfg/format.c \
	libtlmsp-cfg/format.c \
	libtlmsp-cfg/openssl.c \
	libtlmsp-cfg/parse.c \
	libtlmsp-cfg/parse.c \
	libtlmsp-cfg/print.c
	libtlmsp-cfg/print.c
libtlmsp_cfg_la_LIBADD = \
libtlmsp_cfg_la_LIBADD = \
@@ -95,6 +96,7 @@ tlmsp_server_LDADD = \


pkginclude_HEADERS = \
pkginclude_HEADERS = \
	libtlmsp-cfg/libtlmsp-cfg.h \
	libtlmsp-cfg/libtlmsp-cfg.h \
	libtlmsp-cfg/libtlmsp-cfg-openssl.h \
	libtlmsp-util/libtlmsp-util.h
	libtlmsp-util/libtlmsp-util.h




+110 −57
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@
#include <inttypes.h>
#include <inttypes.h>
#include <libgen.h>
#include <libgen.h>
#include <libtlmsp-cfg.h>
#include <libtlmsp-cfg.h>
#include <libtlmsp-cfg-openssl.h>
#include <libtlmsp-util.h>
#include <libtlmsp-util.h>
#include <stdbool.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdio.h>
@@ -61,7 +62,8 @@ static void free_client_cb(void *app_data);
static bool new_connection(struct client_state *client,
static bool new_connection(struct client_state *client,
	                   const TLMSP_ReconnectState *reconnect_state);
	                   const TLMSP_ReconnectState *reconnect_state);
static void show_connection_info(void *app_data);
static void show_connection_info(void *app_data);
static int validate_discovery_results(SSL *ssl, void *arg);
static int validate_discovery_results(SSL *ssl, void *arg,
                                      TLMSP_Middleboxes *middleboxes);
static void free_connection_cb(void *app_data);
static void free_connection_cb(void *app_data);
static void connection_died(struct demo_connection *conn);
static void connection_died(struct demo_connection *conn);
static void conn_cb(EV_P_ ev_io *w, int revents);
static void conn_cb(EV_P_ ev_io *w, int revents);
@@ -240,7 +242,7 @@ new_connection(struct client_state *client,
{
{
	struct connection_state *conn_state;
	struct connection_state *conn_state;
	struct demo_connection *conn;
	struct demo_connection *conn;
	struct sockaddr *addr;
	struct sockaddr *addr = NULL;
	socklen_t addr_len;
	socklen_t addr_len;
	uint8_t *first_hop_addr = NULL;
	uint8_t *first_hop_addr = NULL;
	char *first_hop_addr_str;
	char *first_hop_addr_str;
@@ -351,9 +353,11 @@ new_connection(struct client_state *client,
		demo_print_errno("Connect failed");
		demo_print_errno("Connect failed");
		goto error;
		goto error;
	}
	}
	free(addr);
	addr = NULL;


	if (!demo_connection_init_io(conn, client->ssl_ctx, sock, client->loop,
	if (!demo_connection_init_io(conn, client->ssl_ctx, sock, client->loop,
		(demo_connection_failed_cb_t)connection_died, conn_cb, EV_WRITE))
		connection_died, NULL, conn_cb, EV_WRITE))
		goto error;
		goto error;


	SSL_set_connect_state(conn->ssl);
	SSL_set_connect_state(conn->ssl);
@@ -366,7 +370,6 @@ new_connection(struct client_state *client,
			demo_print_error_ssl_errq("Failed to set reconnect state");
			demo_print_error_ssl_errq("Failed to set reconnect state");
			goto error;
			goto error;
		}
		}
		TLMSP_reconnect_state_free(reconnect_state);
	}
	}


	demo_connection_start_io(conn);
	demo_connection_start_io(conn);
@@ -374,6 +377,7 @@ new_connection(struct client_state *client,
	return (true);
	return (true);


error:
error:
	free(addr);
	OPENSSL_free(first_hop_addr);
	OPENSSL_free(first_hop_addr);
	demo_connection_free(conn);
	demo_connection_free(conn);
	return (false);
	return (false);
@@ -394,23 +398,19 @@ free_connection_cb(void *app_data)
	struct connection_state *conn_state = app_data;
	struct connection_state *conn_state = app_data;


	TLMSP_reconnect_state_free(conn_state->reconnect_state);
	TLMSP_reconnect_state_free(conn_state->reconnect_state);
	free(conn_state->read_buffer);
	free(conn_state);
	free(conn_state);
}
}


static int
static int
validate_discovery_results(SSL *ssl, void *arg)
validate_discovery_results(SSL *ssl, void *arg, TLMSP_Middleboxes *middleboxes)
{
{
	struct demo_connection *conn = arg;
	struct demo_connection *conn = arg;
	const struct tlmsp_cfg *cfg = conn->app->cfg;
	const struct tlmsp_cfg *cfg = conn->app->cfg;
	TLMSP_Middleboxes *middleboxes;
	int result;
	int result;


	middleboxes = TLMSP_get_middleboxes_instance(conn->ssl);
	if (middleboxes == NULL)
		return (0);
	result = tlmsp_cfg_validate_middlebox_list_client_openssl(cfg,
	result = tlmsp_cfg_validate_middlebox_list_client_openssl(cfg,
		middleboxes);
		middleboxes);
	TLMSP_middleboxes_free(middleboxes);
	return (result);
	return (result);
}
}


@@ -440,11 +440,67 @@ static void
conn_cb(EV_P_ ev_io *w, int revents)
conn_cb(EV_P_ ev_io *w, int revents)
{
{
	struct demo_connection *conn = w->data;
	struct demo_connection *conn = w->data;
	struct connection_state *conn_state = conn->app_data;
	int result;
	int ssl_error;
	bool pending_writes;
	bool pending_writes;


	demo_connection_pause_io(conn);
	demo_connection_pause_io(conn);
	demo_connection_events_arrived(conn, revents);
	demo_connection_events_arrived(conn, revents);


	switch (conn->phase) {
	case DEMO_CONNECTION_PHASE_HANDSHAKE:
		result = SSL_connect(conn->ssl);
		switch (result) {
		case 0:
			demo_conn_print_error(conn, "Handshake terminated by protocol");
			connection_died(conn);
			return;
			break;
		case 1:
			demo_conn_log(1, conn, "Handshake complete");
			demo_connection_wait_for(conn, EV_READ);
			if (!demo_connection_handshake_complete(conn)) {
				connection_died(conn);
				return;
			}
			break;
		default:
			ssl_error = SSL_get_error(conn->ssl, result);
			switch (ssl_error) {
			case SSL_ERROR_WANT_RECONNECT:
				demo_conn_log(5, conn, "SSL_ERROR_WANT_RECONNECT");
				/*
				 * Re-establish outbound connection and
				 * re-enter handshake.
				 */
				conn_state->reconnect_state =
				    TLMSP_get_reconnect_state(conn->ssl);
				if (conn_state->reconnect_state == NULL)
					demo_conn_print_error_ssl_errq(conn,
					    "Reconnect state retrieval failed");
				connection_died(conn);
				return;
				break;
			case SSL_ERROR_WANT_READ:
				demo_conn_log(5, conn, "SSL_ERROR_WANT_READ");
				demo_connection_wait_for(conn, EV_READ);
				break;
			case SSL_ERROR_WANT_WRITE:
				demo_conn_log(5, conn, "SSL_ERROR_WANT_WRITE");
				demo_connection_wait_for(conn, EV_WRITE);
				break;
			default:
				demo_conn_print_error_ssl(conn, ssl_error,
				    "Handshake terminated due to fatal error");
				connection_died(conn);
				return;
				break;
			}
			break;
		}
		break;
	case DEMO_CONNECTION_PHASE_APPLICATION:
		/*
		/*
		 * The general approach is that we prioritize writes over
		 * The general approach is that we prioritize writes over
		 * reads - we work on pending write data until it is all
		 * reads - we work on pending write data until it is all
@@ -488,6 +544,14 @@ conn_cb(EV_P_ ev_io *w, int revents)
		 */
		 */
		if (demo_connection_wait_events(conn) == 0)
		if (demo_connection_wait_events(conn) == 0)
			demo_connection_wait_for(conn, EV_READ);
			demo_connection_wait_for(conn, EV_READ);
		break;
	default:
		demo_conn_print_error(conn,
		    "Unexpected connection phase %d", conn->phase);
		connection_died(conn);
		return;
		break;
	}


	demo_connection_resume_io(conn);
	demo_connection_resume_io(conn);
}
}
@@ -546,7 +610,7 @@ read_containers(struct demo_connection *conn)
			} else if (!TLMSP_container_readable(container)) {
			} else if (!TLMSP_container_readable(container)) {
				demo_conn_print_error(conn,
				demo_conn_print_error(conn,
				    "Opaque container unexpectedly received in "
				    "Opaque container unexpectedly received in "
				    "context %d using containe API", context_id);
				    "context %d using container API", context_id);
				TLMSP_container_free(ssl, container);
				TLMSP_container_free(ssl, container);
				return (false);
				return (false);
			} else {
			} else {
@@ -577,12 +641,6 @@ read_containers(struct demo_connection *conn)
			demo_conn_log(5, conn, "SSL_ERROR_WANT_WRITE");
			demo_conn_log(5, conn, "SSL_ERROR_WANT_WRITE");
			demo_connection_wait_for(conn, EV_WRITE);
			demo_connection_wait_for(conn, EV_WRITE);
			break;
			break;
		case SSL_ERROR_WANT_RECONNECT:
			demo_conn_log(5, conn, "SSL_ERROR_WANT_RECONNECT");
			conn_state->reconnect_state =
			    TLMSP_get_reconnect_state(ssl);
			result = false;
			break;
		default:
		default:
			demo_conn_print_error_ssl(conn, ssl_error,
			demo_conn_print_error_ssl(conn, ssl_error,
			    "Connection terminated due to fatal read error");
			    "Connection terminated due to fatal read error");
@@ -665,11 +723,6 @@ write_containers(struct demo_connection *conn)
			demo_conn_log(5, conn, "SSL_ERROR_WANT_WRITE");
			demo_conn_log(5, conn, "SSL_ERROR_WANT_WRITE");
			demo_connection_wait_for(conn, EV_WRITE);
			demo_connection_wait_for(conn, EV_WRITE);
			break;
			break;
		case SSL_ERROR_WANT_RECONNECT:
			demo_conn_log(5, conn, "SSL_ERROR_WANT_RECONNECT");
			conn_state->reconnect_state = TLMSP_get_reconnect_state(ssl);
			result = false;
			break;
		default:
		default:
			demo_conn_print_error_ssl(conn, ssl_error,
			demo_conn_print_error_ssl(conn, ssl_error,
			    "Connection terminated due to fatal write error");
			    "Connection terminated due to fatal write error");
+56 −1
Original line number Original line Diff line number Diff line
@@ -52,7 +52,7 @@ struct match_groups {
};
};


struct demo_activity_match_state {
struct demo_activity_match_state {
	bool contexts[TLMSP_CONTEXT_ID_MAX + 1];
	bool contexts[TLMSP_UTIL_CONTEXT_ID_LUT_SIZE];
	struct tlmsp_cfg_activity *activity;
	struct tlmsp_cfg_activity *activity;
	struct container_queue_range match_range;
	struct container_queue_range match_range;
	size_t match_offset;
	size_t match_offset;
@@ -95,6 +95,9 @@ static bool demo_activity_queue_payload(struct demo_connection *conn,
                                        struct tlmsp_cfg_payload *payload,
                                        struct tlmsp_cfg_payload *payload,
                                        struct match_groups *match_groups,
                                        struct match_groups *match_groups,
                                        bool present);
                                        bool present);
static bool demo_activity_queue_alert(struct demo_connection *conn,
                                      struct tlmsp_cfg_alert *alert,
                                      bool present);
static void demo_activity_time_triggered_cb(EV_P_ ev_timer *w, int revents);
static void demo_activity_time_triggered_cb(EV_P_ ev_timer *w, int revents);
static bool demo_activity_get_payload_data(struct demo_connection *conn,
static bool demo_activity_get_payload_data(struct demo_connection *conn,
                                           struct tlmsp_cfg_payload *payload,
                                           struct tlmsp_cfg_payload *payload,
@@ -351,6 +354,42 @@ demo_activity_queue_payload(struct demo_connection *conn,
	return (result);
	return (result);
}
}


static bool
demo_activity_queue_alert(struct demo_connection *conn,
    struct tlmsp_cfg_alert *alert, bool present)
{
	struct container_queue *q = &conn->write_queue;
	SSL *ssl = q->conn->ssl;
	TLMSP_Container *container;
	tlmsp_context_id_t context_id;

	context_id = alert->context ? alert->context->id : 0;
	if (present)
		demo_conn_present(conn, "Sending %s alert %d in context %u",
		    alert->level == TLMSP_CFG_ACTION_ALERT_LEVEL_WARNING ?
		    "warning" : "fatal", alert->description, context_id);

	if (!TLMSP_container_create_alert(ssl, &container, context_id,
		(alert->level << 8) | alert->description)) {
		demo_conn_print_error_ssl_errq(conn,
		    "Failed to create container for alert");
		return (false);
	}

	if (!container_queue_add(q, container)) {
		demo_conn_print_error(conn,
		    "Failed to add alert container to queue");
		TLMSP_container_free(ssl, container);
		return (false);
	}

	demo_conn_log(2, conn, "Sending %s alert %d in context %u",
	    alert->level == TLMSP_CFG_ACTION_ALERT_LEVEL_WARNING ?
	    "warning" : "fatal", alert->description, context_id);

	return (true);
}

static void
static void
demo_activity_time_triggered_cb(EV_P_ ev_timer *w, int revents)
demo_activity_time_triggered_cb(EV_P_ ev_timer *w, int revents)
{
{
@@ -1357,12 +1396,28 @@ demo_activity_apply_actions(struct demo_connection *activity_conn,
			if (!demo_activity_queue_payload(outbound_conn,
			if (!demo_activity_queue_payload(outbound_conn,
				&action->send, match_groups, activity->present))
				&action->send, match_groups, activity->present))
				return (false);
				return (false);
		} else if (action->alert.level != TLMSP_CFG_ACTION_ALERT_LEVEL_NONE) {
			if (!demo_activity_queue_alert(send_conn,
				&action->alert, activity->present))
				return (false);
		} else if (action->renegotiate) {
		} else if (action->renegotiate) {
			if (!SSL_renegotiate_abbreviated(activity_conn->ssl)) {
			if (!SSL_renegotiate_abbreviated(activity_conn->ssl)) {
				demo_conn_print_error_ssl_errq(activity_conn,
				demo_conn_print_error_ssl_errq(activity_conn,
				    "Failed to schedule a renegotiation");
				    "Failed to schedule a renegotiation");
				return (false);
				return (false);
			}
			}
		} else if (action->shutdown) {
			/*
			 * This will put the SSL into a state where our next
			 * attempt to read a container will return the
			 * appropriate WANT_WRITE, and we will transition into
			 * flushing the write part of the BIO.  Therefore, we
			 * just ignore any error here.
			 *
			 * We could narrow it to just ignore the expected
			 * errors.
			 */
			(void)SSL_shutdown(activity_conn->ssl);
		}
		}
	}
	}


+27 −19
Original line number Original line Diff line number Diff line
@@ -71,8 +71,11 @@ void
demo_connection_shutdown(struct demo_connection *conn)
demo_connection_shutdown(struct demo_connection *conn)
{
{


	if (conn->is_connected)
	if (conn->is_connected && !conn->is_shut_down) {
		demo_conn_log(1, conn, "Shutting down writes");
		shutdown(conn->socket, SHUT_WR);
		shutdown(conn->socket, SHUT_WR);
		conn->is_shut_down = true;
	}
}
}


void
void
@@ -86,7 +89,8 @@ demo_connection_set_phase(struct demo_connection *conn,
bool
bool
demo_connection_init_io(struct demo_connection *conn, SSL_CTX *ssl_ctx, int sock,
demo_connection_init_io(struct demo_connection *conn, SSL_CTX *ssl_ctx, int sock,
    struct ev_loop *loop, demo_connection_failed_cb_t fail_cb,
    struct ev_loop *loop, demo_connection_failed_cb_t fail_cb,
    demo_connection_cb_t cb, int initial_events)
    demo_connection_connected_cb_t connected_cb, demo_connection_cb_t cb,
    int initial_events)
{
{
	
	
	conn->ssl = SSL_new(ssl_ctx);
	conn->ssl = SSL_new(ssl_ctx);
@@ -97,7 +101,7 @@ demo_connection_init_io(struct demo_connection *conn, SSL_CTX *ssl_ctx, int sock
	conn->socket = sock;
	conn->socket = sock;
	conn->loop = loop;
	conn->loop = loop;
	conn->fail_cb = fail_cb;
	conn->fail_cb = fail_cb;
	conn->cb_data = conn;
	conn->connected_cb = connected_cb;


	ev_io_init(&conn->connected_watcher, demo_conn_connected_cb,
	ev_io_init(&conn->connected_watcher, demo_conn_connected_cb,
	    conn->socket, EV_WRITE);
	    conn->socket, EV_WRITE);
@@ -116,7 +120,7 @@ demo_connection_init_io(struct demo_connection *conn, SSL_CTX *ssl_ctx, int sock
	conn->queues_initialized = true;
	conn->queues_initialized = true;


	ev_io_init(&conn->watcher, cb, conn->socket, conn->wait_events);
	ev_io_init(&conn->watcher, cb, conn->socket, conn->wait_events);
	conn->watcher.data = conn->cb_data;
	conn->watcher.data = conn;


	return (true);
	return (true);
}
}
@@ -126,6 +130,7 @@ demo_connection_start_io(struct demo_connection *conn)
{
{
	struct ev_loop *loop = conn->loop;
	struct ev_loop *loop = conn->loop;


	demo_connection_set_phase(conn, DEMO_CONNECTION_PHASE_HANDSHAKE);
	ev_io_start(EV_A_ &conn->connected_watcher);
	ev_io_start(EV_A_ &conn->connected_watcher);


	return (true);
	return (true);
@@ -137,20 +142,21 @@ demo_conn_connected_cb(EV_P_ ev_io *w, int revents)
	struct demo_connection *conn = w->data;
	struct demo_connection *conn = w->data;
	socklen_t len;
	socklen_t len;


	if (conn->connected_cb)
		conn->connected_cb(conn);
	
	len = sizeof(conn->local_name);
	len = sizeof(conn->local_name);
	if (getsockname(conn->socket, (struct sockaddr *)&conn->local_name,
	if (getsockname(conn->socket, (struct sockaddr *)&conn->local_name,
		&len) == -1) {
		&len) == -1) {
		demo_conn_print_errno(conn, "Could not get local address");
		demo_conn_print_errno(conn, "Could not get local address");
		conn->io_error = true;
		conn->fail_cb(conn);
		conn->fail_cb(conn->cb_data);
		return;
		return;
	}
	}
	len = sizeof(conn->remote_name);
	len = sizeof(conn->remote_name);
	if (getpeername(conn->socket, (struct sockaddr *)&conn->remote_name,
	if (getpeername(conn->socket, (struct sockaddr *)&conn->remote_name,
		&len) == -1) {
		&len) == -1) {
		demo_conn_print_errno(conn, "Could not get remote address");
		demo_conn_print_errno(conn, "Could not get remote address");
		conn->io_error = true;
		conn->fail_cb(conn);
		conn->fail_cb(conn->cb_data);
		return;
		return;
	}
	}
	demo_conn_log_sockaddr(1, conn, "Local  address is ",
	demo_conn_log_sockaddr(1, conn, "Local  address is ",
@@ -158,13 +164,6 @@ demo_conn_connected_cb(EV_P_ ev_io *w, int revents)
	demo_conn_log_sockaddr(1, conn, "Remote address is ",
	demo_conn_log_sockaddr(1, conn, "Remote address is ",
	    (struct sockaddr *)&conn->remote_name);
	    (struct sockaddr *)&conn->remote_name);


	/*
	 * XXX Once the client and server are structured to detect handshake
	 * complete, this will move to that point in client/server.
	 */
	if (!conn->splice)
		demo_connection_handshake_complete(conn);

	conn->is_connected = true;
	conn->is_connected = true;
	ev_io_stop(EV_A_ &conn->connected_watcher);
	ev_io_stop(EV_A_ &conn->connected_watcher);
	ev_io_start(EV_A_ &conn->watcher);
	ev_io_start(EV_A_ &conn->watcher);
@@ -173,6 +172,14 @@ demo_conn_connected_cb(EV_P_ ev_io *w, int revents)
bool
bool
demo_connection_handshake_complete(struct demo_connection *conn)
demo_connection_handshake_complete(struct demo_connection *conn)
{
{
	
	demo_connection_set_phase(conn, DEMO_CONNECTION_PHASE_APPLICATION);

	if (conn->initial_handshake_complete)
		return (true);

	conn->initial_handshake_complete = true;

	if (!demo_activity_conn_queue_initial(conn)) {
	if (!demo_activity_conn_queue_initial(conn)) {
		demo_conn_print_error(conn,
		demo_conn_print_error(conn,
		    "Failed to queue initial send data for write");
		    "Failed to queue initial send data for write");
@@ -283,7 +290,7 @@ void
demo_connection_free(struct demo_connection *conn)
demo_connection_free(struct demo_connection *conn)
{
{


	demo_conn_log(1, conn, "Shutting down");
	demo_conn_log(1, conn, "Closing");


	if (!conn->app->uses_splices)
	if (!conn->app->uses_splices)
		demo_app_remove_connection(conn->app, conn);
		demo_app_remove_connection(conn->app, conn);
@@ -301,6 +308,7 @@ demo_connection_free(struct demo_connection *conn)


	demo_activity_conn_tear_down_time_triggered(conn);
	demo_activity_conn_tear_down_time_triggered(conn);


	free(conn->activity_states);
	free(conn);
	free(conn);
}
}


+9 −5
Original line number Original line Diff line number Diff line
@@ -20,11 +20,13 @@
struct demo_app;
struct demo_app;
struct demo_splice;
struct demo_splice;
struct tlmsp_cfg_activity;
struct tlmsp_cfg_activity;
struct demo_connection;


typedef void (*demo_connection_connected_cb_t)(struct demo_connection *conn);
typedef void (*demo_connection_cb_t)(EV_P_ struct ev_io *w, int revents);
typedef void (*demo_connection_cb_t)(EV_P_ struct ev_io *w, int revents);
typedef void (*demo_connection_failed_cb_t)(void *cb_data);
typedef void (*demo_connection_failed_cb_t)(struct demo_connection *conn);
typedef void (*demo_connection_free_cb_t)(void *);
typedef void (*demo_connection_free_cb_t)(void *app_data);
typedef void (*demo_connection_show_info_cb_t)(void *);
typedef void (*demo_connection_show_info_cb_t)(void *app_data);


enum demo_connection_phase {
enum demo_connection_phase {
	DEMO_CONNECTION_PHASE_UNKNOWN,
	DEMO_CONNECTION_PHASE_UNKNOWN,
@@ -37,13 +39,14 @@ struct demo_connection {
	struct demo_app *app;
	struct demo_app *app;
	void *app_data;
	void *app_data;
	demo_connection_failed_cb_t fail_cb;
	demo_connection_failed_cb_t fail_cb;
	void *cb_data;
	demo_connection_connected_cb_t connected_cb;
	struct demo_splice *splice; /* only used by middlebox */
	struct demo_splice *splice; /* only used by middlebox */
	struct demo_connection *other_side; /* only used when there is a splice */
	struct demo_connection *other_side; /* only used when there is a splice */
	bool to_client; /* only used when there is a splice */
	bool to_client; /* only used when there is a splice */
	bool is_connected;
	bool is_connected;
	bool initial_handshake_complete;
	bool is_shut_down;
	bool read_eof;  /* read returned SSL_ERROR_ZERO_RETURN */
	bool read_eof;  /* read returned SSL_ERROR_ZERO_RETURN */
	bool io_error;  /* other than eof */
	struct sockaddr_storage local_name;
	struct sockaddr_storage local_name;
	struct sockaddr_storage remote_name;
	struct sockaddr_storage remote_name;
	uint64_t id;
	uint64_t id;
@@ -92,6 +95,7 @@ bool demo_connection_handshake_complete(struct demo_connection *conn);
bool demo_connection_init_io(struct demo_connection *conn, SSL_CTX *ssl_ctx,
bool demo_connection_init_io(struct demo_connection *conn, SSL_CTX *ssl_ctx,
                             int sock, struct ev_loop *loop,
                             int sock, struct ev_loop *loop,
                             demo_connection_failed_cb_t fail_cb,
                             demo_connection_failed_cb_t fail_cb,
                             demo_connection_connected_cb_t connected_cb,
                             demo_connection_cb_t cb, int initial_events);
                             demo_connection_cb_t cb, int initial_events);
bool demo_connection_start_io(struct demo_connection *conn);
bool demo_connection_start_io(struct demo_connection *conn);
void demo_connection_pause_io(struct demo_connection *conn);
void demo_connection_pause_io(struct demo_connection *conn);
Loading