mirror of
https://github.com/jorisvink/kore
synced 2025-03-09 12:39:01 -04:00
rework disconnecting clients and fix bug where spdy ocnnections could segfault after disconnecting
This commit is contained in:
parent
fdb9004c6d
commit
364dc58219
@ -33,7 +33,6 @@ struct netbuf {
|
||||
u_int32_t offset;
|
||||
u_int32_t len;
|
||||
u_int8_t type;
|
||||
u_int8_t retain;
|
||||
u_int8_t flags;
|
||||
|
||||
void *owner;
|
||||
@ -47,9 +46,10 @@ struct listener {
|
||||
struct sockaddr_in sin;
|
||||
};
|
||||
|
||||
#define CONN_STATE_UNKNOWN 0
|
||||
#define CONN_STATE_SSL_SHAKE 1
|
||||
#define CONN_STATE_ESTABLISHED 2
|
||||
#define CONN_STATE_UNKNOWN 0
|
||||
#define CONN_STATE_SSL_SHAKE 1
|
||||
#define CONN_STATE_ESTABLISHED 2
|
||||
#define CONN_STATE_DISCONNECTING 3
|
||||
|
||||
#define CONN_PROTO_UNKNOWN 0
|
||||
#define CONN_PROTO_SPDY 1
|
||||
@ -59,6 +59,7 @@ struct listener {
|
||||
#define CONN_WRITE_POSSIBLE 0x02
|
||||
|
||||
#define NETBUF_CALL_CB_ALWAYS 0x01
|
||||
#define NETBUF_FORCE_REMOVE 0x02
|
||||
|
||||
struct connection {
|
||||
int fd;
|
||||
@ -79,6 +80,8 @@ struct connection {
|
||||
|
||||
u_int32_t client_stream_id;
|
||||
TAILQ_HEAD(, spdy_stream) spdy_streams;
|
||||
|
||||
TAILQ_ENTRY(connection) list;
|
||||
};
|
||||
|
||||
#define HANDLER_TYPE_STATIC 1
|
||||
|
20
src/http.c
20
src/http.c
@ -222,7 +222,7 @@ void
|
||||
http_process(void)
|
||||
{
|
||||
struct http_request *req, *next;
|
||||
int (*handler)(struct http_request *);
|
||||
int r, (*handler)(struct http_request *);
|
||||
|
||||
if (TAILQ_EMPTY(&http_requests))
|
||||
return;
|
||||
@ -232,15 +232,16 @@ http_process(void)
|
||||
next = TAILQ_NEXT(req, list);
|
||||
|
||||
handler = kore_module_handler_find(req->path);
|
||||
if (handler == NULL) {
|
||||
if (!http_generic_404(req))
|
||||
kore_server_disconnect(req->owner);
|
||||
} else {
|
||||
if (!handler(req))
|
||||
kore_server_disconnect(req->owner);
|
||||
}
|
||||
if (handler == NULL)
|
||||
r = http_generic_404(req);
|
||||
else
|
||||
r = handler(req);
|
||||
|
||||
if (r != KORE_RESULT_ERROR)
|
||||
net_send_flush(req->owner);
|
||||
else
|
||||
kore_server_disconnect(req->owner);
|
||||
|
||||
net_send_flush(req->owner);
|
||||
TAILQ_REMOVE(&http_requests, req, list);
|
||||
http_request_free(req);
|
||||
}
|
||||
@ -265,6 +266,7 @@ http_header_recv(struct netbuf *nb)
|
||||
if (nb->len > 2 && strncmp((p - 2), "\r\n\r\n", 4))
|
||||
return (KORE_RESULT_OK);
|
||||
|
||||
nb->flags |= NETBUF_FORCE_REMOVE;
|
||||
hbuf = kore_strdup((const char *)nb->buf);
|
||||
|
||||
h = kore_split_string(hbuf, "\r\n", headers, HTTP_REQ_HEADER_MAX);
|
||||
|
29
src/kore.c
29
src/kore.c
@ -43,6 +43,9 @@
|
||||
|
||||
static int efd = -1;
|
||||
static SSL_CTX *ssl_ctx = NULL;
|
||||
|
||||
static TAILQ_HEAD(, connection) disconnected;
|
||||
|
||||
int server_port = 0;
|
||||
char *server_ip = NULL;
|
||||
|
||||
@ -51,16 +54,17 @@ static int kore_server_sslstart(void);
|
||||
static void kore_event(int, int, void *);
|
||||
static int kore_server_accept(struct listener *);
|
||||
static int kore_connection_handle(struct connection *, int);
|
||||
static void kore_server_final_disconnect(struct connection *);
|
||||
static int kore_server_bind(struct listener *, const char *, int);
|
||||
static int kore_ssl_npn_cb(SSL *, const u_char **, unsigned int *, void *);
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
struct connection *c;
|
||||
struct listener server;
|
||||
struct epoll_event *events;
|
||||
int n, i, *fd;
|
||||
struct connection *c, *cnext;
|
||||
|
||||
if (argc != 2)
|
||||
fatal("Usage: kore [config file]");
|
||||
@ -80,6 +84,7 @@ main(int argc, char *argv[])
|
||||
fatal("epoll_create(): %s", errno_s);
|
||||
|
||||
http_init();
|
||||
TAILQ_INIT(&disconnected);
|
||||
|
||||
kore_event(server.fd, EPOLLIN, &server);
|
||||
events = kore_calloc(EPOLL_EVENTS, sizeof(struct epoll_event));
|
||||
@ -116,12 +121,28 @@ main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
http_process();
|
||||
|
||||
for (c = TAILQ_FIRST(&disconnected); c != NULL; c = cnext) {
|
||||
cnext = TAILQ_NEXT(c, list);
|
||||
TAILQ_REMOVE(&disconnected, c, list);
|
||||
kore_server_final_disconnect(c);
|
||||
}
|
||||
}
|
||||
|
||||
close(server.fd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
kore_server_disconnect(struct connection *c)
|
||||
{
|
||||
if (c->state != CONN_STATE_DISCONNECTING) {
|
||||
kore_log("preparing %p for disconnection", c);
|
||||
c->state = CONN_STATE_DISCONNECTING;
|
||||
TAILQ_INSERT_TAIL(&disconnected, c, list);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
kore_server_sslstart(void)
|
||||
{
|
||||
@ -230,13 +251,13 @@ kore_server_accept(struct listener *l)
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
void
|
||||
kore_server_disconnect(struct connection *c)
|
||||
static void
|
||||
kore_server_final_disconnect(struct connection *c)
|
||||
{
|
||||
struct netbuf *nb, *next;
|
||||
struct spdy_stream *s, *snext;
|
||||
|
||||
kore_log("kore_server_disconnect(%p)", c);
|
||||
kore_log("kore_server_final_disconnect(%p)", c);
|
||||
|
||||
close(c->fd);
|
||||
if (c->ssl != NULL)
|
||||
|
27
src/net.c
27
src/net.c
@ -50,7 +50,6 @@ net_send_queue(struct connection *c, u_int8_t *data, size_t len, int flags,
|
||||
nb->len = len;
|
||||
nb->owner = c;
|
||||
nb->offset = 0;
|
||||
nb->retain = 0;
|
||||
nb->flags = flags;
|
||||
nb->type = NETBUF_SEND;
|
||||
|
||||
@ -81,7 +80,6 @@ net_recv_queue(struct connection *c, size_t len, int flags,
|
||||
nb->len = len;
|
||||
nb->owner = c;
|
||||
nb->offset = 0;
|
||||
nb->retain = 0;
|
||||
nb->flags = flags;
|
||||
nb->type = NETBUF_RECV;
|
||||
nb->buf = (u_int8_t *)kore_malloc(nb->len);
|
||||
@ -109,7 +107,7 @@ net_recv_expand(struct connection *c, struct netbuf *nb, size_t len,
|
||||
nb->buf = (u_int8_t *)kore_realloc(nb->buf, nb->len);
|
||||
TAILQ_INSERT_HEAD(&(c->recv_queue), nb, list);
|
||||
|
||||
return (net_recv(c));
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
int
|
||||
@ -129,8 +127,8 @@ net_send(struct connection *c)
|
||||
|
||||
r = SSL_write(c->ssl, (nb->buf + nb->offset), (nb->len - nb->offset));
|
||||
|
||||
//kore_log("net_send(%ld/%ld bytes), progress with %d",
|
||||
// nb->offset, nb->len, r);
|
||||
kore_log("net_send(%ld/%ld bytes), progress with %d",
|
||||
nb->offset, nb->len, r);
|
||||
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
@ -146,7 +144,7 @@ net_send(struct connection *c)
|
||||
}
|
||||
|
||||
nb->offset += (size_t)r;
|
||||
if (nb->offset == nb->len || (nb->flags & NETBUF_CALL_CB_ALWAYS)) {
|
||||
if (nb->offset == nb->len) {
|
||||
if (nb->offset == nb->len)
|
||||
TAILQ_REMOVE(&(c->send_queue), nb, list);
|
||||
|
||||
@ -169,6 +167,8 @@ net_send(struct connection *c)
|
||||
int
|
||||
net_send_flush(struct connection *c)
|
||||
{
|
||||
kore_log("net_send_flush(%p)", c);
|
||||
|
||||
while (!TAILQ_EMPTY(&(c->send_queue)) &&
|
||||
(c->flags & CONN_WRITE_POSSIBLE)) {
|
||||
if (!net_send(c))
|
||||
@ -190,8 +190,8 @@ net_recv(struct connection *c)
|
||||
nb = TAILQ_FIRST(&(c->recv_queue));
|
||||
r = SSL_read(c->ssl, (nb->buf + nb->offset), (nb->len - nb->offset));
|
||||
|
||||
//kore_log("net_recv(%ld/%ld bytes), progress with %d",
|
||||
// nb->offset, nb->len, r);
|
||||
kore_log("net_recv(%ld/%ld bytes), progress with %d",
|
||||
nb->offset, nb->len, r);
|
||||
|
||||
if (r <= 0) {
|
||||
r = SSL_get_error(c->ssl, r);
|
||||
@ -213,13 +213,10 @@ net_recv(struct connection *c)
|
||||
return (KORE_RESULT_ERROR);
|
||||
}
|
||||
|
||||
nb->retain++;
|
||||
if (nb->offset == nb->len)
|
||||
TAILQ_REMOVE(&(c->recv_queue), nb, list);
|
||||
r = nb->cb(nb);
|
||||
nb->retain--;
|
||||
|
||||
if (nb->retain == 0 && nb->offset == nb->len) {
|
||||
if (nb->offset == nb->len ||
|
||||
(nb->flags & NETBUF_FORCE_REMOVE)) {
|
||||
TAILQ_REMOVE(&(c->recv_queue), nb, list);
|
||||
free(nb->buf);
|
||||
free(nb);
|
||||
}
|
||||
@ -233,6 +230,8 @@ net_recv(struct connection *c)
|
||||
int
|
||||
net_recv_flush(struct connection *c)
|
||||
{
|
||||
kore_log("net_recv_flush(%p)", c);
|
||||
|
||||
while (!TAILQ_EMPTY(&(c->recv_queue)) &&
|
||||
(c->flags & CONN_READ_POSSIBLE)) {
|
||||
if (!net_recv(c))
|
||||
|
Loading…
x
Reference in New Issue
Block a user