forked from mirrors/kore
Allow applications to create new connections in our event loop.
This commit is contained in:
parent
b2f870a36f
commit
7771adbec2
|
@ -160,6 +160,10 @@ struct connection {
|
|||
void *hdlr_extra;
|
||||
X509 *cert;
|
||||
|
||||
void (*disconnect)(struct connection *);
|
||||
int (*read)(struct connection *, int *);
|
||||
int (*write)(struct connection *, int, int *);
|
||||
|
||||
u_int8_t addrtype;
|
||||
union {
|
||||
struct sockaddr_in ipv4;
|
||||
|
@ -359,6 +363,7 @@ void kore_platform_disable_read(int);
|
|||
void kore_platform_enable_accept(void);
|
||||
void kore_platform_disable_accept(void);
|
||||
void kore_platform_event_wait(u_int64_t);
|
||||
void kore_platform_event_all(int, void *);
|
||||
void kore_platform_schedule_read(int, void *);
|
||||
void kore_platform_event_schedule(int, int, int, void *);
|
||||
void kore_platform_worker_setcpu(struct kore_worker *);
|
||||
|
@ -376,15 +381,18 @@ int kore_ssl_sni_cb(SSL *, int *, void *);
|
|||
int kore_server_bind(const char *, const char *);
|
||||
int kore_ssl_npn_cb(SSL *, const u_char **, unsigned int *, void *);
|
||||
|
||||
void kore_connection_init(void);
|
||||
int kore_connection_nonblock(int);
|
||||
int kore_connection_handle(struct connection *);
|
||||
void kore_connection_remove(struct connection *);
|
||||
void kore_connection_disconnect(struct connection *);
|
||||
void kore_connection_start_idletimer(struct connection *);
|
||||
void kore_connection_stop_idletimer(struct connection *);
|
||||
void kore_connection_check_idletimer(u_int64_t, struct connection *);
|
||||
int kore_connection_accept(struct listener *, struct connection **);
|
||||
void kore_connection_init(void);
|
||||
struct connection *kore_connection_new(void *);
|
||||
int kore_connection_nonblock(int);
|
||||
int kore_connection_handle(struct connection *);
|
||||
void kore_connection_remove(struct connection *);
|
||||
void kore_connection_disconnect(struct connection *);
|
||||
void kore_connection_start_idletimer(struct connection *);
|
||||
void kore_connection_stop_idletimer(struct connection *);
|
||||
void kore_connection_check_idletimer(u_int64_t,
|
||||
struct connection *);
|
||||
int kore_connection_accept(struct listener *,
|
||||
struct connection **);
|
||||
|
||||
u_int64_t kore_time_ms(void);
|
||||
void kore_log_init(void);
|
||||
|
@ -457,6 +465,10 @@ int net_recv(struct connection *);
|
|||
int net_send(struct connection *);
|
||||
int net_send_flush(struct connection *);
|
||||
int net_recv_flush(struct connection *);
|
||||
int net_read(struct connection *, int *);
|
||||
int net_read_ssl(struct connection *, int *);
|
||||
int net_write(struct connection *, int, int *);
|
||||
int net_write_ssl(struct connection *, int, int *);
|
||||
void net_remove_netbuf(struct netbuf_head *, struct netbuf *);
|
||||
void net_recv_queue(struct connection *, u_int32_t, int,
|
||||
struct netbuf **, int (*cb)(struct netbuf *));
|
||||
|
|
12
src/bsd.c
12
src/bsd.c
|
@ -145,10 +145,7 @@ kore_platform_event_wait(u_int64_t timer)
|
|||
if (c == NULL)
|
||||
break;
|
||||
|
||||
kore_platform_event_schedule(c->fd,
|
||||
EVFILT_READ, EV_ADD, c);
|
||||
kore_platform_event_schedule(c->fd,
|
||||
EVFILT_WRITE, EV_ADD | EV_ONESHOT, c);
|
||||
kore_platform_event_all(c->fd, c);
|
||||
}
|
||||
break;
|
||||
case KORE_TYPE_CONNECTION:
|
||||
|
@ -186,6 +183,13 @@ kore_platform_event_wait(u_int64_t timer)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
kore_platform_event_all(int fd, void *c)
|
||||
{
|
||||
kore_platform_event_schedule(fd, EVFILT_READ, EV_ADD, c);
|
||||
kore_platform_event_schedule(fd, EVFILT_WRITE, EV_ADD | EV_ONESHOT, c);
|
||||
}
|
||||
|
||||
void
|
||||
kore_platform_event_schedule(int fd, int type, int flags, void *data)
|
||||
{
|
||||
|
|
|
@ -33,6 +33,38 @@ kore_connection_init(void)
|
|||
sizeof(struct connection), worker_max_connections);
|
||||
}
|
||||
|
||||
struct connection *
|
||||
kore_connection_new(void *owner)
|
||||
{
|
||||
struct connection *c;
|
||||
|
||||
c = kore_pool_get(&connection_pool);
|
||||
|
||||
c->ssl = NULL;
|
||||
c->flags = 0;
|
||||
c->cert = NULL;
|
||||
c->owner = owner;
|
||||
c->disconnect = NULL;
|
||||
c->hdlr_extra = NULL;
|
||||
c->inflate_started = 0;
|
||||
c->deflate_started = 0;
|
||||
c->client_stream_id = 0;
|
||||
c->proto = CONN_PROTO_UNKNOWN;
|
||||
c->type = KORE_TYPE_CONNECTION;
|
||||
c->wsize_initial = SPDY_INIT_WSIZE;
|
||||
c->spdy_send_wsize = SPDY_INIT_WSIZE;
|
||||
c->spdy_recv_wsize = SPDY_INIT_WSIZE;
|
||||
c->idle_timer.start = 0;
|
||||
c->idle_timer.length = KORE_IDLE_TIMER_MAX;
|
||||
|
||||
TAILQ_INIT(&(c->send_queue));
|
||||
TAILQ_INIT(&(c->recv_queue));
|
||||
TAILQ_INIT(&(c->spdy_streams));
|
||||
TAILQ_INIT(&(c->http_requests));
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
int
|
||||
kore_connection_accept(struct listener *l, struct connection **out)
|
||||
{
|
||||
|
@ -43,8 +75,7 @@ kore_connection_accept(struct listener *l, struct connection **out)
|
|||
kore_debug("kore_connection_accept(%p)", l);
|
||||
|
||||
*out = NULL;
|
||||
c = kore_pool_get(&connection_pool);
|
||||
c->type = KORE_TYPE_CONNECTION;
|
||||
c = kore_connection_new(l);
|
||||
|
||||
c->addrtype = l->addrtype;
|
||||
if (c->addrtype == AF_INET) {
|
||||
|
@ -67,31 +98,16 @@ kore_connection_accept(struct listener *l, struct connection **out)
|
|||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
c->owner = l;
|
||||
c->ssl = NULL;
|
||||
c->flags = 0;
|
||||
c->cert = NULL;
|
||||
c->hdlr_extra = NULL;
|
||||
c->inflate_started = 0;
|
||||
c->deflate_started = 0;
|
||||
c->client_stream_id = 0;
|
||||
c->proto = CONN_PROTO_UNKNOWN;
|
||||
c->wsize_initial = SPDY_INIT_WSIZE;
|
||||
c->spdy_send_wsize = SPDY_INIT_WSIZE;
|
||||
c->spdy_recv_wsize = SPDY_INIT_WSIZE;
|
||||
c->idle_timer.start = 0;
|
||||
c->idle_timer.length = KORE_IDLE_TIMER_MAX;
|
||||
|
||||
TAILQ_INIT(&(c->send_queue));
|
||||
TAILQ_INIT(&(c->recv_queue));
|
||||
TAILQ_INIT(&(c->spdy_streams));
|
||||
TAILQ_INIT(&(c->http_requests));
|
||||
|
||||
#if !defined(KORE_BENCHMARK)
|
||||
c->state = CONN_STATE_SSL_SHAKE;
|
||||
c->write = net_write_ssl;
|
||||
c->read = net_read_ssl;
|
||||
#else
|
||||
c->state = CONN_STATE_ESTABLISHED;
|
||||
c->proto = CONN_PROTO_HTTP;
|
||||
c->write = net_write;
|
||||
c->read = net_read;
|
||||
|
||||
if (http_keepalive_time != 0)
|
||||
c->idle_timer.length = http_keepalive_time * 1000;
|
||||
|
||||
|
@ -112,6 +128,9 @@ kore_connection_disconnect(struct connection *c)
|
|||
if (c->state != CONN_STATE_DISCONNECTING) {
|
||||
kore_debug("preparing %p for disconnection", c);
|
||||
c->state = CONN_STATE_DISCONNECTING;
|
||||
if (c->disconnect)
|
||||
c->disconnect(c);
|
||||
|
||||
kore_worker_connection_move(c);
|
||||
}
|
||||
}
|
||||
|
|
11
src/linux.c
11
src/linux.c
|
@ -131,9 +131,7 @@ kore_platform_event_wait(u_int64_t timer)
|
|||
if (c == NULL)
|
||||
break;
|
||||
|
||||
kore_platform_event_schedule(c->fd,
|
||||
EPOLLIN | EPOLLOUT |
|
||||
EPOLLRDHUP | EPOLLET, 0, c);
|
||||
kore_platform_event_all(c->fd, c);
|
||||
}
|
||||
break;
|
||||
case KORE_TYPE_CONNECTION:
|
||||
|
@ -164,6 +162,13 @@ kore_platform_event_wait(u_int64_t timer)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
kore_platform_event_all(int fd, void *c)
|
||||
{
|
||||
kore_platform_event_schedule(fd,
|
||||
EPOLLIN | EPOLLOUT | EPOLLRDHUP | EPOLLET, 0, c);
|
||||
}
|
||||
|
||||
void
|
||||
kore_platform_event_schedule(int fd, int type, int flags, void *udata)
|
||||
{
|
||||
|
|
167
src/net.c
167
src/net.c
|
@ -176,37 +176,11 @@ net_send(struct connection *c)
|
|||
|
||||
len = MIN(NETBUF_SEND_PAYLOAD_MAX, smin);
|
||||
|
||||
#if !defined(KORE_BENCHMARK)
|
||||
r = SSL_write(c->ssl,
|
||||
(c->snb->buf + c->snb->s_off), len);
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
switch (r) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
c->snb->flags |= NETBUF_MUST_RESEND;
|
||||
c->flags &= ~CONN_WRITE_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("SSL_write(): %s",
|
||||
ssl_errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
#else
|
||||
r = write(c->fd, (c->snb->buf + c->snb->s_off), len);
|
||||
if (r <= -1) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
c->flags &= ~CONN_WRITE_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("write: %s", errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!c->write(c, len, &r))
|
||||
return (KORE_RESULT_ERROR);
|
||||
if (!(c->flags & CONN_WRITE_POSSIBLE))
|
||||
return (KORE_RESULT_OK);
|
||||
|
||||
kore_debug("net_send(%p/%d/%d bytes), progress with %d",
|
||||
c->snb, c->snb->s_off, c->snb->b_len, r);
|
||||
|
||||
|
@ -253,37 +227,11 @@ net_recv(struct connection *c)
|
|||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
#if !defined(KORE_BENCHMARK)
|
||||
r = SSL_read(c->ssl,
|
||||
(c->rnb->buf + c->rnb->s_off),
|
||||
(c->rnb->b_len - c->rnb->s_off));
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
switch (r) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
c->flags &= ~CONN_READ_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("SSL_read(): %s", ssl_errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
#else
|
||||
r = read(c->fd, (c->rnb->buf + c->rnb->s_off),
|
||||
(c->rnb->b_len - c->rnb->s_off));
|
||||
if (r <= 0) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
c->flags &= ~CONN_READ_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("read(): %s", errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (!c->read(c, &r))
|
||||
return (KORE_RESULT_ERROR);
|
||||
if (!(c->flags & CONN_READ_POSSIBLE))
|
||||
return (KORE_RESULT_OK);
|
||||
|
||||
kore_debug("net_recv(%ld/%ld bytes), progress with %d",
|
||||
c->rnb->s_off, c->rnb->b_len, r);
|
||||
|
||||
|
@ -340,6 +288,101 @@ net_remove_netbuf(struct netbuf_head *list, struct netbuf *nb)
|
|||
kore_pool_put(&nb_pool, nb);
|
||||
}
|
||||
|
||||
#if !defined(KORE_BENCHMARK)
|
||||
int
|
||||
net_write_ssl(struct connection *c, int len, int *written)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = SSL_write(c->ssl, (c->snb->buf + c->snb->s_off), len);
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
switch (r) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
c->snb->flags |= NETBUF_MUST_RESEND;
|
||||
c->flags &= ~CONN_WRITE_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("SSL_write(): %s", ssl_errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
*written = r;
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
int
|
||||
net_read_ssl(struct connection *c, int *bytes)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = SSL_read(c->ssl, (c->rnb->buf + c->rnb->s_off),
|
||||
(c->rnb->b_len - c->rnb->s_off));
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
switch (r) {
|
||||
case SSL_ERROR_WANT_READ:
|
||||
case SSL_ERROR_WANT_WRITE:
|
||||
c->flags &= ~CONN_READ_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("SSL_read(): %s", ssl_errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
*bytes = r;
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
net_write(struct connection *c, int len, int *written)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = write(c->fd, (c->snb->buf + c->snb->s_off), len);
|
||||
if (r <= -1) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
c->flags &= ~CONN_WRITE_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("write: %s", errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
*written = r;
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
int
|
||||
net_read(struct connection *c, int *bytes)
|
||||
{
|
||||
int r;
|
||||
|
||||
r = read(c->fd, (c->rnb->buf + c->rnb->s_off),
|
||||
(c->rnb->b_len - c->rnb->s_off));
|
||||
if (r <= 0) {
|
||||
switch (errno) {
|
||||
case EINTR:
|
||||
case EAGAIN:
|
||||
c->flags &= ~CONN_READ_POSSIBLE;
|
||||
return (KORE_RESULT_OK);
|
||||
default:
|
||||
kore_debug("read(): %s", errno_s);
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
*bytes = r;
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
u_int16_t
|
||||
net_read16(u_int8_t *b)
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue