Add WASM sandbox, bench harness, and cache CDB at startup

Jaime Fournier <jaimef@linbsd.org>

94c84a634b09d4a2bcaabd0f92dedcda443d0e63

diff --git a/.gitignore b/.gitignore
index 42ca438..3b309bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,7 +2,7 @@
 *.so
 *.wpo
 
-# CDB data files
+# CDB data files (generated from .data via bench/gen-zone.sh)
 *.cdb
 
 # Static build artifacts
@@ -12,3 +12,13 @@ static/*.h
 static/jdns
 static/jdns-data
 static/jdns-debug
+
+# Bench logs and server-stderr dumps (large, regenerable)
+bench/logs/
+bench/results/**/*-server.log
+bench/results/**/*-server.log.pid
+bench/results/**/*.pid
+
+# Rust wasm build artifacts (the lib/jerboa-dns/sandbox/*.wasm outputs
+# are committed; the intermediate target/ dir is not)
+wasm/target/
diff --git a/Makefile b/Makefile
index 0e79aea..183c050 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,15 @@ SCHEME ?= $(JERBOA_HOME)/.chez/bin/scheme
 JERBOA ?= $(JERBOA_HOME)/lib
 LIBDIRS = lib:$(JERBOA)
 
-.PHONY: all build test clean jdns jdns-data
+WASM_DIR = wasm
+WASM_DNS_OUT = lib/jerboa-dns/sandbox/dns_parser.wasm
+WASM_CDB_OUT = lib/jerboa-dns/sandbox/cdb_parser.wasm
+WASM_OUTPUTS = $(WASM_DNS_OUT) $(WASM_CDB_OUT)
+WASM_SOURCES = $(WASM_DIR)/Cargo.toml \
+               $(WASM_DIR)/dns/Cargo.toml $(WASM_DIR)/dns/src/lib.rs \
+               $(WASM_DIR)/cdb/Cargo.toml $(WASM_DIR)/cdb/src/lib.rs
+
+.PHONY: all build test clean jdns jdns-data wasm wasm-clean
 
 all: build
 
@@ -11,6 +19,16 @@ build:
 	@echo "Compiling jerboa-dns libraries..."
 	@$(SCHEME) --libdirs "$(LIBDIRS)" --compile-imported-libraries --script build.ss
 
+# Build the sandboxed DNS parser and CDB lookup engine as WebAssembly
+# modules. Requires rustup with the wasm32-unknown-unknown target installed.
+wasm: $(WASM_OUTPUTS)
+
+$(WASM_OUTPUTS): $(WASM_SOURCES)
+	@$(WASM_DIR)/build.sh
+
+wasm-clean:
+	rm -rf $(WASM_DIR)/target $(WASM_OUTPUTS)
+
 jdns: build
 	$(SCHEME) --libdirs "$(LIBDIRS)" --script bin/jdns.ss
 
@@ -19,8 +37,14 @@ jdns-data: build
 
 test: build
 	@echo "Running tests..."
