Remove RTR request session vs negotiated session check
I complained about this on sidrops:
https://mailarchive.ietf.org/arch/msg/sidrops/IqvFzvZcSkBN_9gQAwUKAJtIRko/
The hack was too horrid, so I decided to remove it, at least for this
release.
The request session is now only compared to the cache session.
Fort does not care whether the client sustains a constant session.
As long as it's a valid cached session, it's fine. It can ask for many
sessions if it wants.
In practice, all this means is the Corrupt Data is switched for a
Cache Reset.
Whatever. The client will be none the wiser, and the end result will be
the same (a new Cache Request).
It used to be caching incremental deltas between RTR serials.
Then, because the only thing that matters in the end is the net delta
between the router's serial and the latest, it was building up the net
delta from the incremental ones.
The complexity was O(n^2), where n is the total VRPs + RKs + ASPAs
across all involved incremental deltas. Under normal load, n seems to
tend to be small. But that's asking for trouble. Also, the algorithm
also had to allocate n objects, which is rather excessive for a Serial
Query handler.
There was also the issue that all the RTR data was cached in RAM,
which means the RTR session had to change every time Fort was
restarted. And this memory usage wasn't terribly insignificant.
And also, computing a net delta from incremental ASPAs is awkward.
Because ASPAs that share customerAS are supposed to override each other,
they cancel out differently from VRPs.
So I ended up rewriting the entire RTR session caching code.
The Serial Query handler now computes net deltas from RTR snapshots.
The snapshots are stored in the cache, not RAM.
Complexity is O(m), where m is the total VRPs + RKs + ASPAs of the two
relevant snapshots. So m tends to be large, but it degrades much
healthier. The handler also allocates very little memory.
It's a temporal hack; not safe because of the multithreading.
It's meant to be enabled during the controlled environment of Rapport
tests, and nowhere else.
Compile with -DOVERRIDE_SIGTERM to enable.
In general, the openmetrics Content-Type is preferred. The code makes
an exception out of browsers, however.
The full logic is
- If the request has no Accept header, Content-Type will be openmetrics
1.0.0.
- If the Accept header expects neither openmetrics nor plaintext,
Content-Type will be plaintext 0.0.4.
This is because the client is usually a browser (which seem to typically
lack Openmetrics handlers) or a generic HTTP client like curl (which
don't really care about Content-Type).
- Otherwise Fort will decide between openmetrics 1.0.0 or plaintext
0.0.4, depending on q-values. (Requested version will be ignored,
because only one is supported for each.) If their q is the same,
openmetrics will be preferred.
fort_valid_vrps_total{ta="<TA>",proto="ipv<IP>"}
Total VRPs generated from TA <TA> (and the given
protocol) during the previous cycle.
"<TA>" is inferred from the TAL's file name.
fort_rtr_current_connections
Number of active RTR clients.
To activate the server, set --mode=server and --prometheus.port to an
allowed and available port number.
Stop rejecting RPPs if unrecognizable absent files are fileListed
RFC 9286:
> The RP MUST acquire all of the files enumerated in the manifest
> (fileList) from the publication point. If there are files listed in
> the manifest that cannot be retrieved from the publication point,
> the RP MUST treat this as a failed fetch.
This was clashing with Fort's default rsync filters because they were
preventing unknown extensions from being downloaded:
Which will be a problem whenever the IETF defines new legal repository
extensions, such as .asa.
Therefore, ignore unknown manifest fileList extensions. This technically
violates RFC 9286, but it's necessary evil given that we can't trust
repositories to always only serve proper RPKI content.
The code was assuming the object was DER-encoded, and the relevant
integer was therefore in short form.
Because I postponed the DER enforcement in deef7b7823f21914b17838f152a8bd510a348f54, the code should not make
reckless assumptions about the signedAttrs encoding.
Job Snijders [Tue, 25 Jun 2024 05:21:39 +0000 (05:21 +0000)]
Generate all permutations of the list with equal probability
@botovq was kind enough to point out that although my earlier
implementation produced random-ish ordering, it strictly speaking
wasn't Fisher-Yates.
We need to ensure `j` is a random number between `i` and `list.count`
see the second example in the 'Modern Algorithm'
https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle
Job Snijders [Thu, 13 Jun 2024 18:21:36 +0000 (18:21 +0000)]
Shuffle the order in which Manifest entries are processed
Previously work items were enqueued in the order the CA intended them
to appear on a Manifest. However, there is no obvious benefit to letting
third parties decide the order in which objects are processed.
Instead, randomize the list of FileAndHashes, its ordering has no meaning
anyway. As they say, a fox is not taken twice in the same snare
Job Snijders [Fri, 7 Jun 2024 17:09:44 +0000 (17:09 +0000)]
Verify the signature on a self-signed TA cert against it's own pubkey
X509_verify_cert() doesn't check the purported root certificate itself
unless X509_V_FLAG_CHECK_SS_SIGNATURE is set.
The pubkey was compared against the TAL, so check that the signature is
right as required by RFC 6487, section 7, additional condition 1,
applied to self-issued certs.
The error check looks weird, but OpenSSL 3 broke yet another API.