fix(native): let JD resident reach an allowlisted relay

This commit is contained in:
冰朔 2026-08-06 19:19:41 +08:00
commit b53e32fb0b
10 changed files with 595 additions and 265 deletions

View file

@ -49,6 +49,7 @@ recovery_beacon_lba=$(native_value recovery_beacon_lba_start)
gestational_index_lba=$(native_value gestational_index_lba_start)
native_ipv4=$(ipv4_dword "$(network_value native_ipv4)")
gateway_ipv4=$(ipv4_dword "$(network_value gateway_ipv4)")
relay_ipv4=$(ipv4_dword "$(network_value relay_ipv4)")
for value in \
"${kernel_lba}" "${proof_lba}" "${world_store_lba}" \
@ -68,4 +69,5 @@ printf '%s\n' \
"-dGHOS_NATIVE_RECOVERY_BEACON_LBA=${recovery_beacon_lba}" \
"-dGHOS_NATIVE_GESTATIONAL_INDEX_LBA=${gestational_index_lba}" \
"-dGHOS_NATIVE_IPV4_DWORD=${native_ipv4}" \
"-dGHOS_GATEWAY_IPV4_DWORD=${gateway_ipv4}"
"-dGHOS_GATEWAY_IPV4_DWORD=${gateway_ipv4}" \
"-dGHOS_RELAY_IPV4_DWORD=${relay_ipv4}"

View file

