#!/bin/bash # The RTR client against a validator that has the real RPKI: what the # daemon ends up with has to be what the validator says it has. # # The lab (lab.sh) gives Routinator made-up data, which says nothing about # ASPAs (Routinator does not take those from a local file) nor about data # of the Internet's size. This does, against a Routinator you run # yourself, which takes a quarter of an hour and some gigabytes the first # time: # # routinator --enable-aspa server --rtr 127.0.0.1:3324 --http 127.0.0.1:8324 # scripts/interop/real-rpki.sh # those are the defaults # scripts/interop/real-rpki.sh 127.0.0.1 3324 http://127.0.0.1:8324 # # The daemon is run with no peers and nothing but the validator # configured, on a port of its own; nothing else is touched. set -euo pipefail cd "$(dirname "$0")/../.." address=${1:-127.0.0.1} port=${2:-3324} validator=${3:-http://127.0.0.1:8324} bgp="${CARGO_TARGET_DIR:-target}/release/bgp" [ -x "$bgp" ] || { echo "$bgp not found: cargo build --release -p bgp" >&2; exit 1; } work=$(mktemp -d) trap 'kill "$pid" 2>/dev/null || true; rm -rf "$work"' EXIT cat > "$work/config.textpb" < "$work/log" 2>&1 & pid=$! for _ in $(seq 600); do if curl -sf http://127.0.0.1:18080/api/rpki | jq -e '.state == "synchronised"' >/dev/null 2>&1; then break fi sleep 0.2 done ours=$(curl -sf http://127.0.0.1:18080/api/rpki) jq -e '.state == "synchronised"' <<<"$ours" >/dev/null || { echo "FAILED: not synchronised: $ours" >&2 tail -n 5 "$work/log" >&2 exit 1 } # What the validator says it has: distinct VRPs, and ASes with an ASPA. theirs=$(curl -sf "$validator/json") their_v4=$(jq '[.roas[] | select(.prefix | contains(":") | not) | {asn, prefix, maxLength}] | unique | length' <<<"$theirs") their_v6=$(jq '[.roas[] | select(.prefix | contains(":")) | {asn, prefix, maxLength}] | unique | length' <<<"$theirs") their_aspas=$(jq '[(.aspas // [])[] | .customer] | unique | length' <<<"$theirs") our_v4=$(jq .vrps_ipv4 <<<"$ours") our_v6=$(jq .vrps_ipv6 <<<"$ours") our_aspas=$(jq .aspas <<<"$ours") echo "RTR version $(jq .protocol_version <<<"$ours"), serial $(jq .serial <<<"$ours")" echo "IPv4 VRPs: validator $their_v4, daemon $our_v4" echo "IPv6 VRPs: validator $their_v6, daemon $our_v6" echo "ASPAs: validator $their_aspas, daemon $our_aspas" # The validator may have moved on a serial between the two looks; a # handful apart is that, more is not. close() { [ $(( $1 > $2 ? $1 - $2 : $2 - $1 )) -le $(( $1 / 200 + 5 )) ]; } close "$their_v4" "$our_v4" && close "$their_v6" "$our_v6" && close "$their_aspas" "$our_aspas" \ || { echo "FAILED: the daemon does not have what the validator has" >&2; exit 1; } [ "$our_v4" -gt 0 ] || { echo "FAILED: no data at all" >&2; exit 1; } echo "ok: the daemon has what the validator has"