From 9295a00a976df83d2c35a6dc56ceb35c05f692dd Mon Sep 17 00:00:00 2001 From: David Härdeman Date: Mon, 22 Jun 2020 21:59:14 +0200 Subject: Fixup server connection timeouts --- announce.c | 12 +++--------- idle.c | 4 +--- main.c | 3 +++ main.h | 1 + ptimer.c | 37 ++++++++++++++++++++++++++----------- ptimer.h | 14 +++++++++++--- server-proxy.c | 37 ++++++++++++++++++++++++++++++------- server-proxy.h | 3 ++- server.c | 1 + 9 files changed, 78 insertions(+), 34 deletions(-) diff --git a/announce.c b/announce.c index eea668c..673d649 100644 --- a/announce.c +++ b/announce.c @@ -16,7 +16,6 @@ struct announce { struct uring_task task; struct ptimer_task ptask; int mcast_fd; - bool active; }; #define ANNOUNCE_INTERVAL 3 @@ -71,7 +70,7 @@ announce_stop() { struct announce *announce = cfg->announce; - assert_return_silent(announce && announce->active); + assert_return_silent(announce); ptimer_del_task(&announce->ptask); } @@ -91,10 +90,7 @@ announce_start(unsigned duration) DIV_ROUND_UP(duration, ANNOUNCE_INTERVAL)); announce->ptask.times = times; - if (!announce->active) { - ptimer_add_task(&announce->ptask); - announce->active = true; - } + ptimer_add_task(&announce->ptask); } void @@ -114,9 +110,7 @@ announce_init() die("socket: %m"); uring_task_init(&announce->task, "announce", uring_parent(), announce_free); - announce->ptask.interval = ANNOUNCE_INTERVAL; - announce->ptask.cb = announce_cb; - announce->active = false; + ptask_init(&announce->ptask, ANNOUNCE_INTERVAL, 0, announce_cb); announce->mcast_fd = sfd; cfg->announce = announce; } diff --git a/idle.c b/idle.c index 0d13b31..dd1eeee 100644 --- a/idle.c +++ b/idle.c @@ -369,9 +369,7 @@ idle_init() if (!idle) die("malloc: %m"); - idle->ptask.interval = 60; - idle->ptask.times = 0; - idle->ptask.cb = idle_cb; + ptask_init(&idle->ptask, 60, 0, idle_cb); uring_task_init(&idle->task, "idle", uring_parent(), idle_free); ptimer_add_task(&idle->ptask); cfg->idle = idle; diff --git a/main.c b/main.c index 22c14af..111ea33 100644 --- a/main.c +++ b/main.c @@ -343,6 +343,9 @@ const struct { },{ .name = "dns", .val = DBG_DNS, + },{ + .name = "timer", + .val = DBG_TIMER, },{ .name = NULL, .val = 0, diff --git a/main.h b/main.h index c94954a..af21ece 100644 --- a/main.h +++ b/main.h @@ -29,6 +29,7 @@ enum debug_lvl { DBG_IGMP = (0x1 << 14), DBG_SYSD = (0x1 << 15), DBG_DNS = (0x1 << 16), + DBG_TIMER = (0x1 << 17), }; static inline bool diff --git a/ptimer.c b/ptimer.c index 7d8662d..5f9cf5d 100644 --- a/ptimer.c +++ b/ptimer.c @@ -62,19 +62,26 @@ ptimer_tick(struct ptimer *ptimer) unsigned diff = (unsigned)(now - ptimer->previous_time); struct ptimer_task *ptask, *ptmp; - fprintf(stderr, "Got a tick of %u secs\n", diff); + debug(DBG_TIMER, "got a tick of %u secs", diff); list_for_each_entry_safe(ptask, ptmp, &ptimer->ptasks, list) { if (ptask->remain > diff) { ptask->remain -= diff; continue; } + debug(DBG_TIMER, "triggering ptask %p (times %u)", + ptask, ptask->times); + ptask->cb(ptask); ptask->remain = ptask->interval; - if (ptask->times > 0) { - ptask->times--; - if (ptask->times == 0) - list_del(&ptask->list); + + if (ptask->times == 0) + continue; + + ptask->times--; + if (ptask->times == 0) { + ptask->active = false; + list_del(&ptask->list); } } @@ -87,8 +94,10 @@ ptimer_reconfig(struct ptimer *ptimer) struct ptimer_task *ptask; unsigned i = 0; unsigned lowest = ~0; + unsigned interval; if (list_empty(&ptimer->ptasks)) { + debug(DBG_TIMER, "no tasks"); ptimer_set(0, 0); return; } @@ -101,8 +110,10 @@ ptimer_reconfig(struct ptimer *ptimer) intervals[i++] = ptask->interval; } - fprintf(stderr, "Lowest %u GCD is %u\n", lowest, array_gcd(intervals, i)); - ptimer_set(lowest, array_gcd(intervals, i)); + interval = array_gcd(intervals, i); + + debug(DBG_TIMER, "lowest: %u, gcd: %u\n", lowest, interval); + ptimer_set(lowest, interval); } void @@ -110,9 +121,12 @@ ptimer_del_task(struct ptimer_task *ptask) { struct ptimer *ptimer = cfg->ptimer; - assert_return(ptask && ptimer && ptimer->task_count > 0); + assert_return(ptask && ptimer); + assert_return_silent(ptask->active); + assert_return(ptimer->task_count > 0); list_del(&ptask->list); + ptask->active = false; ptimer->task_count--; ptimer_tick(ptimer); ptimer_reconfig(ptimer); @@ -125,8 +139,10 @@ ptimer_add_task(struct ptimer_task *ptask) struct ptimer *ptimer = cfg->ptimer; assert_return(ptask && ptask->interval > 0 && ptask->cb && ptimer); + assert_return_silent(!ptask->active); uring_task_get(&ptimer->task); + ptask->active = true; ptask->remain = ptask->interval; ptimer_tick(ptimer); list_add(&ptask->list, &ptimer->ptasks); @@ -149,7 +165,7 @@ ptimer_free(struct uring_task *task) assert_return(task); - debug(DBG_ANN, "task %p, ptimer %p", task, ptimer); + debug(DBG_TIMER, "task %p, ptimer %p", task, ptimer); xfree(ptimer); cfg->ptimer = NULL; } @@ -159,7 +175,7 @@ ptimer_delete() { assert_return(cfg->ptimer); - debug(DBG_ANN, "closing fd %i", cfg->ptimer->task.fd); + debug(DBG_TIMER, "closing fd %i", cfg->ptimer->task.fd); uring_task_destroy(&cfg->ptimer->task); } @@ -176,7 +192,6 @@ ptimer_cb(struct uring_task *task, int res) return; } - debug(DBG_IGMP, "Called"); ptimer_tick(ptimer); uring_read(&ptimer->task, &ptimer->value, sizeof(ptimer->value), ptimer_cb); } diff --git a/ptimer.h b/ptimer.h index 9ac53f7..0b53590 100644 --- a/ptimer.h +++ b/ptimer.h @@ -2,16 +2,24 @@ #define fooptimerhfoo struct ptimer_task { - /* to be set by caller */ unsigned interval; unsigned times; void (*cb)(struct ptimer_task *); - - /* internal */ + bool active; unsigned remain; struct list_head list; }; +static inline void +ptask_init(struct ptimer_task *ptask, unsigned interval, + unsigned times, void(*cb)(struct ptimer_task *)) +{ + ptask->interval = interval; + ptask->times = times; + ptask->cb = cb; + ptask->active = false; +} + void ptimer_del_task(struct ptimer_task *ptask); void ptimer_add_task(struct ptimer_task *ptask); diff --git a/server-proxy.c b/server-proxy.c index 2e8bbd5..f897aa2 100644 --- a/server-proxy.c +++ b/server-proxy.c @@ -10,6 +10,7 @@ #include "main.h" #include "uring.h" +#include "ptimer.h" #include "server.h" #include "server-proxy.h" #include "utils.h" @@ -121,12 +122,15 @@ proxy_delete(struct server_proxy *proxy) assert_return(proxy); + ptimer_del_task(&proxy->ptask); + if (cfg->splice_supported) { uring_close(&proxy->server->task, proxy->cpipe[PIPE_RD]); uring_close(&proxy->server->task, proxy->cpipe[PIPE_WR]); uring_close(&proxy->server->task, proxy->spipe[PIPE_RD]); uring_close(&proxy->server->task, proxy->spipe[PIPE_WR]); } + uring_task_set_fd(&proxy->servertask, proxy->sfd); uring_task_destroy(&proxy->servertask); uring_task_set_fd(&proxy->clienttask, proxy->cfd); @@ -149,7 +153,6 @@ proxy_client_written(struct uring_task *task, int res) if (res <= 0) { debug(DBG_PROXY, "%s: res: %i", proxy->server->name, res); - uring_task_close_fd(task); proxy_delete(proxy); return; } @@ -169,7 +172,6 @@ proxy_client_read(struct uring_task *task, int res) if (res <= 0) { debug(DBG_PROXY, "%s: res: %i", proxy->server->name, res); - uring_task_close_fd(task); proxy_delete(proxy); return; } @@ -190,7 +192,6 @@ proxy_server_written(struct uring_task *task, int res) if (res <= 0) { debug(DBG_PROXY, "%s: res: %i", proxy->server->name, res); - uring_task_close_fd(task); proxy_delete(proxy); return; } @@ -210,7 +211,6 @@ proxy_server_read(struct uring_task *task, int res) if (res <= 0) { debug(DBG_PROXY, "%s: res: %i", proxy->server->name, res); - uring_task_close_fd(task); proxy_delete(proxy); return; } @@ -303,13 +303,17 @@ proxy_connected_cb(struct connection *conn, bool connected) assert_task_alive(DBG_PROXY, &proxy->clienttask); assert_task_alive(DBG_PROXY, &proxy->servertask); + proxy->connecting = false; if (!connected) { error("%s: proxy connection to remote server failed", proxy->server->name); - proxy_delete(proxy); + if (!proxy->ptask.active) + proxy_delete(proxy); return; } + ptimer_del_task(&proxy->ptask); + proxy->sfd = proxy->servertask.fd; verbose("%s: proxy connection %s -> %s opened", proxy->server->name, @@ -338,6 +342,21 @@ proxy_refdump(struct server_proxy *proxy) uring_task_refdump(&proxy->servertask); } +static void +proxy_connect_timer_cb(struct ptimer_task *ptask) +{ + struct server_proxy *proxy = container_of(ptask, struct server_proxy, ptask); + + assert_return(ptask); + + if (proxy->connecting) + return; + + proxy->connecting = true; + connect_any(&proxy->servertask, &proxy->server->remotes, + &proxy->server_conn, proxy_connected_cb); +} + struct server_proxy * proxy_new(struct server *server, struct saddr *client, int fd) { @@ -381,10 +400,14 @@ proxy_new(struct server *server, struct saddr *client, int fd) uring_task_set_buf(&proxy->servertask, &proxy->serverbuf); list_add(&proxy->list, &server->proxys); + if (server->state != SERVER_STATE_RUNNING) { - /* FIXME: We need to wait for the server to start */ - server_start(server); + server_start(server); + ptask_init(&proxy->ptask, 3, 20, proxy_connect_timer_cb); + ptimer_add_task(&proxy->ptask); } + + proxy->connecting = true; connect_any(&proxy->servertask, &server->remotes, &proxy->server_conn, proxy_connected_cb); diff --git a/server-proxy.h b/server-proxy.h index 14d176d..ee3bda3 100644 --- a/server-proxy.h +++ b/server-proxy.h @@ -16,8 +16,9 @@ struct server_proxy { int spipe[2]; int sfd; + bool connecting; time_t begin; - unsigned next_remote; + struct ptimer_task ptask; struct uring_task task; struct server *server; struct list_head list; diff --git a/server.c b/server.c index e1c2f4b..379adb8 100644 --- a/server.c +++ b/server.c @@ -13,6 +13,7 @@ #include "main.h" #include "uring.h" +#include "ptimer.h" #include "server.h" #include "server-proxy.h" #include "utils.h" -- cgit v1.2.3