Version in base suite: 0.6.2-1 Base version: stayrtr_0.6.2-1 Target version: stayrtr_0.6.2-1+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/stayrtr/stayrtr_0.6.2-1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/stayrtr/stayrtr_0.6.2-1+deb13u1.dsc changelog | 8 +++++ patches/commit-0ac8a9a | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ patches/series | 1 stayrtr.service | 2 - 4 files changed, 86 insertions(+), 1 deletion(-) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp4gzna_9z/stayrtr_0.6.2-1.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmp4gzna_9z/stayrtr_0.6.2-1+deb13u1.dsc: no acceptable signature found diff -Nru stayrtr-0.6.2/debian/changelog stayrtr-0.6.2/debian/changelog --- stayrtr-0.6.2/debian/changelog 2025-03-07 00:25:57.000000000 +0000 +++ stayrtr-0.6.2/debian/changelog 2026-03-02 01:46:51.000000000 +0000 @@ -1,3 +1,11 @@ +stayrtr (0.6.2-1+deb13u1) trixie; urgency=medium + + * Backport the upstream commit 0ac8a9abef021cbd45d362135c8fc25174d752f7 + to stop serving stale VRPs when the validator is stuck. (See #1120625.) + * Use Restart=on-abnormal instead of on-abort. + + -- Marco d'Itri Mon, 02 Mar 2026 02:46:51 +0100 + stayrtr (0.6.2-1) unstable; urgency=medium * New upstream release. 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 00:00:00.000000000 +0000 +++ stayrtr-0.6.2/debian/patches/commit-0ac8a9a 2026-03-02 01:46:51.000000000 +0000 @@ -0,0 +1,76 @@ +From 0ac8a9abef021cbd45d362135c8fc25174d752f7 Mon Sep 17 00:00:00 2001 +From: Lukas Tribus +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 00:00:00.000000000 +0000 +++ stayrtr-0.6.2/debian/patches/series 2026-03-02 01:46:51.000000000 +0000 @@ -0,0 +1 @@ +commit-0ac8a9a diff -Nru stayrtr-0.6.2/debian/stayrtr.service stayrtr-0.6.2/debian/stayrtr.service --- stayrtr-0.6.2/debian/stayrtr.service 2024-11-10 01:10:17.000000000 +0000 +++ stayrtr-0.6.2/debian/stayrtr.service 2026-03-02 01:46:51.000000000 +0000 @@ -7,7 +7,7 @@ ExecStart=/usr/bin/stayrtr $STAYRTR_ARGS Type=exec User=_stayrtr -Restart=on-failure +Restart=on-abnormal PrivateDevices=yes PrivateTmp=yes ProtectClock=yes