mirror of https://git.kore.io/kore.git
- add idle timer for normal connections (ie: !SPDY), max 20 seconds.
- use idle timer to make sure we don't block SPDY connections indefinately when our window size has reached 0.
This commit is contained in:
parent
a2392e645f
commit
0c08b57d3e
|
@ -75,6 +75,9 @@ struct listener {
|
|||
#define CONN_READ_POSSIBLE 0x01
|
||||
#define CONN_WRITE_POSSIBLE 0x02
|
||||
#define CONN_WRITE_BLOCK 0x04
|
||||
#define CONN_IDLE_TIMER_ACT 0x10
|
||||
|
||||
#define KORE_IDLE_TIMER_MAX 20000
|
||||
|
||||
struct connection {
|
||||
int fd;
|
||||
|
@ -85,6 +88,11 @@ struct connection {
|
|||
SSL *ssl;
|
||||
u_int8_t flags;
|
||||
|
||||
struct {
|
||||
u_int64_t length;
|
||||
u_int64_t start;
|
||||
} idle_timer;
|
||||
|
||||
u_int8_t inflate_started;
|
||||
z_stream z_inflate;
|
||||
u_int8_t deflate_started;
|
||||
|
@ -203,6 +211,9 @@ 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);
|
||||
|
|
|
@ -77,11 +77,15 @@ kore_connection_accept(struct listener *l, struct connection **out)
|
|||
c->proto = CONN_PROTO_UNKNOWN;
|
||||
c->state = CONN_STATE_SSL_SHAKE;
|
||||
c->wsize_initial = 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));
|
||||
|
||||
kore_worker_connection_add(c);
|
||||
kore_connection_start_idletimer(c);
|
||||
|
||||
*out = c;
|
||||
return (KORE_RESULT_OK);
|
||||
|
@ -106,6 +110,9 @@ kore_connection_handle(struct connection *c)
|
|||
|
||||
kore_debug("kore_connection_handle(%p)", c);
|
||||
|
||||
if (c->proto != CONN_PROTO_SPDY)
|
||||
kore_connection_stop_idletimer(c);
|
||||
|
||||
switch (c->state) {
|
||||
case CONN_STATE_SSL_SHAKE:
|
||||
if (c->ssl == NULL) {
|
||||
|
@ -173,6 +180,9 @@ kore_connection_handle(struct connection *c)
|
|||
break;
|
||||
}
|
||||
|
||||
if (c->proto != CONN_PROTO_SPDY)
|
||||
kore_connection_start_idletimer(c);
|
||||
|
||||
return (KORE_RESULT_OK);
|
||||
}
|
||||
|
||||
|
@ -225,6 +235,36 @@ kore_connection_remove(struct connection *c)
|
|||
kore_mem_free(c);
|
||||
}
|
||||
|
||||
void
|
||||
kore_connection_check_idletimer(u_int64_t now, struct connection *c)
|
||||
{
|
||||
u_int64_t d;
|
||||
|
||||
d = now - c->idle_timer.start;
|
||||
if (d >= c->idle_timer.length) {
|
||||
kore_debug("%p idle for %d ms, expiring", c, d);
|
||||
kore_connection_disconnect(c);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
kore_connection_start_idletimer(struct connection *c)
|
||||
{
|
||||
kore_debug("kore_connection_start_idletimer(%p)", c);
|
||||
|
||||
c->flags |= CONN_IDLE_TIMER_ACT;
|
||||
c->idle_timer.start = kore_time_ms();
|
||||
}
|
||||
|
||||
void
|
||||
kore_connection_stop_idletimer(struct connection *c)
|
||||
{
|
||||
kore_debug("kore_connection_stop_idletimer(%p)", c);
|
||||
|
||||
c->flags &= ~CONN_IDLE_TIMER_ACT;
|
||||
c->idle_timer.start = 0;
|
||||
}
|
||||
|
||||
int
|
||||
kore_connection_nonblock(int fd)
|
||||
{
|
||||
|
|
|
@ -259,6 +259,7 @@ http_response(struct http_request *req, int status, u_int8_t *d, u_int32_t len)
|
|||
kore_buf_appendf(buf, "HTTP/1.1 %d\r\n", status);
|
||||
kore_buf_appendf(buf, "Content-length: %d\r\n", len);
|
||||
kore_buf_appendf(buf, "Connection: keep-alive\r\n");
|
||||
kore_buf_appendf(buf, "Keep-Alive: timeout=20\r\n");
|
||||
kore_buf_appendf(buf, "Server: %s\r\n", kore_version_string);
|
||||
|
||||
TAILQ_FOREACH(hdr, &(req->resp_headers), list) {
|
||||
|
|
|
@ -520,6 +520,7 @@ spdy_ctrl_frame_window(struct netbuf *nb)
|
|||
if (s->wsize > 0) {
|
||||
c->flags &= ~CONN_WRITE_BLOCK;
|
||||
c->flags |= CONN_WRITE_POSSIBLE;
|
||||
kore_connection_stop_idletimer(c);
|
||||
|
||||
kore_debug("can now send again (%d wsize)", s->wsize);
|
||||
return (net_send_flush(c));
|
||||
|
@ -606,6 +607,7 @@ spdy_update_wsize(struct connection *c, struct spdy_stream *s, u_int32_t len)
|
|||
kore_debug("window size <= 0 for stream %d", s->stream_id);
|
||||
c->flags &= ~CONN_WRITE_POSSIBLE;
|
||||
c->flags |= CONN_WRITE_BLOCK;
|
||||
kore_connection_start_idletimer(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
15
src/worker.c
15
src/worker.c
|
@ -189,6 +189,7 @@ kore_worker_entry(struct kore_worker *kw)
|
|||
int quit;
|
||||
char buf[16];
|
||||
struct connection *c, *cnext;
|
||||
u_int64_t now, idle_check;
|
||||
|
||||
worker = kw;
|
||||
|
||||
|
@ -216,6 +217,7 @@ kore_worker_entry(struct kore_worker *kw)
|
|||
TAILQ_INIT(&worker_clients);
|
||||
|
||||
quit = 0;
|
||||
now = idle_check = 0;
|
||||
kore_platform_event_init();
|
||||
kore_accesslog_worker_init();
|
||||
|
||||
|
@ -244,6 +246,19 @@ kore_worker_entry(struct kore_worker *kw)
|
|||
|
||||
http_process();
|
||||
|
||||
now = kore_time_ms();
|
||||
if ((now - idle_check) >= 10000) {
|
||||
idle_check = now;
|
||||
TAILQ_FOREACH(c, &worker_clients, list) {
|
||||
if (c->proto == CONN_PROTO_SPDY &&
|
||||
!(c->flags & CONN_WRITE_BLOCK))
|
||||
continue;
|
||||
if (!(c->flags & CONN_IDLE_TIMER_ACT))
|
||||
continue;
|
||||
kore_connection_check_idletimer(now, c);
|
||||
}
|
||||
}
|
||||
|
||||
for (c = TAILQ_FIRST(&disconnected); c != NULL; c = cnext) {
|
||||
cnext = TAILQ_NEXT(c, list);
|
||||
TAILQ_REMOVE(&disconnected, c, list);
|
||||
|
|
Loading…
Reference in New Issue