[core] con interface for read/write; isolate SSL

This commit is contained in:
Glenn Strauss 2016-12-20 21:57:08 -05:00
parent 93fc82c4ac
commit 2bc94dee82
5 changed files with 30 additions and 27 deletions

View File

@ -386,7 +386,7 @@ typedef struct {
buffer *comp_value; /* just a pointer */
} cond_cache_t;
typedef struct {
typedef struct connection {
connection_state_t state;
/* timestamps */
@ -467,6 +467,8 @@ typedef struct {
http_method_t error_handler_saved_method;
struct server_socket *srv_socket; /* reference to the server-socket */
int (* network_write)(struct server *srv, struct connection *con, chunkqueue *cq, off_t max_bytes);
int (* network_read)(struct server *srv, struct connection *con, chunkqueue *cq, off_t max_bytes);
#ifdef USE_OPENSSL
SSL *ssl;
@ -682,9 +684,6 @@ typedef struct server {
fdevent_handler_t event_handler;
int (* network_backend_write)(struct server *srv, connection *con, int fd, chunkqueue *cq, off_t max_bytes);
#ifdef USE_OPENSSL
int (* network_ssl_backend_write)(struct server *srv, connection *con, SSL *ssl, chunkqueue *cq, off_t max_bytes);
#endif
uid_t uid;
gid_t gid;

View File

@ -2,7 +2,6 @@
#include "base.h"
#include "connections.h"
#include "joblist.h"
#include "log.h"
#include <errno.h>
@ -98,12 +97,15 @@ static void dump_packet(const unsigned char *data, size_t len) {
}
#endif
static int connection_handle_read_ssl(server *srv, connection *con) {
int connection_read_cq_ssl(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
#ifdef USE_OPENSSL
int r, ssl_err, len;
char *mem = NULL;
size_t mem_len = 0;
force_assert(cq == con->read_queue); /*(code transform assumption; minimize diff)*/
UNUSED(max_bytes);
if (!con->srv_socket->is_ssl) return -1;
ERR_clear_error();
@ -217,20 +219,20 @@ static int connection_handle_read_ssl(server *srv, connection *con) {
#else
UNUSED(srv);
UNUSED(con);
UNUSED(cq);
UNUSED(max_bytes);
return -1;
#endif
}
/* 0: everything ok, -1: error, -2: con closed */
int connection_handle_read(server *srv, connection *con) {
int connection_read_cq(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
int len;
char *mem = NULL;
size_t mem_len = 0;
int toread;
if (con->srv_socket->is_ssl) {
return connection_handle_read_ssl(srv, con);
}
force_assert(cq == con->read_queue); /*(code transform assumption; minimize diff)*/
force_assert(max_bytes == MAX_READ_LIMIT); /*(code transform assumption; minimize diff)*/
/* default size for chunks is 4kb; only use bigger chunks if FIONREAD tells
* us more than 4kb is available
@ -541,7 +543,7 @@ handler_t connection_handle_read_post_state(server *srv, connection *con) {
if (con->is_readable) {
con->read_idle_ts = srv->cur_ts;
switch(connection_handle_read(srv, con)) {
switch(con->network_read(srv, con, con->read_queue, MAX_READ_LIMIT)) {
case -1:
return HANDLER_ERROR;
case -2:

View File

@ -801,7 +801,7 @@ static int connection_handle_read_state(server *srv, connection *con) {
if (con->is_readable) {
con->read_idle_ts = srv->cur_ts;
switch(connection_handle_read(srv, con)) {
switch(con->network_read(srv, con, con->read_queue, MAX_READ_LIMIT)) {
case -1:
return -1;
case -2:
@ -1039,6 +1039,15 @@ connection *connection_accept(server *srv, server_socket *srv_socket) {
}
}
static int connection_write_cq(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
return srv->network_backend_write(srv, con, con->fd, cq, max_bytes);
}
#include "network_backends.h" /* network_write_chunkqueue_openssl() */
static int connection_write_cq_ssl(server *srv, connection *con, chunkqueue *cq, off_t max_bytes) {
return network_write_chunkqueue_openssl(srv, con, con->ssl, cq, max_bytes);
}
connection *connection_accepted(server *srv, server_socket *srv_socket, sock_addr *cnt_addr, int cnt) {
connection *con;
@ -1056,6 +1065,8 @@ connection *connection_accepted(server *srv, server_socket *srv_socket, sock_add
con->fd = cnt;
con->fde_ndx = -1;
fdevent_register(srv->ev, con->fd, connection_handle_fdevent, con);
con->network_read = connection_read_cq;
con->network_write = connection_write_cq;
connection_set_state(srv, con, CON_STATE_REQUEST_START);
@ -1080,6 +1091,8 @@ connection *connection_accepted(server *srv, server_socket *srv_socket, sock_add
return NULL;
}
con->network_read = connection_read_cq_ssl;
con->network_write = connection_write_cq_ssl;
con->renegotiations = 0;
SSL_set_app_data(con->ssl, con);
SSL_set_accept_state(con->ssl);

View File

@ -16,7 +16,8 @@ int connection_set_state(server *srv, connection *con, connection_state_t state)
const char * connection_get_state(connection_state_t state);
const char * connection_get_short_state(connection_state_t state);
int connection_state_machine(server *srv, connection *con);
int connection_handle_read(server *srv, connection *con);
int connection_read_cq(server *srv, connection *con, chunkqueue *cq, off_t max_bytes);
int connection_read_cq_ssl(server *srv, connection *con, chunkqueue *cq, off_t max_bytes);
handler_t connection_handle_read_post_state(server *srv, connection *con);
handler_t connection_handle_read_post_error(server *srv, connection *con, int http_status);
void connection_response_reset(server *srv, connection *con);

View File

@ -1023,10 +1023,6 @@ int network_init(server *srv) {
}
buffer_free(b);
#ifdef USE_OPENSSL
srv->network_ssl_backend_write = network_write_chunkqueue_openssl;
#endif
/* get a usefull default */
backend = network_backends[0].nb;
@ -1119,7 +1115,6 @@ int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, off_t
#ifdef TCP_CORK
int corked = 0;
#endif
server_socket *srv_socket = con->srv_socket;
if (con->conf.global_kbytes_per_second) {
off_t limit = con->conf.global_kbytes_per_second * 1024 - *(con->conf.global_bytes_per_second_cnt_ptr);
@ -1157,14 +1152,7 @@ int network_write_chunkqueue(server *srv, connection *con, chunkqueue *cq, off_t
}
#endif
if (srv_socket->is_ssl) {
#ifdef USE_OPENSSL
ret = srv->network_ssl_backend_write(srv, con, con->ssl, cq, max_bytes);
#endif
} else {
ret = srv->network_backend_write(srv, con, con->fd, cq, max_bytes);
}
ret = con->network_write(srv, con, cq, max_bytes);
if (ret >= 0) {
chunkqueue_remove_finished_chunks(cq);
ret = chunkqueue_is_empty(cq) ? 0 : 1;