From 9339f0e52c7a1d2024377e7a2446e80b93d334aa Mon Sep 17 00:00:00 2001 From: Thomas Bernard Date: Sat, 8 Jun 2024 23:59:28 +0200 Subject: [PATCH] miniupnpd: default NOTIFY interval of 900s minus a random value fixes #698 As advised in UDA: Due to the unreliable nature of UDP, devices SHOULD send the entire set of discovery messages more than once with some delay between sets e.g. a few hundred milliseconds. To avoid network congestion discovery messages SHOULD NOT be sent more than three times. In addition, the device MUST re-send its advertisements periodically prior to expiration of the duration specified in the CACHE-CONTROL header field; it is RECOMMENDED that such refreshing of advertisements be done at a randomly-distributed interval of less than one-half of the advertisement expiration time. (CACHE-CONTROL value is minimum 1800 seconds, so the interval should be less than 900s --- miniupnpd/Changelog.txt | 3 +++ miniupnpd/miniupnpd.c | 23 +++++++++++++++++------ miniupnpd/miniupnpd.conf | 6 +++--- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/miniupnpd/Changelog.txt b/miniupnpd/Changelog.txt index 7874cb5..f3e3ad6 100644 --- a/miniupnpd/Changelog.txt +++ b/miniupnpd/Changelog.txt @@ -1,5 +1,8 @@ $Id: Changelog.txt,v 1.515 2024/03/19 23:40:30 nanard Exp $ +2024/06/09: + default NOTIFY interval of 900s minus a random value + 2024/04/29: ipv6: prefer globally routable addresses diff --git a/miniupnpd/miniupnpd.c b/miniupnpd/miniupnpd.c index d4e1b14..506ef44 100644 --- a/miniupnpd/miniupnpd.c +++ b/miniupnpd/miniupnpd.c @@ -303,6 +303,14 @@ tomato_helper(void) #endif /* 1 (tomato) */ #endif /* TOMATO */ +static int gen_current_notify_interval(int notify_interval) { + /* if possible, remove a random number of seconds between 1 and 64 */ + if (notify_interval > 65) + return notify_interval - 1 - (random() & 0x3f); + else + return notify_interval; +} + /* OpenAndConfHTTPSocket() : * setup the socket used to handle incoming HTTP connections. */ static int @@ -896,7 +904,7 @@ struct runtime_vars { #ifdef ENABLE_HTTPS int https_port; /* HTTPS Port */ #endif - int notify_interval; /* seconds between SSDP announces */ + int notify_interval; /* seconds between SSDP announces. Should be >= 900s */ /* unused rules cleaning related variables : */ int clean_ruleset_threshold; /* threshold for removing unused rules */ int clean_ruleset_interval; /* (minimum) interval between checks. 0=disabled */ @@ -1220,7 +1228,7 @@ init(int argc, char * * argv, struct runtime_vars * v) #ifdef ENABLE_HTTPS v->https_port = -1; #endif - v->notify_interval = 30; /* seconds between SSDP announces */ + v->notify_interval = 900; /* seconds between SSDP announces */ v->clean_ruleset_threshold = 20; v->clean_ruleset_interval = 0; /* interval between ruleset check. 0=disabled */ #ifndef DISABLE_CONFIG_FILE @@ -2147,6 +2155,7 @@ main(int argc, char * * argv) fd_set readset; /* for select() */ fd_set writeset; struct timeval timeout, timeofday, lasttimeofday = {0, 0}; + int current_notify_interval; /* with random variation */ int max_fd = -1; #ifdef USE_MINIUPNPDCTL int sctl = -1; @@ -2233,6 +2242,7 @@ main(int argc, char * * argv) memset(&v, 0, sizeof(v)); if(init(argc, argv, &v) != 0) return 1; + current_notify_interval = gen_current_notify_interval(v.notify_interval); #ifdef ENABLE_HTTPS if(init_ssl() < 0) return 1; @@ -2658,13 +2668,13 @@ main(int argc, char * * argv) if(upnp_gettimeofday(&timeofday) < 0) { syslog(LOG_ERR, "gettimeofday(): %m"); - timeout.tv_sec = v.notify_interval; + timeout.tv_sec = current_notify_interval; timeout.tv_usec = 0; } else { /* the comparaison is not very precise but who cares ? */ - if(timeofday.tv_sec >= (lasttimeofday.tv_sec + v.notify_interval)) + if(timeofday.tv_sec >= (lasttimeofday.tv_sec + current_notify_interval)) { if (GETFLAG(ENABLEUPNPMASK)) SendSSDPNotifies2(snotify, @@ -2673,13 +2683,14 @@ main(int argc, char * * argv) (unsigned short)v.https_port, #endif v.notify_interval << 1); + current_notify_interval = gen_current_notify_interval(v.notify_interval); memcpy(&lasttimeofday, &timeofday, sizeof(struct timeval)); - timeout.tv_sec = v.notify_interval; + timeout.tv_sec = current_notify_interval; timeout.tv_usec = 0; } else { - timeout.tv_sec = lasttimeofday.tv_sec + v.notify_interval + timeout.tv_sec = lasttimeofday.tv_sec + current_notify_interval - timeofday.tv_sec; if(timeofday.tv_usec > lasttimeofday.tv_usec) { diff --git a/miniupnpd/miniupnpd.conf b/miniupnpd/miniupnpd.conf index 9bf0c69..9b591a3 100644 --- a/miniupnpd/miniupnpd.conf +++ b/miniupnpd/miniupnpd.conf @@ -133,9 +133,9 @@ # Report system uptime instead of daemon uptime system_uptime=yes -# Notify interval in seconds. default is 30 seconds. -#notify_interval=240 -notify_interval=60 +# Notify interval in seconds. default is 900 seconds. +# As advised in the standard, announcement have a lifetime double of this value. +notify_interval=900 # Unused rules cleaning. # never remove any rule before this threshold for the number