From 9144339ebe1fa3661b97d2dd68b7c1c4f3fb1e64 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Fri, 16 Sep 2022 15:25:20 +0200 Subject: [PATCH] pex: improve handling of a longer list of PEX hosts Instead of rotating and picking one every 5 seconds, pick one from the list every 500ms, but enforce a minimum interval of 10 seconds per host between pings Signed-off-by: Felix Fietkau --- pex.c | 35 ++++++++++++++++++++++------------- pex.h | 1 + 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/pex.c b/pex.c index 3f28f51..2b83f5d 100644 --- a/pex.c +++ b/pex.c @@ -253,6 +253,8 @@ network_pex_host_request_update(struct network *net, struct network_pex_host *ho char addrstr[INET6_ADDRSTRLEN]; uint64_t version = 0; + host->last_ping = unet_gettime(); + if (net->net_data_len) version = net->net_data_version; @@ -282,23 +284,27 @@ network_pex_request_update_cb(struct uloop_timeout *t) { struct network *net = container_of(t, struct network, pex.request_update_timer); struct network_pex *pex = &net->pex; - struct network_pex_host *host; + struct network_pex_host *host, *tmp; + uint64_t now = unet_gettime(); - uloop_timeout_set(t, 5000); + uloop_timeout_set(t, 500); -retry: if (list_empty(&pex->hosts)) return; - host = list_first_entry(&pex->hosts, struct network_pex_host, list); - if (host->timeout && host->timeout < unet_gettime()) { - list_del(&host->list); - free(host); - goto retry; - } + list_for_each_entry_safe(host, tmp, &pex->hosts, list) { + if (host->timeout && host->timeout < now) { + list_del(&host->list); + free(host); + continue; + } + + if (host->last_ping + 10 >= now) + continue; - list_move_tail(&host->list, &pex->hosts); - network_pex_host_request_update(net, host); + list_move_tail(&host->list, &pex->hosts); + network_pex_host_request_update(net, host); + } } void network_pex_init(struct network *net) @@ -701,13 +707,17 @@ void network_pex_create_host(struct network *net, union network_endpoint *ep, { struct network_pex *pex = &net->pex; struct network_pex_host *host; + uint64_t now = unet_gettime(); bool new_host = false; list_for_each_entry(host, &pex->hosts, list) { if (memcmp(&host->endpoint, ep, sizeof(host->endpoint)) != 0) continue; - list_move_tail(&host->list, &pex->hosts); + if (host->last_ping + 10 < now) { + list_move_tail(&host->list, &pex->hosts); + network_pex_host_request_update(net, host); + } goto out; } @@ -719,7 +729,6 @@ void network_pex_create_host(struct network *net, union network_endpoint *ep, out: if (timeout && (new_host || host->timeout)) host->timeout = timeout + unet_gettime(); - network_pex_host_request_update(net, host); } static void diff --git a/pex.h b/pex.h index acaf372..18f323e 100644 --- a/pex.h +++ b/pex.h @@ -15,6 +15,7 @@ struct network_pex_host { struct list_head list; uint64_t timeout; uint64_t last_active; + uint64_t last_ping; union network_endpoint endpoint; }; -- 2.30.2