Package: release.debian.org
Severity: normal
Tags: trixie
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:stayrtr
User: [email protected]
Usertags: pu

This release contains the backport of an upstream commit which stops
the daemon from serving stale data to routers.
It has been strongly requested by the operators community.

The same change has been in testing for over one month in release 
0.6.2+20251113-1.

diff -Nru stayrtr-0.6.2/debian/changelog stayrtr-0.6.2/debian/changelog
--- stayrtr-0.6.2/debian/changelog      2025-04-04 00:34:18.000000000 +0200
+++ stayrtr-0.6.2/debian/changelog      2026-01-04 19:32:17.000000000 +0100
@@ -1,3 +1,10 @@
+stayrtr (0.6.2-1~bpo12+2) bookworm-backports; urgency=medium
+
+  * Backport the upstream commit 0ac8a9abef021cbd45d362135c8fc25174d752f7
+    to stop serving stale VRPs when the validator is stuck. (See #1120625.)
+
+ -- Marco d'Itri <[email protected]>  Sun, 04 Jan 2026 19:32:17 +0100
+
 stayrtr (0.6.2-1~bpo12+1) bookworm-backports; urgency=medium
 
   * Rebuild for bookworm-backports.
diff -Nru stayrtr-0.6.2/debian/patches/commit-0ac8a9a 
stayrtr-0.6.2/debian/patches/commit-0ac8a9a
--- stayrtr-0.6.2/debian/patches/commit-0ac8a9a 1970-01-01 01:00:00.000000000 
+0100
+++ stayrtr-0.6.2/debian/patches/commit-0ac8a9a 2026-01-04 19:25:10.000000000 
+0100
@@ -0,0 +1,76 @@
+From 0ac8a9abef021cbd45d362135c8fc25174d752f7 Mon Sep 17 00:00:00 2001
+From: Lukas Tribus <[email protected]>
+Date: Tue, 2 Sep 2025 18:31:24 +0000
+Subject: Avoid sending stale data, properly handle errRPKIJsonFileTooOld
+
+Both updateFromNewState() and reloadFromCurrentState() can return
+errRPKIJsonFileTooOld.
+
+However the RTR clearing code that would withdraw all VRPs is only in the call
+site of updateFromNewState(), which is not called when the JSON file is stuck,
+because CacheUpdated is false (as updateFile() returns false, IdenticalFile).
+
+That is why with a hung RPKI validator and logging turned up to info we see:
+
+File /var/lib/rpki-client/json is identical to the previous version
+RPKI JSON file is older than 24 hours: 2025-09-01 16:29:30 +0000 UTC
+Error updating state: RPKI JSON file is older than 24 hours
+
+But no clearing of the VRPs occurs, because the reloadFromCurrentState()
+caller doesn't handle errRPKIJsonFileTooOld specifically and just prints
+an error.
+
+Move errRPKIJsonFileTooOld handling into it's own function and call the
+handler from both call sites. Although I'm not sure about the use-case for
+updateFromNewState(), if it is returning errRPKIJsonFileTooOld I want to
+handle it properly. I also want to avoid duplicate handling code, because
+that will bite us again in the future if this code ever changes.
+
+diff --git a/cmd/stayrtr/stayrtr.go b/cmd/stayrtr/stayrtr.go
+index c712b59..510de70 100644
+--- a/cmd/stayrtr/stayrtr.go
++++ b/cmd/stayrtr/stayrtr.go
+@@ -539,6 +539,16 @@ func (s *state) updateDelay(delay *time.Ticker, interval 
int) {
+       }
+ }
+ 
++func (s *state) errRPKIJsonFileTooOldHandler() {
++      // If the exiting build time is over 24 hours, It's time to drop 
everything out.
++      // to avoid routing on stale data
++      buildTime := s.exported.Metadata.GetBuildTime()
++      if !buildTime.IsZero() && time.Since(buildTime) > time.Hour*24 {
++              log.Errorf("Data is stale, clearing it all.")
++              s.server.AddData([]rtr.SendableData{}) // empty the store of 
sendable stuff, triggering a emptying of the RTR server
++      }
++}
++
+ func (s *state) routineUpdate(file string, interval int, slurmFile string) {
+       log.Debugf("Starting refresh routine (file: %v, interval: %vs, slurm: 
%v)", file, interval, slurmFile)
+       signals := make(chan os.Signal, 1)
+@@ -612,20 +622,18 @@ func (s *state) routineUpdate(file string, interval int, 
slurmFile string) {
+               if cacheUpdated || slurmNotPresentOrUpdated {
+                       err := s.updateFromNewState()
+                       if err != nil {
++                              log.Errorf("Error updating from new state: %v", 
err)
+                               if err == errRPKIJsonFileTooOld {
+-                                      // If the exiting build time is over 24 
hours, It's time to drop everything out.
+-                                      // to avoid routing on stale data
+-                                      buildTime := 
s.exported.Metadata.GetBuildTime()
+-                                      if !buildTime.IsZero() && 
time.Since(buildTime) > time.Hour*24 {
+-                                              
s.server.AddData([]rtr.SendableData{}) // empty the store of sendable stuff, 
triggering a emptying of the RTR server
+-                                      }
++                                      s.errRPKIJsonFileTooOldHandler()
+                               }
+-                              log.Errorf("Error updating from new state: %v", 
err)
+                       }
+               } else {
+                       err := s.reloadFromCurrentState()
+                       if err != nil {
+-                              log.Errorf("Error updating state: %v", err)
++                              log.Errorf("Error updating from current state: 
%v", err)
++                              if err == errRPKIJsonFileTooOld {
++                                      s.errRPKIJsonFileTooOldHandler()
++                              }
+                       }
+               }
+       }
diff -Nru stayrtr-0.6.2/debian/patches/series 
stayrtr-0.6.2/debian/patches/series
--- stayrtr-0.6.2/debian/patches/series 1970-01-01 01:00:00.000000000 +0100
+++ stayrtr-0.6.2/debian/patches/series 2026-01-04 19:25:19.000000000 +0100
@@ -0,0 +1 @@
+commit-0ac8a9a

-- 
ciao,
Marco

Attachment: signature.asc
Description: PGP signature

Reply via email to