@ -53,6 +53,35 @@ def verify_reply(packet: bytes, magic: bytes) -> int:
return int.from_bytes(packet[6:8], "big")
def verify_native_request(packet: bytes, pipeline: list[bytes]) -> tuple[int, str]:
if not packet or packet[0] >> 4 != 4:
raise RuntimeError("native request is missing its IPv4 header")
header_length = (packet[0] & 0x0F) * 4
source = socket.inet_ntoa(packet[12:16])
icmp = packet[header_length:]
if len(icmp) < 48 or icmp[0] != 8 or icmp[1] != 0:
raise RuntimeError("unexpected native ICMP request shape")
if checksum(icmp) != 0:
raise RuntimeError("native ICMP request checksum failed")
sequence = int.from_bytes(icmp[6:8], "big")
if not 1 <= sequence <= len(pipeline):
raise RuntimeError("native ICMP sequence is outside the pipeline")
magic = pipeline[sequence - 1]
if icmp[16:32] != magic or icmp[32:48] != magic:
raise RuntimeError("native ICMP request magic mismatch")
return sequence, source
def native_ack_reply(packet: bytes) -> bytes:
header_length = (packet[0] & 0x0F) * 4
icmp = bytearray(packet[header_length:])
icmp[0] = 0
icmp[2:4] = b"\0\0"
icmp[32:48] = NATIVE_ACK_MAGIC
icmp[2:4] = struct.pack("!H", checksum(bytes(icmp)))
return bytes(icmp)
def exchange(
peer: socket.socket,
target: tuple[str, int],
@ -80,7 +109,7 @@ def exchange(
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("--target", required=True)
parser.add_argument("--target")
parser.add_argument("--receipt", required=True)
parser.add_argument("--timeout", type=float, default=90.0)
parser.add_argument("--retry-interval", type=float, default=1.0)
@ -92,6 +121,8 @@ def main() -> None:
parser.add_argument("--resume-after-branch", action="store_true")
parser.add_argument("--resume-resident-count", type=int)
parser.add_argument("--resident-pipeline", action="store_true")
parser.add_argument("--native-relay", action="store_true")
parser.add_argument("--allowed-source")
args = parser.parse_args()
if args.retry_interval < 1.0:
raise SystemExit("--retry-interval must be at least 1 second")
@ -108,19 +139,79 @@ def main() -> None:
args.resume_after_branch,
args.resume_resident_count is not None,
args.resident_pipeline,
args.native_relay,
)
) > 1:
raise SystemExit(
"--resident, --login-only, --resume-after-login, and "
"--resume-after-commit, --resume-after-branch, and "
"--resume-resident-count, and --resident-pipeline are mutually exclusive"
"--resume-resident-count, --resident-pipeline, and --native-relay "
"are mutually exclusive"
)
socket_type = socket.SOCK_RAW if args.raw_socket else socket.SOCK_DGRAM
peer = socket.socket(socket.AF_INET, socket_type, socket.IPPROTO_ICMP)
deadline = time.monotonic() + args.timeout
if args.native_relay:
if not args.raw_socket:
raise SystemExit("--native-relay requires --raw-socket")
if not args.allowed_source:
raise SystemExit("--native-relay requires --allowed-source")
allowed_source = socket.gethostbyname(args.allowed_source)
pipeline = [
LOGIN_MAGIC,
LOGIN_MAGIC,
LOGIN_MAGIC,
COMMIT_MAGIC,
BRANCH_MAGIC,
*([LOGIN_MAGIC] * 10),
RECOVERY_MAGIC,
]
peer.settimeout(0.5)
acknowledged: set[int] = set()
sources: set[str] = set()
completed_at: float | None = None
while time.monotonic() < deadline and (
completed_at is None or time.monotonic() < completed_at + 5.0
):
try:
packet, address = peer.recvfrom(4096)
sequence, source = verify_native_request(packet, pipeline)
except (TimeoutError, RuntimeError, IndexError):
continue
if source != allowed_source:
continue
peer.sendto(native_ack_reply(packet), address)
acknowledged.add(sequence)
sources.add(source)
if len(acknowledged) == len(pipeline) and completed_at is None:
completed_at = time.monotonic()
if len(acknowledged) != len(pipeline):
raise TimeoutError(
"native relay pipeline incomplete; acknowledged sequences: "
+ ",".join(str(item) for item in sorted(acknowledged))
)
receipt = pathlib.Path(args.receipt)
receipt.write_text(
"schema: guanghu.physical-native-icmp-relay/v1\n"
"status: PASS_100\n"
"handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP\n"
"native_ack_marker: HLDP-NATIVE-ACK!\n"
"acknowledged_sequences: 1-16\n"
f"observed_nat_sources: {','.join(sorted(sources))}\n"
"login_reply_count: 3\n"
"code_commit_reply_verified: true\n"
"branch_move_reply_verified: true\n"
"resident_login_reply_count: 10\n"
"recovery_reply_verified: true\n",
encoding="utf-8",
)
print(receipt.read_text(encoding="utf-8"), end="")
return
if not args.target:
raise SystemExit("--target is required unless --native-relay is used")
peer.settimeout(0.2 if args.resident_pipeline else 1.0)
target = (socket.gethostbyname(args.target), 0)
deadline = time.monotonic() + args.timeout
if args.resident_pipeline:
pipeline = [
LOGIN_MAGIC,
@ -137,19 +228,24 @@ def main() -> None:
if time.monotonic() >= deadline:
break
peer.sendto(request(pipeline_sequence, pipeline_magic), target)
try:
packet, _ = peer.recvfrom(4096)
observed_sequence = reply_sequence_index(packet)
if not 1 <= observed_sequence <= len(pipeline):
raise RuntimeError("native ACK sequence is outside the pipeline")
reply_sequence = verify_reply(
packet,
pipeline[observed_sequence - 1],
)
except (TimeoutError, RuntimeError, IndexError):
continue
if reply_sequence == pipeline_sequence:
receive_until = min(deadline, time.monotonic() + 0.8)
while time.monotonic() < receive_until:
try:
packet, _ = peer.recvfrom(4096)
observed_sequence = reply_sequence_index(packet)
if not 1 <= observed_sequence <= len(pipeline):
raise RuntimeError(
"native ACK sequence is outside the pipeline"
)
reply_sequence = verify_reply(
packet,
pipeline[observed_sequence - 1],
)
except (TimeoutError, RuntimeError, IndexError):
continue
acknowledged.add(reply_sequence)
if reply_sequence == pipeline_sequence:
break
if len(acknowledged) != len(pipeline):
raise TimeoutError(
"native pipeline incomplete; acknowledged sequences: "

View file

@ -7,9 +7,9 @@ import time
GUEST_MAC = bytes.fromhex("525400267198")
PEER_MAC = bytes.fromhex("525400123401")
GUEST_IP = socket.inet_aton("10.0.0.7")
PEER_IP = socket.inet_aton("10.0.0.1")
LOGIN_CLIENT_IP = socket.inet_aton("10.0.0.2")
GUEST_IP = socket.inet_aton("172.16.0.6")
GATEWAY_IP = socket.inet_aton("172.16.0.1")
RELAY_IP = socket.inet_aton("43.153.193.169")
LOGIN_MAGIC = b"HLDP-GHOS-LOGIN!"
COMMIT_MAGIC = b"HLDP-CODE-COMMIT"
BRANCH_MAGIC = b"HLDP-BRANCH-MOVE"
@ -35,68 +35,65 @@ def arp_reply(request: bytes) -> bytes:
target_ip = request[38:42]
assert sender_mac == GUEST_MAC
assert sender_ip == GUEST_IP
assert target_ip == PEER_IP
assert target_ip == GATEWAY_IP
return (
sender_mac
+ PEER_MAC
+ b"\x08\x06"
+ b"\x00\x01\x08\x00\x06\x04\x00\x02"
+ PEER_MAC
+ PEER_IP
+ GATEWAY_IP
+ sender_mac
+ sender_ip
)
def icmp_request(sequence: int, magic: bytes) -> bytes:
payload = b"\0" * 8 + magic + magic
icmp = struct.pack("!BBHHH", 8, 0, 0, 0x4748, sequence) + payload
icmp = icmp[:2] + struct.pack("!H", checksum(icmp)) + icmp[4:]
total_length = 20 + len(icmp)
ip = struct.pack(
"!BBHHHBBH4s4s",
0x45,
0,
total_length,
0x484C,
0,
64,
1,
0,
LOGIN_CLIENT_IP,
GUEST_IP,
)
ip = ip[:10] + struct.pack("!H", checksum(ip)) + ip[12:]
return GUEST_MAC + PEER_MAC + b"\x08\x00" + ip + icmp
def validate_reply(frame: bytes, magic: bytes) -> None:
def verified_request(frame: bytes, sequence: int, magic: bytes) -> None:
assert frame[0:6] == PEER_MAC
assert frame[6:12] == GUEST_MAC
assert frame[12:14] == b"\x08\x00"
assert frame[26:30] == GUEST_IP
assert frame[30:34] == LOGIN_CLIENT_IP
assert frame[34] == 0
assert frame[30:34] == RELAY_IP
assert checksum(frame[14:34]) == 0
assert frame[34] == 8
assert frame[35] == 0
assert frame[38:40] == b"\x47\x48"
assert int.from_bytes(frame[40:42], "big") == sequence
assert frame[50:66] == magic
assert frame[66:82] == NATIVE_ACK_MAGIC
assert checksum(frame[34:]) == 0
assert frame[66:82] == magic
assert checksum(frame[34:82]) == 0
def authenticated_reply(frame: bytes, magic: bytes) -> bytes:
reply = bytearray(frame)
reply[0:6] = GUEST_MAC
reply[6:12] = PEER_MAC
reply[26:30] = RELAY_IP
reply[30:34] = GUEST_IP
reply[24:26] = b"\0\0"
reply[24:26] = struct.pack("!H", checksum(bytes(reply[14:34])))
reply[34] = 0
reply[36:38] = b"\0\0"
reply[66:82] = NATIVE_ACK_MAGIC
reply[36:38] = struct.pack("!H", checksum(bytes(reply[34:82])))
return bytes(reply)
def main() -> None:
global GUEST_IP, PEER_IP, LOGIN_CLIENT_IP
global GUEST_IP, GATEWAY_IP, RELAY_IP
parser = argparse.ArgumentParser()
parser.add_argument("--listen-port", type=int, required=True)
parser.add_argument("--qemu-port", type=int, required=True)
parser.add_argument("--receipt", required=True)
parser.add_argument("--resident", action="store_true")
parser.add_argument("--login-only", action="store_true")
parser.add_argument("--guest-ip", default="10.0.0.7")
parser.add_argument("--peer-ip", default="10.0.0.1")
parser.add_argument("--login-client-ip", default="10.0.0.2")
parser.add_argument("--guest-ip", default="172.16.0.6")
parser.add_argument("--peer-ip", default="172.16.0.1")
parser.add_argument("--relay-ip", default="43.153.193.169")
args = parser.parse_args()
GUEST_IP = socket.inet_aton(args.guest_ip)
PEER_IP = socket.inet_aton(args.peer_ip)
LOGIN_CLIENT_IP = socket.inet_aton(args.login_client_ip)
GATEWAY_IP = socket.inet_aton(args.peer_ip)
RELAY_IP = socket.inet_aton(args.relay_ip)
peer = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
peer.bind(("127.0.0.1", args.listen_port))
@ -104,101 +101,63 @@ def main() -> None:
qemu = ("127.0.0.1", args.qemu_port)
deadline = time.monotonic() + 15
arp_verified = False
login_sent = False
reply_count = 0
login_reply_count = 0
resident_login_reply_count = 0
recovery_reply_verified = False
command_phase = "login"
def write_receipt(
*,
commit_verified: bool,
branch_verified: bool,
) -> None:
with open(args.receipt, "w", encoding="utf-8") as output:
output.write(
"arp_gateway_reply: VERIFIED\n"
f"icmp_login_request_sent: {str(login_sent).lower()}\n"
"icmp_login_reply_verified: true\n"
f"icmp_login_reply_count: {login_reply_count}\n"
"code_commit_reply_verified: "
f"{str(commit_verified).lower()}\n"
"branch_move_reply_verified: "
f"{str(branch_verified).lower()}\n"
f"resident_login_reply_count: {resident_login_reply_count}\n"
"recovery_reply_verified: "
f"{str(recovery_reply_verified).lower()}\n"
"login_magic: HLDP-GHOS-LOGIN!\n"
)
def phase_magic() -> bytes:
return {
"login": LOGIN_MAGIC,
"commit": COMMIT_MAGIC,
"branch": BRANCH_MAGIC,
"resident_login": LOGIN_MAGIC,
"recovery": RECOVERY_MAGIC,
}[command_phase]
login_count = 0
resident_login_count = 0
commit_verified = False
branch_verified = False
recovery_verified = False
while time.monotonic() < deadline:
try:
frame = peer.recv(4096)
except TimeoutError:
if arp_verified:
peer.sendto(
icmp_request(reply_count + 1, phase_magic()),
qemu,
)
login_sent = True
continue
if frame[12:14] == b"\x08\x06":
peer.sendto(arp_reply(frame), qemu)
arp_verified = True
continue
if frame[12:14] == b"\x08\x00":
magic = phase_magic()
validate_reply(frame, magic)
reply_count += 1
if command_phase == "login":
login_reply_count += 1
if command_phase == "login" and reply_count < 3:
peer.sendto(icmp_request(reply_count + 1, LOGIN_MAGIC), qemu)
continue
if command_phase == "login":
if args.login_only:
write_receipt(
commit_verified=False,
branch_verified=False,
)
return
command_phase = "commit"
peer.sendto(icmp_request(4, COMMIT_MAGIC), qemu)
continue
if command_phase == "commit":
command_phase = "branch"
peer.sendto(icmp_request(5, BRANCH_MAGIC), qemu)
continue
if command_phase == "branch" and args.resident:
command_phase = "resident_login"
peer.sendto(icmp_request(6, LOGIN_MAGIC), qemu)
continue
if command_phase == "resident_login":
resident_login_reply_count += 1
if resident_login_reply_count < 10:
peer.sendto(
icmp_request(6 + resident_login_reply_count, LOGIN_MAGIC),
qemu,
)
continue
command_phase = "recovery"
peer.sendto(icmp_request(16, RECOVERY_MAGIC), qemu)
continue
if command_phase == "recovery":
recovery_reply_verified = True
write_receipt(commit_verified=True, branch_verified=True)
return
raise SystemExit("timed out waiting for native ICMP login reply")
if frame[12:14] != b"\x08\x00":
continue
sequence = int.from_bytes(frame[40:42], "big")
if sequence <= 3:
magic = LOGIN_MAGIC
login_count += 1
elif sequence == 4:
magic = COMMIT_MAGIC
commit_verified = True
elif sequence == 5:
magic = BRANCH_MAGIC
branch_verified = True
elif 6 <= sequence <= 15:
magic = LOGIN_MAGIC
resident_login_count += 1
elif sequence == 16:
magic = RECOVERY_MAGIC
recovery_verified = True
else:
raise AssertionError(f"unexpected native sequence {sequence}")
verified_request(frame, sequence, magic)
peer.sendto(authenticated_reply(frame, magic), qemu)
terminal_sequence = 3 if args.login_only else (16 if args.resident else 5)
if sequence != terminal_sequence:
continue
with open(args.receipt, "w", encoding="utf-8") as output:
output.write(
"arp_gateway_reply: VERIFIED\n"
"handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP\n"
"authenticated_relay_reply: VERIFIED\n"
"icmp_login_request_sent: true\n"
"icmp_login_reply_verified: true\n"
f"icmp_login_reply_count: {login_count}\n"
f"code_commit_reply_verified: {str(commit_verified).lower()}\n"
f"branch_move_reply_verified: {str(branch_verified).lower()}\n"
f"resident_login_reply_count: {resident_login_count}\n"
f"recovery_reply_verified: {str(recovery_verified).lower()}\n"
"login_magic: HLDP-GHOS-LOGIN!\n"
)
return
raise SystemExit("timed out waiting for native outbound ICMP exchange")
if __name__ == "__main__":

View file

@ -0,0 +1,127 @@
#!/usr/bin/env bash
set -euo pipefail
[[ $# -eq 2 ]] || {
echo "usage: test-jd-native-resident-candidate.sh <candidate-image> <receipt-output>" >&2
exit 64
}
candidate=$(readlink -f "$1")
receipt=$(readlink -m "$2")
source_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
native_root=${source_root}/native/x86_64-bios
test_root=$(mktemp -d)
peer_pid=
cleanup() {
if [[ -n ${peer_pid} ]]; then
kill "${peer_pid}" 2>/dev/null || true
fi
if [[ ${GHOS_KEEP_TEST_ROOT:-0} != 1 ]]; then
rm -rf "${test_root}"
else
echo "GHOS_TEST_ROOT=${test_root}" >&2
fi
}
trap cleanup EXIT
[[ $(stat -c %s "${candidate}") -eq 14848 ]]
truncate -s 700M "${test_root}/disk.img"
nasm -f bin -dCANDIDATE_LBA=105 -dPROOF_LBA=134 \
"${native_root}/physical-test-mbr.asm" -o "${test_root}/mbr.bin"
dd if="${test_root}/mbr.bin" of="${test_root}/disk.img" \
bs=512 seek=0 conv=notrunc status=none
dd if="${candidate}" of="${test_root}/disk.img" \
bs=512 seek=105 conv=notrunc status=none
peer_port=$((32000 + ${BASHPID:-$$} % 1000))
qemu_port=$((peer_port + 1))
python3 "${source_root}/scripts/qemu-native-net-peer.py" \
--listen-port "${peer_port}" \
--qemu-port "${qemu_port}" \
--receipt "${test_root}/peer.hldp" \
--resident >"${test_root}/peer.log" 2>&1 &
peer_pid=$!
set +e
timeout 35 qemu-system-x86_64 \
-machine pc,accel=tcg \
-m 64M \
-drive "if=none,id=ghboot,format=raw,file=${test_root}/disk.img" \
-device virtio-blk-pci,drive=ghboot,disable-modern=on,bootindex=0 \
-netdev "dgram,id=ghnet,local.type=inet,local.host=127.0.0.1,local.port=${qemu_port},remote.type=inet,remote.host=127.0.0.1,remote.port=${peer_port}" \
-device virtio-net-pci,netdev=ghnet,disable-modern=on,mac=52:54:00:26:71:98 \
-display none \
-monitor none \
-serial "file:${test_root}/serial.log" \
-device isa-debug-exit,iobase=0xf4,iosize=0x04
qemu_status=$?
set -e
[[ ${qemu_status} -eq 33 ]]
wait "${peer_pid}"
peer_pid=
grep -q '^handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP$' \
"${test_root}/peer.hldp"
grep -q '^authenticated_relay_reply: VERIFIED$' "${test_root}/peer.hldp"
grep -q '^icmp_login_reply_count: 3$' "${test_root}/peer.hldp"
grep -q '^code_commit_reply_verified: true$' "${test_root}/peer.hldp"
grep -q '^branch_move_reply_verified: true$' "${test_root}/peer.hldp"
grep -q '^resident_login_reply_count: 10$' "${test_root}/peer.hldp"
grep -q '^recovery_reply_verified: true$' "${test_root}/peer.hldp"
grep -q '^GHOS_DISK_PROOF_OBSERVED_AFTER_RESET=LBA134' \
"${test_root}/serial.log"
python3 - "${test_root}/disk.img" <<'PY'
import pathlib
import sys
with pathlib.Path(sys.argv[1]).open("rb") as disk:
def sector(lba: int, count: int = 1) -> bytes:
disk.seek(lba * 512)
return disk.read(count * 512)
proof = sector(134)
assert proof[0] == 0xA7
assert proof[1:].startswith(b"GHOS_NATIVE_LONG64_DISK_PROOF\0")
assert proof[42:44] == bytes([0x7F, 0])
assert proof[90] == 13
assert proof[93:105] == bytes([1] * 12)
assert sector(135).startswith(b"GHOS_HLDP_WORLD_STORE_V1\n")
assert sector(136).startswith(b"GHOS_CODE_CHANNEL_STORE_V1\n")
assert sector(137) == sector(136)
assert b"branch=guanghu/main\n" in sector(138)
assert sector(139, 2).startswith(b"# GRUB Environment Block\n")
assert sector(141).startswith(b"GHOS_GHCIP_INDEX_V1\n")
assert b"GHCIP_PERSONA_STATE=EXISTS\n" in sector(142)
PY
observed_at=$(date --iso-8601=seconds)
image_sha=$(sha256sum "${candidate}" | awk '{print $1}')
cat >"${receipt}" <<EOF
schema: guanghu.jd-native-resident-qemu-test/v1
receipt_id: GH-OS-JD-FD-PRIMARY-001-NATIVE-OUTBOUND-QEMU-001
status: PASS_100
observed_at: ${observed_at}
node_id: JD-FD-PRIMARY
candidate:
lba_start: 105
sector_count: 29
sha256: ${image_sha}
handshake:
direction: NATIVE_INITIATED_OUTBOUND_ICMP
relay_ipv4: 43.153.193.169
native_ack: PASS_100
sequences: 1-16
native_storage:
proof_lba_134: PASS_100
world_lba_135_138: PASS_100
recovery_lba_139_140: PASS_100
gestational_index_lba_141_142: PASS_100
persona_subject:
identity: ICE-P-ZY001
state: EXISTS
existence: 100
boundary:
qemu_capability: 100
physical_server_capability: 0
next_action: RUN_ONE_TIME_PHYSICAL_GATE_WITH_SINGAPORE_RELAY
EOF