commit c999bf5001f14c283e9077d1481648ab7d22ac98
parent f59e94a7b666fb55fe164c74b14528a7e97a668d
Author: Joris Vink <joris@coders.se>
Date: Sat, 13 Jul 2013 20:19:01 +0200
Kore can now disconnect SPDY session if they've been idle too long.
Configurable via spdy_idle_time in your configuration file.
Setting this to 0 will keep SPDY sessions open indefinately.
Diffstat:
6 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/includes/kore.h b/includes/kore.h
@@ -188,6 +188,7 @@ extern char *config_file;
extern char kore_version_string[];
extern char *kore_ssl_cipher_list;
+extern u_int64_t spdy_idle_time;
extern u_int32_t meminuse;
extern u_int16_t cpu_count;
extern u_int8_t worker_count;
diff --git a/modules/example/module.conf b/modules/example/module.conf
@@ -29,6 +29,10 @@ load modules/example/example.module
# Specify the SSL ciphers that will be used.
#ssl_cipher HIGH:!aNULL:!MD5;
+# Specify the amount of seconds a SPDY connection is kept open.
+# You can keep it open indefinately by setting this to 0.
+#spdy_idle_time 120
+
# Domain configuration
#
# Each domain configuration starts with listing what domain
diff --git a/src/config.c b/src/config.c
@@ -34,6 +34,7 @@ static int configure_certfile(char **);
static int configure_certkey(char **);
static int configure_max_connections(char **);
static int configure_ssl_cipher(char **);
+static int configure_spdy_idle_time(char **);
static void domain_sslstart(void);
static struct {
@@ -46,6 +47,7 @@ static struct {
{ "static", configure_handler },
{ "dynamic", configure_handler },
{ "ssl_cipher", configure_ssl_cipher },
+ { "spdy_idle_time", configure_spdy_idle_time },
{ "domain", configure_domain },
{ "chroot", configure_chroot },
{ "runas", configure_runas },
@@ -184,6 +186,24 @@ configure_ssl_cipher(char **argv)
}
static int
+configure_spdy_idle_time(char **argv)
+{
+ int err;
+
+ if (argv[1] == NULL)
+ return (KORE_RESULT_ERROR);
+
+ spdy_idle_time = kore_strtonum(argv[1], 0, 65535, &err);
+ if (err != KORE_RESULT_OK) {
+ kore_debug("spdy_idle_time has invalid value: %s", argv[1]);
+ return (KORE_RESULT_ERROR);
+ }
+
+ spdy_idle_time = spdy_idle_time * 1000;
+ return (KORE_RESULT_OK);
+}
+
+static int
configure_domain(char **argv)
{
if (argv[2] == NULL)
diff --git a/src/connection.c b/src/connection.c
@@ -87,8 +87,7 @@ kore_connection_handle(struct connection *c)
kore_debug("kore_connection_handle(%p)", c);
- if (c->proto != CONN_PROTO_SPDY)
- kore_connection_stop_idletimer(c);
+ kore_connection_stop_idletimer(c);
switch (c->state) {
case CONN_STATE_SSL_SHAKE:
@@ -126,6 +125,7 @@ kore_connection_handle(struct connection *c)
if (data) {
if (!memcmp(data, "spdy/3", MIN(6, len))) {
c->proto = CONN_PROTO_SPDY;
+ c->idle_timer.length = spdy_idle_time;
net_recv_queue(c, SPDY_FRAME_SIZE, 0,
NULL, spdy_frame_recv);
} else if (!memcmp(data, "http/1.1", MIN(8, len))) {
@@ -163,8 +163,7 @@ kore_connection_handle(struct connection *c)
break;
}
- if (c->proto != CONN_PROTO_SPDY)
- kore_connection_start_idletimer(c);
+ kore_connection_start_idletimer(c);
return (KORE_RESULT_OK);
}
diff --git a/src/spdy.c b/src/spdy.c
@@ -35,6 +35,8 @@ static int spdy_zlib_inflate(struct connection *, u_int8_t *,
static int spdy_zlib_deflate(struct connection *, u_int8_t *,
size_t, u_int8_t **, u_int32_t *);
+u_int64_t spdy_idle_time = 120000;
+
int
spdy_frame_recv(struct netbuf *nb)
{
@@ -339,7 +341,7 @@ spdy_session_teardown(struct connection *c, u_int8_t err)
c->flags &= ~CONN_READ_POSSIBLE;
c->flags |= CONN_READ_BLOCK;
- c->idle_timer.length = 5;
+ c->idle_timer.length = 5000;
kore_connection_start_idletimer(c);
}
@@ -540,7 +542,9 @@ spdy_ctrl_frame_window(struct netbuf *nb)
if (s->wsize > 0 && c->flags & CONN_WRITE_BLOCK) {
c->flags &= ~CONN_WRITE_BLOCK;
c->flags |= CONN_WRITE_POSSIBLE;
+
kore_connection_stop_idletimer(c);
+ c->idle_timer.length = spdy_idle_time;
kore_debug("can now send again (%d wsize)", s->wsize);
return (net_send_flush(c));
@@ -638,6 +642,8 @@ 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;
+
+ c->idle_timer.length = 5000;
kore_connection_start_idletimer(c);
}
}
diff --git a/src/worker.c b/src/worker.c
@@ -231,6 +231,7 @@ kore_worker_entry(struct kore_worker *kw)
idle_check = now;
TAILQ_FOREACH(c, &worker_clients, list) {
if (c->proto == CONN_PROTO_SPDY &&
+ c->idle_timer.length == 0 &&
!(c->flags & CONN_WRITE_BLOCK) &&
!(c->flags & CONN_READ_BLOCK))
continue;