+	@# macOS strips DYLD_LIBRARY_PATH through sh; DYLD_FALLBACK_LIBRARY_PATH
+	@# is preserved and works for finding libjerboa_native.dylib so the
+	@# wasm sandbox tests can exercise the sandbox path. On Linux/BSD,
+	@# LD_LIBRARY_PATH is honored normally.
 	@for f in tests/*-test.ss; do \
 		echo "  $$f"; \
+		DYLD_FALLBACK_LIBRARY_PATH="$(JERBOA)" \
+		LD_LIBRARY_PATH="$(JERBOA):$$LD_LIBRARY_PATH" \
 		$(SCHEME) --libdirs "$(LIBDIRS)" --script "$$f" || exit 1; \
 	done
 	@echo "All tests passed."
diff --git a/bench/gen-queries.sh b/bench/gen-queries.sh
new file mode 100755
index 0000000..4a743ad
--- /dev/null
+++ b/bench/gen-queries.sh
@@ -0,0 +1,68 @@
+#!/usr/bin/env bash
+# Generate dnsperf-format query files.
+#
+# Usage: bench/gen-queries.sh <max-host-index>
+# Produces (in bench/queries/):
+#   hot.txt        — A queries against host-1..N (all should hit)
+#   nxdomain.txt   — A queries against names that don't exist (still inside
+#                    the zone, so the server walks the auth chain)
+#   wildcard.txt   — A queries against names matched by *.bench.local
+#   mixed.txt      — 70% hot, 15% wildcard, 15% nxdomain
+#
+# Each line is "QNAME QTYPE" — dnsperf's input format.
+
+set -euo pipefail
+
+N="${1:-1000}"
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+QDIR="$ROOT/bench/queries"
+
+mkdir -p "$QDIR"
+
+# 1) hot: 5 × N queries cycling through host-1..N, A
+{
+  for r in 1 2 3 4 5; do
+    for i in $(seq 1 "$N"); do
+      echo "host-${i}.bench.local A"
+    done
+  done
+} > "$QDIR/hot.txt"
+
+# 2) nxdomain: names with no exact match but inside the auth chain.
+#    Use a label not used as wildcard target and not present as A.
+{
+  for r in 1 2 3 4 5; do
+    for i in $(seq 1 "$N"); do
+      echo "nx-${i}.bench.local A"
+    done
+  done
+} > "$QDIR/nxdomain.txt"
+
+# 3) wildcard: names that don't exist as exact records but DO match the
+#    *.bench.local wildcard.
+{
+  for r in 1 2 3 4 5; do
+    for i in $(seq 1 "$N"); do
+      echo "wild-${i}.wild.bench.local A"
+    done
+  done
+} > "$QDIR/wildcard.txt"
+
+# 4) mixed: 70/15/15 hot/wild/nx — shuffled deterministically (sort -R
+#    on macOS uses /dev/urandom; reproducible enough for our purposes).
+{
+  for r in 1 2 3 4 5 6 7; do
+    for i in $(seq 1 "$N"); do echo "host-${i}.bench.local A"; done
+  done
+  for r in 1 2; do
+    for i in $(seq 1 "$N"); do echo "wild-${i}.wild.bench.local A"; done
+  done
+  for r in 1 2; do
+    for i in $(seq 1 "$N"); do echo "nx-${i}.bench.local A"; done
+  done
+} | awk 'BEGIN{srand(42)} {print rand()"\t"$0}' | sort -k1,1n | cut -f2- > "$QDIR/mixed.txt"
+
+for f in hot.txt nxdomain.txt wildcard.txt mixed.txt; do
+  echo "$QDIR/$f: $(wc -l < "$QDIR/$f") queries"
+done
diff --git a/bench/gen-zone.sh b/bench/gen-zone.sh
new file mode 100755
index 0000000..f9368da
--- /dev/null
+++ b/bench/gen-zone.sh
@@ -0,0 +1,72 @@
+#!/usr/bin/env bash
+# Generate a tinydns-data zone for benchmarking.
+#
+# Usage: bench/gen-zone.sh <record-count>
+# Produces:
+#   bench/zones/zone-<N>.data    — tinydns-data source
+#   bench/zones/zone-<N>.cdb     — compiled CDB
+#
+# Zone layout:
+#   bench.local                  — apex (SOA + NS)
+#   *.bench.local                — wildcard A
+#   host-1.bench.local
+#   ...
+#   host-<N>.bench.local         — A records
+#   mx.bench.local               — A used by MX
+#   aaaa-1..N/10.bench.local     — AAAA records (10% of N)
+#   www.bench.local              — CNAME → host-1.bench.local
+
+set -euo pipefail
+
+N="${1:-1000}"
+SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
+ZONES_DIR="$ROOT/bench/zones"
+
+DATA="$ZONES_DIR/zone-${N}.data"
+CDB="$ZONES_DIR/zone-${N}.cdb"
+
+mkdir -p "$ZONES_DIR"
+
+{
+  # Apex SOA + NS + glue
+  echo ".bench.local:10.0.0.1:ns1.bench.local:259200"
+  echo "&bench.local:10.0.0.2:ns2.bench.local:259200"
+  # MX + glue
+  echo "@bench.local:10.0.0.3:mx.bench.local:10:86400"
+  # CNAME
+  echo "Cwww.bench.local:host-1.bench.local:86400"
+  # Wildcard — confined to wild.bench.local so queries under the apex
+  # without an exact match cleanly return NXDOMAIN.
+  echo "+*.wild.bench.local:10.99.99.99:86400"
+
+  # Bulk A records
+  for i in $(seq 1 "$N"); do
+    # Spread across an /8 to avoid the same rdata for every host
+    a=$(( i / 65536 % 256 ))
+    b=$(( i / 256 % 256 ))
+    c=$(( i % 256 ))
+    echo "+host-${i}.bench.local:10.${a}.${b}.${c}:86400"
+  done
+
+  # AAAA records — 10% of N (rounded up, ≥1)
+  aaaa=$(( (N + 9) / 10 ))
+  for i in $(seq 1 "$aaaa"); do
+    # IPv6 32-hex: 2001:db8:0000:...:<i hex padded to 8>
+    h=$(printf "%08x" "$i")
+    echo "3aaaa-${i}.bench.local:20010db8000000000000000000${h}:86400"
+  done
+} > "$DATA"
+
+echo "Wrote $DATA ($(wc -l < "$DATA") lines)"
+
+# Compile via jdns-data. Needs JERBOA stdlib's native libs on the
+# loader path so the server.sls socket FFI bindings resolve at import.
+cd "$ROOT"
+echo "Compiling $DATA -> $CDB ..."
+DYLD_FALLBACK_LIBRARY_PATH="$HOME/mine/jerboa/lib" \
+LD_LIBRARY_PATH="$HOME/mine/jerboa/lib:${LD_LIBRARY_PATH:-}" \
+$HOME/mine/jerboa/.chez/bin/scheme \
+  --libdirs "lib:$HOME/mine/jerboa/lib" \
+  --script bin/jdns-data.ss "$DATA" "$CDB" 2>&1 | tail -3
+echo "CDB size: $(wc -c < "$CDB") bytes"
diff --git a/bench/percentiles.awk b/bench/percentiles.awk
new file mode 100644
index 0000000..a205b0e
--- /dev/null
+++ b/bench/percentiles.awk
@@ -0,0 +1,30 @@
+#!/usr/bin/awk -f
+# Extract latency percentiles from a dnsperf -O latency-histogram output.
+# Usage: awk -f percentiles.awk <dnsperf-output.txt>
+
+/^ +[0-9].*:.*[0-9]+$/ {
+  sub(/^ +/, "")
+  split($0, parts, ":")
+  split(parts[1], r, "-")
+  lat = (r[1] + r[2]) / 2.0
+  cnt = parts[2] + 0
+  n++
+  buckets[n] = lat
+  counts[n] = cnt
+  total += cnt
+}
+
+END {
+  if (total == 0) { print "no samples"; exit }
+  p50  = total * 0.50;  p95  = total * 0.95
+  p99  = total * 0.99;  p999 = total * 0.999
+  cum = 0
+  for (i = 1; i <= n; i++) {
+    cum += counts[i]
+    if (!s50  && cum >= p50)  { v50  = buckets[i]; s50  = 1 }
+    if (!s95  && cum >= p95)  { v95  = buckets[i]; s95  = 1 }
+    if (!s99  && cum >= p99)  { v99  = buckets[i]; s99  = 1 }
+    if (!s999 && cum >= p999) { v999 = buckets[i]; s999 = 1 }
+  }
+  printf "p50=%.6f p95=%.6f p99=%.6f p99.9=%.6f n=%d\n", v50, v95, v99, v999, total
+}
diff --git a/bench/queries/hot.txt b/bench/queries/hot.txt
new file mode 100644
index 0000000..d727ce9
--- /dev/null
+++ b/bench/queries/hot.txt
@@ -0,0 +1,5000 @@
+host-1.bench.local A
+host-2.bench.local A
+host-3.bench.local A
+host-4.bench.local A
+host-5.bench.local A
+host-6.bench.local A
+host-7.bench.local A
+host-8.bench.local A
+host-9.bench.local A
+host-10.bench.local A
+host-11.bench.local A
+host-12.bench.local A
+host-13.bench.local A
+host-14.bench.local A
+host-15.bench.local A
+host-16.bench.local A
+host-17.bench.local A
+host-18.bench.local A
+host-19.bench.local A
+host-20.bench.local A
+host-21.bench.local A
+host-22.bench.local A
+host-23.bench.local A
+host-24.bench.local A
+host-25.bench.local A
+host-26.bench.local A
+host-27.bench.local A
+host-28.bench.local A
+host-29.bench.local A
+host-30.bench.local A
+host-31.bench.local A
+host-32.bench.local A
+host-33.bench.local A
+host-34.bench.local A
+host-35.bench.local A
+host-36.bench.local A
+host-37.bench.local A
+host-38.bench.local A
+host-39.bench.local A
+host-40.bench.local A
+host-41.bench.local A
+host-42.bench.local A
+host-43.bench.local A
+host-44.bench.local A
+host-45.bench.local A
+host-46.bench.local A
+host-47.bench.local A
+host-48.bench.local A
+host-49.bench.local A
+host-50.bench.local A
+host-51.bench.local A
+host-52.bench.local A
+host-53.bench.local A
+host-54.bench.local A
+host-55.bench.local A
+host-56.bench.local A
+host-57.bench.local A
+host-58.bench.local A
+host-59.bench.local A
+host-60.bench.local A
+host-61.bench.local A
+host-62.bench.local A
+host-63.bench.local A
+host-64.bench.local A
+host-65.bench.local A
+host-66.bench.local A
+host-67.bench.local A
+host-68.bench.local A
+host-69.bench.local A
+host-70.bench.local A
+host-71.bench.local A
+host-72.bench.local A
+host-73.bench.local A
+host-74.bench.local A
+host-75.bench.local A
+host-76.bench.local A
+host-77.bench.local A
+host-78.bench.local A
+host-79.bench.local A
+host-80.bench.local A
+host-81.bench.local A
+host-82.bench.local A
+host-83.bench.local A
+host-84.bench.local A
+host-85.bench.local A
+host-86.bench.local A
+host-87.bench.local A
+host-88.bench.local A
+host-89.bench.local A
+host-90.bench.local A
+host-91.bench.local A
+host-92.bench.local A
+host-93.bench.local A
+host-94.bench.local A
+host-95.bench.local A
+host-96.bench.local A
+host-97.bench.local A
+host-98.bench.local A
+host-99.bench.local A
+host-100.bench.local A
+host-101.bench.local A
+host-102.bench.local A
+host-103.bench.local A
+host-104.bench.local A
+host-105.bench.local A
+host-106.bench.local A
+host-107.bench.local A
+host-108.bench.local A
+host-109.bench.local A
+host-110.bench.local A
+host-111.bench.local A
+host-112.bench.local A
+host-113.bench.local A
+host-114.bench.local A
+host-115.bench.local A
+host-116.bench.local A
+host-117.bench.local A
+host-118.bench.local A
+host-119.bench.local A
+host-120.bench.local A
+host-121.bench.local A
+host-122.bench.local A
+host-123.bench.local A
+host-124.bench.local A
+host-125.bench.local A
+host-126.bench.local A
+host-127.bench.local A
+host-128.bench.local A
+host-129.bench.local A
+host-130.bench.local A
+host-131.bench.local A
+host-132.bench.local A
+host-133.bench.local A
+host-134.bench.local A
+host-135.bench.local A
+host-136.bench.local A
+host-137.bench.local A
+host-138.bench.local A
+host-139.bench.local A
+host-140.bench.local A
+host-141.bench.local A
+host-142.bench.local A
+host-143.bench.local A
+host-144.bench.local A
+host-145.bench.local A
+host-146.bench.local A
+host-147.bench.local A
+host-148.bench.local A
+host-149.bench.local A
+host-150.bench.local A
+host-151.bench.local A
+host-152.bench.local A
+host-153.bench.local A
+host-154.bench.local A
+host-155.bench.local A
+host-156.bench.local A
+host-157.bench.local A
+host-158.bench.local A
+host-159.bench.local A
+host-160.bench.local A
+host-161.bench.local A
+host-162.bench.local A
+host-163.bench.local A
+host-164.bench.local A
+host-165.bench.local A
+host-166.bench.local A
+host-167.bench.local A
+host-168.bench.local A
+host-169.bench.local A
+host-170.bench.local A
+host-171.bench.local A
+host-172.bench.local A
+host-173.bench.local A
+host-174.bench.local A
+host-175.bench.local A
+host-176.bench.local A
+host-177.bench.local A
+host-178.bench.local A
+host-179.bench.local A
+host-180.bench.local A
+host-181.bench.local A
+host-182.bench.local A
+host-183.bench.local A
+host-184.bench.local A
+host-185.bench.local A
+host-186.bench.local A
+host-187.bench.local A
+host-188.bench.local A
+host-189.bench.local A
+host-190.bench.local A
+host-191.bench.local A
+host-192.bench.local A
+host-193.bench.local A
+host-194.bench.local A
+host-195.bench.local A
+host-196.bench.local A
+host-197.bench.local A
+host-198.bench.local A
+host-199.bench.local A
+host-200.bench.local A
+host-201.bench.local A
+host-202.bench.local A
+host-203.bench.local A
+host-204.bench.local A
+host-205.bench.local A
+host-206.bench.local A
+host-207.bench.local A
+host-208.bench.local A
+host-209.bench.local A
+host-210.bench.local A
+host-211.bench.local A
+host-212.bench.local A
+host-213.bench.local A
+host-214.bench.local A
+host-215.bench.local A
+host-216.bench.local A
+host-217.bench.local A
+host-218.bench.local A
+host-219.bench.local A
+host-220.bench.local A
+host-221.bench.local A
+host-222.bench.local A
+host-223.bench.local A
+host-224.bench.local A
+host-225.bench.local A
+host-226.bench.local A
+host-227.bench.local A
+host-228.bench.local A
+host-229.bench.local A
+host-230.bench.local A
+host-231.bench.local A
+host-232.bench.local A
+host-233.bench.local A
+host-234.bench.local A
+host-235.bench.local A
+host-236.bench.local A
+host-237.bench.local A
+host-238.bench.local A
+host-239.bench.local A
+host-240.bench.local A
+host-241.bench.local A
+host-242.bench.local A
+host-243.bench.local A
+host-244.bench.local A
+host-245.bench.local A
+host-246.bench.local A
+host-247.bench.local A
+host-248.bench.local A
+host-249.bench.local A
+host-250.bench.local A
+host-251.bench.local A
+host-252.bench.local A
+host-253.bench.local A
+host-254.bench.local A
+host-255.bench.local A
+host-256.bench.local A
+host-257.bench.local A
+host-258.bench.local A
+host-259.bench.local A
+host-260.bench.local A
+host-261.bench.local A
+host-262.bench.local A
+host-263.bench.local A
+host-264.bench.local A
+host-265.bench.local A
+host-266.bench.local A
+host-267.bench.local A
+host-268.bench.local A
+host-269.bench.local A
+host-270.bench.local A
+host-271.bench.local A
+host-272.bench.local A
+host-273.bench.local A
+host-274.bench.local A
+host-275.bench.local A
+host-276.bench.local A
+host-277.bench.local A
+host-278.bench.local A
+host-279.bench.local A
+host-280.bench.local A
+host-281.bench.local A
+host-282.bench.local A
+host-283.bench.local A
+host-284.bench.local A
+host-285.bench.local A
+host-286.bench.local A
+host-287.bench.local A
+host-288.bench.local A
+host-289.bench.local A
+host-290.bench.local A
+host-291.bench.local A
+host-292.bench.local A
+host-293.bench.local A
+host-294.bench.local A
+host-295.bench.local A
+host-296.bench.local A
+host-297.bench.local A
+host-298.bench.local A
+host-299.bench.local A
+host-300.bench.local A
+host-301.bench.local A
+host-302.bench.local A
+host-303.bench.local A
+host-304.bench.local A
+host-305.bench.local A
+host-306.bench.local A
+host-307.bench.local A
+host-308.bench.local A
+host-309.bench.local A
+host-310.bench.local A
+host-311.bench.local A
+host-312.bench.local A
+host-313.bench.local A
+host-314.bench.local A
+host-315.bench.local A
+host-316.bench.local A
+host-317.bench.local A
+host-318.bench.local A
+host-319.bench.local A
+host-320.bench.local A
+host-321.bench.local A
+host-322.bench.local A
+host-323.bench.local A
+host-324.bench.local A
+host-325.bench.local A
+host-326.bench.local A
+host-327.bench.local A
+host-328.bench.local A
+host-329.bench.local A
+host-330.bench.local A
+host-331.bench.local A
+host-332.bench.local A
+host-333.bench.local A
+host-334.bench.local A
+host-335.bench.local A
+host-336.bench.local A
+host-337.bench.local A
+host-338.bench.local A
+host-339.bench.local A
+host-340.bench.local A
+host-341.bench.local A
+host-342.bench.local A
+host-343.bench.local A
+host-344.bench.local A
+host-345.bench.local A
+host-346.bench.local A
+host-347.bench.local A
+host-348.bench.local A
+host-349.bench.local A
+host-350.bench.local A
+host-351.bench.local A
+host-352.bench.local A
+host-353.bench.local A
+host-354.bench.local A
+host-355.bench.local A
+host-356.bench.local A
+host-357.bench.local A
+host-358.bench.local A
+host-359.bench.local A
+host-360.bench.local A
+host-361.bench.local A
+host-362.bench.local A
+host-363.bench.local A
+host-364.bench.local A
+host-365.bench.local A
+host-366.bench.local A
+host-367.bench.local A
+host-368.bench.local A
+host-369.bench.local A
+host-370.bench.local A
+host-371.bench.local A
+host-372.bench.local A
+host-373.bench.local A
+host-374.bench.local A
+host-375.bench.local A
+host-376.bench.local A
+host-377.bench.local A
+host-378.bench.local A
+host-379.bench.local A
+host-380.bench.local A
+host-381.bench.local A
+host-382.bench.local A
+host-383.bench.local A
+host-384.bench.local A
+host-385.bench.local A
+host-386.bench.local A
+host-387.bench.local A
+host-388.bench.local A
+host-389.bench.local A
+host-390.bench.local A
+host-391.bench.local A
+host-392.bench.local A
+host-393.bench.local A
+host-394.bench.local A
+host-395.bench.local A
+host-396.bench.local A
+host-397.bench.local A
+host-398.bench.local A
+host-399.bench.local A
+host-400.bench.local A
+host-401.bench.local A
+host-402.bench.local A
+host-403.bench.local A
+host-404.bench.local A
+host-405.bench.local A
+host-406.bench.local A
+host-407.bench.local A
+host-408.bench.local A
+host-409.bench.local A
+host-410.bench.local A
+host-411.bench.local A
+host-412.bench.local A
+host-413.bench.local A
+host-414.bench.local A
+host-415.bench.local A
+host-416.bench.local A
+host-417.bench.local A
+host-418.bench.local A
+host-419.bench.local A
+host-420.bench.local A
+host-421.bench.local A
+host-422.bench.local A
+host-423.bench.local A
+host-424.bench.local A
+host-425.bench.local A
+host-426.bench.local A
+host-427.bench.local A
+host-428.bench.local A
+host-429.bench.local A
+host-430.bench.local A
+host-431.bench.local A
+host-432.bench.local A
+host-433.bench.local A
+host-434.bench.local A
+host-435.bench.local A
+host-436.bench.local A
+host-437.bench.local A
+host-438.bench.local A
+host-439.bench.local A
+host-440.bench.local A
+host-441.bench.local A
+host-442.bench.local A
+host-443.bench.local A
+host-444.bench.local A
+host-445.bench.local A
+host-446.bench.local A
+host-447.bench.local A
+host-448.bench.local A
+host-449.bench.local A
+host-450.bench.local A
+host-451.bench.local A
+host-452.bench.local A
+host-453.bench.local A
+host-454.bench.local A
+host-455.bench.local A
+host-456.bench.local A
+host-457.bench.local A
+host-458.bench.local A
+host-459.bench.local A
+host-460.bench.local A
+host-461.bench.local A
+host-462.bench.local A
+host-463.bench.local A
+host-464.bench.local A
+host-465.bench.local A
+host-466.bench.local A
+host-467.bench.local A
+host-468.bench.local A
+host-469.bench.local A
+host-470.bench.local A
+host-471.bench.local A
+host-472.bench.local A
+host-473.bench.local A
+host-474.bench.local A
+host-475.bench.local A
+host-476.bench.local A
+host-477.bench.local A
+host-478.bench.local A
+host-479.bench.local A
+host-480.bench.local A
+host-481.bench.local A
+host-482.bench.local A
+host-483.bench.local A
+host-484.bench.local A
+host-485.bench.local A
+host-486.bench.local A
+host-487.bench.local A
+host-488.bench.local A
+host-489.bench.local A
+host-490.bench.local A
+host-491.bench.local A
+host-492.bench.local A
+host-493.bench.local A
+host-494.bench.local A
+host-495.bench.local A
+host-496.bench.local A
+host-497.bench.local A
+host-498.bench.local A
+host-499.bench.local A
+host-500.bench.local A
+host-501.bench.local A
+host-502.bench.local A
+host-503.bench.local A
+host-504.bench.local A
+host-505.bench.local A
+host-506.bench.local A
+host-507.bench.local A
+host-508.bench.local A
+host-509.bench.local A
+host-510.bench.local A
+host-511.bench.local A
+host-512.bench.local A
+host-513.bench.local A
+host-514.bench.local A
+host-515.bench.local A
+host-516.bench.local A
+host-517.bench.local A
+host-518.bench.local A
+host-519.bench.local A
+host-520.bench.local A
+host-521.bench.local A
+host-522.bench.local A
+host-523.bench.local A
+host-524.bench.local A
+host-525.bench.local A
+host-526.bench.local A
+host-527.bench.local A
+host-528.bench.local A
+host-529.bench.local A
+host-530.bench.local A
+host-531.bench.local A
+host-532.bench.local A
+host-533.bench.local A
+host-534.bench.local A
+host-535.bench.local A
+host-536.bench.local A
+host-537.bench.local A
+host-538.bench.local A
+host-539.bench.local A
+host-540.bench.local A
+host-541.bench.local A
+host-542.bench.local A
+host-543.bench.local A
+host-544.bench.local A
+host-545.bench.local A
+host-546.bench.local A
+host-547.bench.local A
+host-548.bench.local A
+host-549.bench.local A
+host-550.bench.local A
+host-551.bench.local A
+host-552.bench.local A
+host-553.bench.local A
+host-554.bench.local A
+host-555.bench.local A
+host-556.bench.local A
+host-557.bench.local A
+host-558.bench.local A
+host-559.bench.local A
+host-560.bench.local A
+host-561.bench.local A
+host-562.bench.local A
+host-563.bench.local A
+host-564.bench.local A
+host-565.bench.local A
+host-566.bench.local A
+host-567.bench.local A
+host-568.bench.local A
+host-569.bench.local A
+host-570.bench.local A
+host-571.bench.local A
+host-572.bench.local A
+host-573.bench.local A
+host-574.bench.local A
+host-575.bench.local A
+host-576.bench.local A
+host-577.bench.local A
+host-578.bench.local A
+host-579.bench.local A
+host-580.bench.local A
+host-581.bench.local A
+host-582.bench.local A
+host-583.bench.local A
+host-584.bench.local A
+host-585.bench.local A
+host-586.bench.local A
+host-587.bench.local A
+host-588.bench.local A
+host-589.bench.local A
+host-590.bench.local A
+host-591.bench.local A
+host-592.bench.local A
+host-593.bench.local A
+host-594.bench.local A
+host-595.bench.local A
+host-596.bench.local A
+host-597.bench.local A
+host-598.bench.local A
+host-599.bench.local A
+host-600.bench.local A
+host-601.bench.local A
+host-602.bench.local A
+host-603.bench.local A
+host-604.bench.local A
+host-605.bench.local A
+host-606.bench.local A
+host-607.bench.local A
+host-608.bench.local A
+host-609.bench.local A
+host-610.bench.local A
+host-611.bench.local A
+host-612.bench.local A
+host-613.bench.local A
+host-614.bench.local A
+host-615.bench.local A
+host-616.bench.local A
+host-617.bench.local A
+host-618.bench.local A
+host-619.bench.local A
+host-620.bench.local A
+host-621.bench.local A
+host-622.bench.local A
+host-623.bench.local A
+host-624.bench.local A
+host-625.bench.local A
+host-626.bench.local A
+host-627.bench.local A
+host-628.bench.local A
+host-629.bench.local A
+host-630.bench.local A
+host-631.bench.local A
+host-632.bench.local A
+host-633.bench.local A
+host-634.bench.local A
+host-635.bench.local A
+host-636.bench.local A
+host-637.bench.local A
+host-638.bench.local A
+host-639.bench.local A
+host-640.bench.local A
+host-641.bench.local A
+host-642.bench.local A
+host-643.bench.local A
+host-644.bench.local A
+host-645.bench.local A
+host-646.bench.local A
+host-647.bench.local A
+host-648.bench.local A
+host-649.bench.local A
+host-650.bench.local A
+host-651.bench.local A
+host-652.bench.local A
+host-653.bench.local A
+host-654.bench.local A
+host-655.bench.local A
+host-656.bench.local A
+host-657.bench.local A
+host-658.bench.local A
+host-659.bench.local A
+host-660.bench.local A
+host-661.bench.local A
+host-662.bench.local A
+host-663.bench.local A
+host-664.bench.local A
+host-665.bench.local A
+host-666.bench.local A
+host-667.bench.local A
+host-668.bench.local A
+host-669.bench.local A
+host-670.bench.local A
+host-671.bench.local A
+host-672.bench.local A
+host-673.bench.local A
+host-674.bench.local A
+host-675.bench.local A
+host-676.bench.local A
+host-677.bench.local A
+host-678.bench.local A
+host-679.bench.local A
+host-680.bench.local A
+host-681.bench.local A
+host-682.bench.local A
+host-683.bench.local A
+host-684.bench.local A
+host-685.bench.local A
+host-686.bench.local A
+host-687.bench.local A
+host-688.bench.local A
+host-689.bench.local A
+host-690.bench.local A
+host-691.bench.local A
+host-692.bench.local A
+host-693.bench.local A
+host-694.bench.local A
+host-695.bench.local A
+host-696.bench.local A
+host-697.bench.local A
+host-698.bench.local A
+host-699.bench.local A
+host-700.bench.local A
+host-701.bench.local A
+host-702.bench.local A
+host-703.bench.local A
+host-704.bench.local A
+host-705.bench.local A
+host-706.bench.local A
+host-707.bench.local A
+host-708.bench.local A
+host-709.bench.local A
+host-710.bench.local A
+host-711.bench.local A
+host-712.bench.local A
+host-713.bench.local A
+host-714.bench.local A
+host-715.bench.local A
+host-716.bench.local A
+host-717.bench.local A
+host-718.bench.local A
+host-719.bench.local A
+host-720.bench.local A
+host-721.bench.local A
+host-722.bench.local A
+host-723.bench.local A
+host-724.bench.local A
+host-725.bench.local A
+host-726.bench.local A
+host-727.bench.local A
+host-728.bench.local A
+host-729.bench.local A
+host-730.bench.local A
+host-731.bench.local A
+host-732.bench.local A
+host-733.bench.local A
+host-734.bench.local A
+host-735.bench.local A
+host-736.bench.local A
+host-737.bench.local A
+host-738.bench.local A
+host-739.bench.local A
+host-740.bench.local A
+host-741.bench.local A
+host-742.bench.local A
+host-743.bench.local A
+host-744.bench.local A
+host-745.bench.local A
+host-746.bench.local A
+host-747.bench.local A