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
This commit is contained in:
Thomas Bernard 2024-06-08 23:59:28 +02:00
parent e35ef64459
commit 9339f0e52c
No known key found for this signature in database
GPG Key ID: DB511043A31ACAAF
3 changed files with 23 additions and 9 deletions

View File

@ -1,5 +1,8 @@
$Id: Changelog.txt,v 1.515 2024/03/19 23:40:30 nanard Exp $ $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: 2024/04/29:
ipv6: prefer globally routable addresses ipv6: prefer globally routable addresses

View File

@ -303,6 +303,14 @@ tomato_helper(void)
#endif /* 1 (tomato) */ #endif /* 1 (tomato) */
#endif /* 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() : /* OpenAndConfHTTPSocket() :
* setup the socket used to handle incoming HTTP connections. */ * setup the socket used to handle incoming HTTP connections. */
static int static int
@ -896,7 +904,7 @@ struct runtime_vars {
#ifdef ENABLE_HTTPS #ifdef ENABLE_HTTPS
int https_port; /* HTTPS Port */ int https_port; /* HTTPS Port */
#endif #endif
int notify_interval; /* seconds between SSDP announces */ int notify_interval; /* seconds between SSDP announces. Should be >= 900s */
/* unused rules cleaning related variables : */ /* unused rules cleaning related variables : */
int clean_ruleset_threshold; /* threshold for removing unused rules */ int clean_ruleset_threshold; /* threshold for removing unused rules */
int clean_ruleset_interval; /* (minimum) interval between checks. 0=disabled */ 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 #ifdef ENABLE_HTTPS
v->https_port = -1; v->https_port = -1;
#endif #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_threshold = 20;
v->clean_ruleset_interval = 0; /* interval between ruleset check. 0=disabled */ v->clean_ruleset_interval = 0; /* interval between ruleset check. 0=disabled */
#ifndef DISABLE_CONFIG_FILE #ifndef DISABLE_CONFIG_FILE
@ -2147,6 +2155,7 @@ main(int argc, char * * argv)
fd_set readset; /* for select() */ fd_set readset; /* for select() */
fd_set writeset; fd_set writeset;
struct timeval timeout, timeofday, lasttimeofday = {0, 0}; struct timeval timeout, timeofday, lasttimeofday = {0, 0};
int current_notify_interval; /* with random variation */
int max_fd = -1; int max_fd = -1;
#ifdef USE_MINIUPNPDCTL #ifdef USE_MINIUPNPDCTL
int sctl = -1; int sctl = -1;
@ -2233,6 +2242,7 @@ main(int argc, char * * argv)
memset(&v, 0, sizeof(v)); memset(&v, 0, sizeof(v));
if(init(argc, argv, &v) != 0) if(init(argc, argv, &v) != 0)
return 1; return 1;
current_notify_interval = gen_current_notify_interval(v.notify_interval);
#ifdef ENABLE_HTTPS #ifdef ENABLE_HTTPS
if(init_ssl() < 0) if(init_ssl() < 0)
return 1; return 1;
@ -2658,13 +2668,13 @@ main(int argc, char * * argv)
if(upnp_gettimeofday(&timeofday) < 0) if(upnp_gettimeofday(&timeofday) < 0)
{ {
syslog(LOG_ERR, "gettimeofday(): %m"); syslog(LOG_ERR, "gettimeofday(): %m");
timeout.tv_sec = v.notify_interval; timeout.tv_sec = current_notify_interval;
timeout.tv_usec = 0; timeout.tv_usec = 0;
} }
else else
{ {
/* the comparaison is not very precise but who cares ? */ /* 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)) if (GETFLAG(ENABLEUPNPMASK))
SendSSDPNotifies2(snotify, SendSSDPNotifies2(snotify,
@ -2673,13 +2683,14 @@ main(int argc, char * * argv)
(unsigned short)v.https_port, (unsigned short)v.https_port,
#endif #endif
v.notify_interval << 1); v.notify_interval << 1);
current_notify_interval = gen_current_notify_interval(v.notify_interval);
memcpy(&lasttimeofday, &timeofday, sizeof(struct timeval)); memcpy(&lasttimeofday, &timeofday, sizeof(struct timeval));
timeout.tv_sec = v.notify_interval; timeout.tv_sec = current_notify_interval;
timeout.tv_usec = 0; timeout.tv_usec = 0;
} }
else else
{ {
timeout.tv_sec = lasttimeofday.tv_sec + v.notify_interval timeout.tv_sec = lasttimeofday.tv_sec + current_notify_interval
- timeofday.tv_sec; - timeofday.tv_sec;
if(timeofday.tv_usec > lasttimeofday.tv_usec) if(timeofday.tv_usec > lasttimeofday.tv_usec)
{ {

View File

@ -133,9 +133,9 @@
# Report system uptime instead of daemon uptime # Report system uptime instead of daemon uptime
system_uptime=yes system_uptime=yes
# Notify interval in seconds. default is 30 seconds. # Notify interval in seconds. default is 900 seconds.
#notify_interval=240 # As advised in the standard, announcement have a lifetime double of this value.
notify_interval=60 notify_interval=900
# Unused rules cleaning. # Unused rules cleaning.
# never remove any rule before this threshold for the number # never remove any rule before this threshold for the number