From b286cb680326ff31ad3592aeace5962cf0377072 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 19 Feb 2024 11:03:17 +0100 Subject: netwatch-notify: do not update with record in cache Using `:resolve` we have just one address, but chances are several records do exist. These end up in cache, so we are happy to find them there - no need to update then. --- netwatch-notify.rsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index ae9c8a8..77b0e69 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -79,7 +79,8 @@ $ScriptLock $0; :if ([ $IsDNSResolving ] = true) do={ :do { :local Resolve [ :resolve ($HostInfo->"resolve") ]; - :if ($Resolve != $HostVal->"host") do={ + :if ($Resolve != $HostVal->"host" and \ + [ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ $HostInfo->"name") "" ] . "' resolves to different address " . $Resolve . \ -- cgit v1.2.3-54-g00ecf From 471e0ead051117f9c4de71f05d9af0f8d6750931 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 28 Feb 2024 22:56:43 +0100 Subject: doc/netwatch-notify: update for multiple records --- doc/netwatch-notify.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/netwatch-notify.md b/doc/netwatch-notify.md index b673af8..6925ca5 100644 --- a/doc/netwatch-notify.md +++ b/doc/netwatch-notify.md @@ -83,9 +83,9 @@ with a resolvable name: /tool/netwatch/add comment="notify, name=example.com, resolve=example.com"; -But be warned: Dynamic updates will probably cause issues if the name has -more than one record in dns - a high rate of configuration changes (and flash -writes) at least. +This supports multiple A or AAAA records for a name just fine, but be +warned: A CNAME to multiple records will cause a high rate of configuration +changes (and flash writes)! ### No notification on host down -- cgit v1.2.3-54-g00ecf From 1c2048628d68a94e08bfcae98f33bb0bce53a25c Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 26 Feb 2024 08:13:34 +0100 Subject: netwatch-notify: use logical operator, no literal "and" Just like we do everywhere else. --- netwatch-notify.rsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 77b0e69..d2a18ca 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -79,7 +79,7 @@ $ScriptLock $0; :if ([ $IsDNSResolving ] = true) do={ :do { :local Resolve [ :resolve ($HostInfo->"resolve") ]; - :if ($Resolve != $HostVal->"host" and \ + :if ($Resolve != $HostVal->"host" && \ [ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ -- cgit v1.2.3-54-g00ecf From 1344694708eba29f02864f9c5016e835084a0788 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 21 Feb 2024 09:05:29 +0100 Subject: netwatch-notify: handle status "down" in its own condition... ... instead of else-branch. This makes sure to skip hosts that just became "unknown". (Possible soon!) --- netwatch-notify.rsc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index d2a18ca..a562c85 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -125,7 +125,9 @@ $ScriptLock $0; :set ($Metric->"notified") false; :set ($Metric->"parent") ($HostInfo->"parent"); :set ($Metric->"since"); - } else={ + } + + :if ($HostVal->"status" = "down") do={ :set ($Metric->"count-down") ($Metric->"count-down" + 1); :set ($Metric->"count-up") 0; :set ($Metric->"parent") ($HostInfo->"parent"); @@ -178,6 +180,7 @@ $ScriptLock $0; :set ($Metric->"notified") true; } } + :set ($NetwatchNotify->$Name) { "count-down"=($Metric->"count-down"); "count-up"=($Metric->"count-up"); -- cgit v1.2.3-54-g00ecf From b1199ca50a16c9accb9a49ae334c4620a69993cc Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 21 Feb 2024 09:05:52 +0100 Subject: netwatch-notify: ... and switch state to "unknown" on host update --- netwatch-notify.rsc | 1 + 1 file changed, 1 insertion(+) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index a562c85..186ac0a 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -87,6 +87,7 @@ $ScriptLock $0; ", updating.") false; /tool/netwatch/set host=$Resolve $Host; :set ($Metric->"resolve-failcnt") 0; + :set ($HostVal->"status") "unknown"; } } on-error={ :set ($Metric->"resolve-failcnt") ($Metric->"resolve-failcnt" + 1); -- cgit v1.2.3-54-g00ecf From 45875ad68e4898d5c66ee08335e0c32fe04a95a6 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 26 Feb 2024 23:17:07 +0100 Subject: netwatch-notify: simplify the check --- netwatch-notify.rsc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 186ac0a..53ea7e3 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -79,8 +79,7 @@ $ScriptLock $0; :if ([ $IsDNSResolving ] = true) do={ :do { :local Resolve [ :resolve ($HostInfo->"resolve") ]; - :if ($Resolve != $HostVal->"host" && \ - [ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ + :if ([ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ $HostInfo->"name") "" ] . "' resolves to different address " . $Resolve . \ -- cgit v1.2.3-54-g00ecf From c2f5272f18c2161150481b9569ee17bc2c3d2289 Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 27 Feb 2024 17:56:08 +0100 Subject: netwatch-notify: restore the check 🥴 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 28da1da49e275fef6089a103edf6c158bbff317f. Chances are that we have to resolve a CNAME, that does not match when querying the cache. How to handle CNAME do multiple A records? 🤨 --- netwatch-notify.rsc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 53ea7e3..186ac0a 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -79,7 +79,8 @@ $ScriptLock $0; :if ([ $IsDNSResolving ] = true) do={ :do { :local Resolve [ :resolve ($HostInfo->"resolve") ]; - :if ([ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ + :if ($Resolve != $HostVal->"host" && \ + [ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ $HostInfo->"name") "" ] . "' resolves to different address " . $Resolve . \ -- cgit v1.2.3-54-g00ecf From 93bed1b081bb23624b988627d2db6e71d55e796a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Mon, 26 Feb 2024 23:18:02 +0100 Subject: netwatch-notify: work around race condition This used to crash every now and then with: > script;error script error: no such item (4) I guess this is caused by querying the dns cache just exactly when a record expires. The chance is maximized: The script is started by scheduler every minute, and the record's ttl is a multiple of a minute. Let's query records that are not about to expire immediately, and try again. --- netwatch-notify.rsc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 186ac0a..c8de7e1 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -80,14 +80,18 @@ $ScriptLock $0; :do { :local Resolve [ :resolve ($HostInfo->"resolve") ]; :if ($Resolve != $HostVal->"host" && \ - [ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ - $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ - ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ - $HostInfo->"name") "" ] . "' resolves to different address " . $Resolve . \ - ", updating.") false; - /tool/netwatch/set host=$Resolve $Host; - :set ($Metric->"resolve-failcnt") 0; - :set ($HostVal->"status") "unknown"; + [ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ttl>0s ] ] = 0) do={ + :delay 1500ms; + :resolve ($HostInfo->"resolve"); + :if ([ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ + $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ + ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ + $HostInfo->"name") "" ] . "' resolves to different address " . $Resolve . \ + ", updating.") false; + /tool/netwatch/set host=$Resolve $Host; + :set ($Metric->"resolve-failcnt") 0; + :set ($HostVal->"status") "unknown"; + } } } on-error={ :set ($Metric->"resolve-failcnt") ($Metric->"resolve-failcnt" + 1); -- cgit v1.2.3-54-g00ecf From 01d2c3ea7e3b00a3020705120d896fd6689fab1a Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Tue, 27 Feb 2024 23:18:31 +0100 Subject: netwatch-notify: try another workaround The last one did not make it... Perhaps the cache just needs a moment to settle? --- netwatch-notify.rsc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index c8de7e1..5c6ae40 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -79,10 +79,8 @@ $ScriptLock $0; :if ([ $IsDNSResolving ] = true) do={ :do { :local Resolve [ :resolve ($HostInfo->"resolve") ]; - :if ($Resolve != $HostVal->"host" && \ - [ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ttl>0s ] ] = 0) do={ - :delay 1500ms; - :resolve ($HostInfo->"resolve"); + :if ($Resolve != $HostVal->"host") do={ + :delay 100ms; :if ([ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ -- cgit v1.2.3-54-g00ecf From 6f29c640e4e63b6a5e0d986b63dafa54dc2cc3fa Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 28 Feb 2024 22:19:26 +0100 Subject: netwatch-notify: move check in DNS cache to local function --- netwatch-notify.rsc | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 5c6ae40..1b6a005 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -52,6 +52,19 @@ :return ("Ran hook:\n" . $Hook); } +:local ResolveExpected do={ + :local Name [ :tostr $1 ]; + :local Expected [ :tostr $2 ]; + + :delay 100ms; + + :if ([ :len [ /ip/dns/cache/find where name=$Name data=$Expected ] ] > 0) do={ + :return true; + } + + :return false; +} + $ScriptLock $0; :local ScriptFromTerminalCached [ $ScriptFromTerminal $0 ]; @@ -80,8 +93,7 @@ $ScriptLock $0; :do { :local Resolve [ :resolve ($HostInfo->"resolve") ]; :if ($Resolve != $HostVal->"host") do={ - :delay 100ms; - :if ([ :len [ /ip/dns/cache/find where name=($HostInfo->"resolve") data=[ :tostr ($HostVal->"host") ] ] ] = 0) do={ + :if ([ $ResolveExpected ($HostInfo->"resolve") ($HostVal->"host") ] = false) do={ $LogPrintExit2 info $0 ("Name '" . $HostInfo->"resolve" . [ $IfThenElse \ ($HostInfo->"resolve" != $HostInfo->"name") ("' for " . $Type . " '" . \ $HostInfo->"name") "" ] . "' resolves to different address " . $Resolve . \ -- cgit v1.2.3-54-g00ecf From a924de274c482b79777d9c1ca9d2e1d1919155cb Mon Sep 17 00:00:00 2001 From: Christian Hesse Date: Wed, 28 Feb 2024 22:29:55 +0100 Subject: netwatch-notify: handle CNAME to multiple records --- doc/netwatch-notify.md | 6 +++--- netwatch-notify.rsc | 9 +++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/doc/netwatch-notify.md b/doc/netwatch-notify.md index 6925ca5..a7cc2d6 100644 --- a/doc/netwatch-notify.md +++ b/doc/netwatch-notify.md @@ -83,9 +83,9 @@ with a resolvable name: /tool/netwatch/add comment="notify, name=example.com, resolve=example.com"; -This supports multiple A or AAAA records for a name just fine, but be -warned: A CNAME to multiple records will cause a high rate of configuration -changes (and flash writes)! +This supports multiple A or AAAA records for a name just fine, even a CNAME +to those. But be warned: CNAME chains to multiple records will cause a high +rate of configuration changes (and flash writes)! ### No notification on host down diff --git a/netwatch-notify.rsc b/netwatch-notify.rsc index 1b6a005..cd4fc0d 100644 --- a/netwatch-notify.rsc +++ b/netwatch-notify.rsc @@ -62,6 +62,15 @@ :return true; } + :local Cname [ /ip/dns/cache/find where name=$Name type="CNAME" ]; + :if ([ :len $Cname ] > 0) do={ + :set Cname [ /ip/dns/cache/get $Cname data ]; + :set Cname [ :pick $Cname 0 ([ :len $Cname ] - 1) ]; + :if ([ :len [ /ip/dns/cache/find where name=$Cname data=$Expected ] ] > 0) do={ + :return true; + } + } + :return false; } -- cgit v1.2.3-54-g00ecf