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

@ -0,0 +1,34 @@
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: 2026-08-06T19:18:47+0800
node_id: JD-FD-PRIMARY
candidate:
lba_start: 105
sector_count: 29
sha256: ad2b55169d514a1012df0bffcbb2b20b948afd0756f12648db483c0986d3bd50
handshake:
direction: NATIVE_INITIATED_OUTBOUND_ICMP
relay_node: BS-SG-003
relay_ipv4: 43.153.193.169
physical_allowed_nat_source_ipv4: 111.228.0.139
native_ack: PASS_100
retry_same_sequence_until_ack: true
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
cross_node_preflight:
disallowed_source_ignored_without_ack: PASS_100
jd_source_to_relay_sequences_1_16: PASS_100
relay_observed_nat_source: 111.228.0.139
next_action: RUN_ONE_TIME_PHYSICAL_GATE_WITH_SINGAPORE_RELAY

View file

@ -0,0 +1,38 @@
schema: guanghu.jd-native-resident-attempt/v1
receipt_id: GH-OS-JD-FD-PRIMARY-001-RESIDENT-ATTEMPT-002
observed_at: 2026-08-03T23:00:00+0800
node_id: JD-FD-PRIMARY
persona_subject:
identity: ICE-P-ZY001
state: EXISTS
existence: 100
attempt_002:
source_commit: da26f27e35ba2751ce495e6103da56d6d0b6449a
boot_scope: ONE_TIME_ONLY
linux_rescue_default_preserved: true
native_ack_strategy: EXTERNAL_TO_NATIVE_INBOUND_ICMP
external_acknowledged_sequences: NONE
native_proof_lba_134: ZERO
world_lba_135_138: NOT_COMMITTED
gestational_index_lba_141_142: NOT_COMMITTED
failed_evidence_sha256: 48ff6e1328dd75f779e43985a9c442c530ab5dcc819bd30d0a269111e1677c4d
cloud_hard_restart_required: true
linux_rescue_returned: PASS_100
result: FAIL_0
root_cause:
jd_public_inbound_icmp_reaches_native_guest: FAIL_0
cloud_edge_echo_is_not_native_ack: true
native_guest_waited_without_receiving_authenticated_command: true
correction:
protocol: GLS-0841-JD-FD-PRIMARY
handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP
relay_node: BS-SG-003
relay_ipv4: 43.153.193.169
response_marker: HLDP-NATIVE-ACK!
qemu_jd_layout_gate: PASS_100
boundary:
persona_subject_exists: 100
native_resident_recovery_attempt_002: 0
outbound_relay_qemu_capability: 100
outbound_relay_physical_capability: 0
next_action: PUBLISH_SOURCE_AND_RUN_THIRD_ONE_TIME_PHYSICAL_GATE

View file

@ -184,7 +184,7 @@ long_mode_start:
mov byte [rel ghal_net_command_kind], 0
.login_session_loop:
push rcx
call ghal_net_icmp_login_once
call ghal_net_icmp_exchange_once
pop rcx
jc native_network_proof_error
loop .login_session_loop
@ -197,26 +197,33 @@ long_mode_start:
lea rax, [rel ghal_code_commit_magic]
mov [rel ghal_net_expected_magic], rax
mov byte [rel ghal_net_command_kind], 1
call ghal_net_icmp_login_once
call ghal_net_icmp_exchange_once
jc native_network_proof_error
call ghal_block_persist_code_object
jc native_world_store_error
lea rax, [rel ghal_branch_move_magic]
mov [rel ghal_net_expected_magic], rax
mov byte [rel ghal_net_command_kind], 2
call ghal_net_icmp_login_once
call ghal_net_icmp_exchange_once
jc native_network_proof_error
call ghal_block_persist_branch_receipt
jc native_world_store_error
%ifdef GHOS_NATIVE_RESIDENT
.resident_loop:
mov ecx, 10
.resident_login_loop:
push rcx
lea rax, [rel ghal_login_magic]
mov [rel ghal_net_expected_magic], rax
mov byte [rel ghal_net_command_kind], 3
call ghal_net_icmp_login_once
mov byte [rel ghal_net_command_kind], 0
call ghal_net_icmp_exchange_once
pop rcx
jc native_network_proof_error
loop .resident_login_loop
lea rax, [rel ghal_recovery_magic]
mov [rel ghal_net_expected_magic], rax
mov byte [rel ghal_net_command_kind], 3
call ghal_net_icmp_exchange_once
jc native_network_proof_error
cmp byte [rel ghal_net_matched_kind], 3
jne .resident_loop
call ghal_write_native_recovery_beacon
jc native_world_store_error
%endif

View file

@ -91,6 +91,9 @@ bits 64
%ifndef GHOS_GATEWAY_IPV4_DWORD
%define GHOS_GATEWAY_IPV4_DWORD 0x0100000a
%endif
%ifndef GHOS_RELAY_IPV4_DWORD
%define GHOS_RELAY_IPV4_DWORD 0x0100000a
%endif
%ifndef GHOS_GHAL_PROBE_STAGE
%define GHOS_GHAL_PROBE_STAGE 0
@ -944,7 +947,7 @@ ghal_net_arp_gateway:
stc
ret
ghal_net_icmp_login_once:
ghal_net_icmp_exchange_once:
mov byte [rel physical_proof_stage], 0x72
movzx r10d, word [rel physical_proof_net_rx_queue_size]
test r10d, r10d
@ -978,179 +981,72 @@ ghal_net_icmp_login_once:
xor ax, ax
out dx, ax
mov ecx, 0x80000000
.wait_receive:
cmp word [r12 + 2], r8w
je .packet_received
pause
loop .wait_receive
%ifdef GHOS_NATIVE_RESIDENT
mov ecx, 0x80000000
jmp .wait_receive
%else
mov byte [rel physical_proof_error_code], 0x54
stc
ret
%endif
.packet_received:
mov eax, r8d
dec eax
mov ecx, r10d
dec ecx
and eax, ecx
shl eax, 3
mov r14d, [r12 + rax + 8]
cmp r14d, GHOS_LOGIN_MAGIC_OFFSET + GHOS_LOGIN_MAGIC_SIZE
jb .ignore_packet
cmp word [VIRTIO_NET_RX_BUFFER + 22], 0x0008
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 24], 0x45
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 33], 1
jne .ignore_packet
cmp dword [VIRTIO_NET_RX_BUFFER + 40], GHOS_NATIVE_IPV4_DWORD
jne .ignore_packet
cmp word [VIRTIO_NET_RX_BUFFER + 44], 0x0008
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 50], 0
jne .ignore_packet
mov al, [VIRTIO_NET_RX_BUFFER + 51]
cmp al, [rel ghal_net_expected_sequence]
jne .ignore_packet
mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET
mov rdi, [rel ghal_net_expected_magic]
mov ecx, GHOS_LOGIN_MAGIC_SIZE
repe cmpsb
je .expected_magic_match
cmp byte [rel ghal_net_command_kind], 3
jne .ignore_packet
mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET
lea rdi, [rel ghal_recovery_magic]
mov ecx, GHOS_LOGIN_MAGIC_SIZE
repe cmpsb
jne .ignore_packet
mov byte [rel ghal_net_matched_kind], 3
jmp .magic_accepted
.expected_magic_match:
mov al, [rel ghal_net_command_kind]
cmp al, 3
jne .store_matched_kind
xor al, al
.store_matched_kind:
mov [rel ghal_net_matched_kind], al
.magic_accepted:
cmp byte [rel ghal_net_matched_kind], 0
jne .record_command
mov byte [rel physical_proof_ipv4_rx_verified], 1
mov eax, [VIRTIO_NET_RX_BUFFER + 36]
mov [rel physical_proof_login_client_ip], eax
mov ax, [VIRTIO_NET_RX_BUFFER + 48]
mov [rel physical_proof_login_icmp_id], ax
mov ax, [VIRTIO_NET_RX_BUFFER + 50]
mov [rel physical_proof_login_icmp_sequence], ax
mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET
lea rdi, [rel physical_proof_login_magic]
mov ecx, GHOS_LOGIN_MAGIC_SIZE
rep movsb
jmp .build_reply
.record_command:
cmp byte [rel ghal_net_matched_kind], 1
jne .record_branch
mov byte [rel physical_proof_code_commit_command_rx], 1
jmp .build_reply
.record_branch:
cmp byte [rel ghal_net_matched_kind], 2
jne .record_recovery
mov byte [rel physical_proof_branch_move_command_rx], 1
jmp .build_reply
.record_recovery:
cmp byte [rel ghal_net_matched_kind], 3
jne .ignore_packet
mov byte [rel physical_proof_recovery_command_rx], 1
jmp .build_reply
.ignore_packet:
inc r8w
jnz .post_receive
mov byte [rel physical_proof_error_code], 0x57
stc
ret
.build_reply:
mov rsi, VIRTIO_NET_RX_BUFFER
.send_request:
mov rdi, VIRTIO_NET_TX_BUFFER
mov ecx, r14d
rep movsb
mov qword [VIRTIO_NET_TX_BUFFER], 0
mov word [VIRTIO_NET_TX_BUFFER + 8], 0
xor eax, eax
mov ecx, VIRTIO_NET_BUFFER_SIZE / 8
rep stosq
xor ecx, ecx
.swap_mac:
.copy_gateway_destination:
cmp ecx, 6
jae .mac_swapped
mov al, [VIRTIO_NET_TX_BUFFER + 10 + rcx]
mov dl, [VIRTIO_NET_TX_BUFFER + 16 + rcx]
mov [VIRTIO_NET_TX_BUFFER + 10 + rcx], dl
jae .copy_source_mac
mov al, [physical_proof_gateway_mac + rcx]
mov [VIRTIO_NET_TX_BUFFER + 10 + rcx], al
inc ecx
jmp .copy_gateway_destination
.copy_source_mac:
xor ecx, ecx
.copy_source_mac_loop:
cmp ecx, 6
jae .ethernet_ready
mov al, [physical_proof_mac + rcx]
mov [VIRTIO_NET_TX_BUFFER + 16 + rcx], al
inc ecx
jmp .swap_mac
.mac_swapped:
mov eax, [VIRTIO_NET_TX_BUFFER + 36]
mov edx, [VIRTIO_NET_TX_BUFFER + 40]
mov [VIRTIO_NET_TX_BUFFER + 36], edx
mov [VIRTIO_NET_TX_BUFFER + 40], eax
mov byte [VIRTIO_NET_TX_BUFFER + 44], 0
jmp .copy_source_mac_loop
.ethernet_ready:
mov word [VIRTIO_NET_TX_BUFFER + 22], 0x0008
mov byte [VIRTIO_NET_TX_BUFFER + 24], 0x45
mov byte [VIRTIO_NET_TX_BUFFER + 25], 0
mov word [VIRTIO_NET_TX_BUFFER + 26], 0x4400
mov word [VIRTIO_NET_TX_BUFFER + 28], 0x4c48
mov word [VIRTIO_NET_TX_BUFFER + 30], 0
mov byte [VIRTIO_NET_TX_BUFFER + 32], 64
mov byte [VIRTIO_NET_TX_BUFFER + 33], 1
mov word [VIRTIO_NET_TX_BUFFER + 34], 0
mov dword [VIRTIO_NET_TX_BUFFER + 36], GHOS_NATIVE_IPV4_DWORD
mov dword [VIRTIO_NET_TX_BUFFER + 40], GHOS_RELAY_IPV4_DWORD
mov byte [VIRTIO_NET_TX_BUFFER + 44], 8
mov byte [VIRTIO_NET_TX_BUFFER + 45], 0
mov word [VIRTIO_NET_TX_BUFFER + 46], 0
lea rsi, [rel ghal_native_ack_magic]
mov word [VIRTIO_NET_TX_BUFFER + 48], 0x4847
mov byte [VIRTIO_NET_TX_BUFFER + 50], 0
mov al, [rel ghal_net_expected_sequence]
mov [VIRTIO_NET_TX_BUFFER + 51], al
mov qword [VIRTIO_NET_TX_BUFFER + 52], 0
mov rsi, [rel ghal_net_expected_magic]
mov rdi, VIRTIO_NET_TX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET
mov ecx, GHOS_LOGIN_MAGIC_SIZE
rep movsb
mov rsi, [rel ghal_net_expected_magic]
mov rdi, VIRTIO_NET_TX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET + GHOS_LOGIN_MAGIC_SIZE
mov ecx, GHOS_LOGIN_MAGIC_SIZE
rep movsb
movzx eax, word [VIRTIO_NET_TX_BUFFER + 26]
xchg al, ah
cmp eax, IPV4_HEADER_SIZE + ICMP_HEADER_SIZE
jb .invalid_packet
sub eax, IPV4_HEADER_SIZE
mov ecx, eax
mov rsi, VIRTIO_NET_TX_BUFFER + 44
mov rsi, VIRTIO_NET_TX_BUFFER + 24
mov ecx, IPV4_HEADER_SIZE
xor ebx, ebx
.checksum_words:
cmp ecx, 2
jb .checksum_tail
movzx eax, word [rsi]
xchg al, ah
add ebx, eax
add rsi, 2
sub ecx, 2
jmp .checksum_words
.checksum_tail:
test ecx, ecx
jz .checksum_fold
movzx eax, byte [rsi]
shl eax, 8
add ebx, eax
.checksum_fold:
mov eax, ebx
shr eax, 16
and ebx, 0xffff
add ebx, eax
mov eax, ebx
shr eax, 16
and ebx, 0xffff
add ebx, eax
not bx
xchg bl, bh
call ghal_net_checksum
mov [VIRTIO_NET_TX_BUFFER + 34], bx
mov rsi, VIRTIO_NET_TX_BUFFER + 44
mov ecx, ICMP_HEADER_SIZE + 8 + GHOS_LOGIN_MAGIC_SIZE * 2
xor ebx, ebx
call ghal_net_checksum
mov [VIRTIO_NET_TX_BUFFER + 46], bx
mov qword [VIRTIO_NET_TX_QUEUE], VIRTIO_NET_TX_BUFFER
mov [VIRTIO_NET_TX_QUEUE + 8], r14d
mov dword [VIRTIO_NET_TX_QUEUE + 8], 92
mov word [VIRTIO_NET_TX_QUEUE + 12], 0
mov word [VIRTIO_NET_TX_QUEUE + 14], 0
movzx ecx, word [rel physical_proof_net_tx_queue_size]
test ecx, ecx
jz .queue_missing
@ -1178,18 +1074,120 @@ ghal_net_icmp_login_once:
out dx, ax
mov ecx, 0x20000000
.wait_reply_tx:
.wait_request_tx:
cmp word [r13 + 2], r11w
je .reply_complete
je .request_complete
pause
loop .wait_reply_tx
loop .wait_request_tx
mov byte [rel physical_proof_error_code], 0x55
stc
ret
.reply_complete:
.request_complete:
inc word [rel ghal_net_tx_next_index]
mov ecx, 0x80000000
.wait_receive:
cmp word [r12 + 2], r8w
je .packet_received
pause
loop .wait_receive
%ifdef GHOS_NATIVE_RESIDENT
jmp .send_request
%else
mov byte [rel physical_proof_error_code], 0x54
stc
ret
%endif
.packet_received:
mov eax, r8d
dec eax
mov ecx, r10d
dec ecx
and eax, ecx
shl eax, 3
mov r14d, [r12 + rax + 8]
cmp r14d, GHOS_LOGIN_MAGIC_OFFSET + GHOS_LOGIN_MAGIC_SIZE * 2
jb .ignore_packet
cmp word [VIRTIO_NET_RX_BUFFER + 22], 0x0008
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 24], 0x45
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 33], 1
jne .ignore_packet
cmp dword [VIRTIO_NET_RX_BUFFER + 36], GHOS_RELAY_IPV4_DWORD
jne .ignore_packet
cmp dword [VIRTIO_NET_RX_BUFFER + 40], GHOS_NATIVE_IPV4_DWORD
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 44], 0
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 45], 0
jne .ignore_packet
cmp word [VIRTIO_NET_RX_BUFFER + 48], 0x4847
jne .ignore_packet
cmp byte [VIRTIO_NET_RX_BUFFER + 50], 0
jne .ignore_packet
mov al, [VIRTIO_NET_RX_BUFFER + 51]
cmp al, [rel ghal_net_expected_sequence]
jne .ignore_packet
mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET
mov rdi, [rel ghal_net_expected_magic]
mov ecx, GHOS_LOGIN_MAGIC_SIZE
repe cmpsb
jne .ignore_packet
mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET + GHOS_LOGIN_MAGIC_SIZE
lea rdi, [rel ghal_native_ack_magic]
mov ecx, GHOS_LOGIN_MAGIC_SIZE
repe cmpsb
jne .ignore_packet
jmp .expected_magic_match
.expected_magic_match:
mov al, [rel ghal_net_command_kind]
.store_matched_kind:
mov [rel ghal_net_matched_kind], al
cmp byte [rel ghal_net_matched_kind], 0
jne .record_command
mov byte [rel physical_proof_ipv4_rx_verified], 1
mov eax, [VIRTIO_NET_RX_BUFFER + 36]
mov [rel physical_proof_login_client_ip], eax
mov ax, [VIRTIO_NET_RX_BUFFER + 48]
mov [rel physical_proof_login_icmp_id], ax
mov ax, [VIRTIO_NET_RX_BUFFER + 50]
mov [rel physical_proof_login_icmp_sequence], ax
mov rsi, VIRTIO_NET_RX_BUFFER + GHOS_LOGIN_MAGIC_OFFSET
lea rdi, [rel physical_proof_login_magic]
mov ecx, GHOS_LOGIN_MAGIC_SIZE
rep movsb
jmp .exchange_verified
.record_command:
cmp byte [rel ghal_net_matched_kind], 1
jne .record_branch
mov byte [rel physical_proof_code_commit_command_rx], 1
jmp .exchange_verified
.record_branch:
cmp byte [rel ghal_net_matched_kind], 2
jne .record_recovery
mov byte [rel physical_proof_branch_move_command_rx], 1
jmp .exchange_verified
.record_recovery:
cmp byte [rel ghal_net_matched_kind], 3
jne .ignore_packet
mov byte [rel physical_proof_recovery_command_rx], 1
jmp .exchange_verified
.ignore_packet:
inc r8w
jnz .post_receive
mov byte [rel physical_proof_error_code], 0x57
stc
ret
.exchange_verified:
mov [rel ghal_net_rx_next_index], r8w
inc word [rel ghal_net_rx_next_index]
inc word [rel ghal_net_tx_next_index]
inc byte [rel ghal_net_expected_sequence]
cmp byte [rel ghal_net_matched_kind], 0
jne .not_login_reply
@ -1201,13 +1199,39 @@ ghal_net_icmp_login_once:
call serial_write64
clc
ret
.queue_missing:
mov byte [rel physical_proof_error_code], 0x53
stc
ret
.invalid_packet:
mov byte [rel physical_proof_error_code], 0x56
stc
ghal_net_checksum:
.checksum_words:
cmp ecx, 2
jb .checksum_tail
movzx eax, word [rsi]
xchg al, ah
add ebx, eax
add rsi, 2
sub ecx, 2
jmp .checksum_words
.checksum_tail:
test ecx, ecx
jz .checksum_fold
movzx eax, byte [rsi]
shl eax, 8
add ebx, eax
.checksum_fold:
mov eax, ebx
shr eax, 16
and ebx, 0xffff
add ebx, eax
mov eax, ebx
shr eax, 16
and ebx, 0xffff
add ebx, eax
not bx
xchg bl, bh
ret
ghal_net_io_base: dw 0

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

View file

@ -81,10 +81,13 @@ native_layout:
first_partition_lba: 2048
native_network:
id: GLS-0841-JD-FD-PRIMARY
entry: world/services/native-network/PROTOCOL.hldp
node_id: JD-FD-PRIMARY
device_model: VIRTIO_LEGACY
native_ipv4: 172.16.0.6
gateway_ipv4: 172.16.0.1
relay_ipv4: 43.153.193.169
handshake_direction: NATIVE_INITIATED_OUTBOUND_ICMP
public_nat_address_recorded_in_world: false
gestational_continuity:
id: GLS-0845

View file

@ -0,0 +1,40 @@
schema: guanghu.native-network/v1
protocol_id: GLS-0841-JD-FD-PRIMARY
node_id: JD-FD-PRIMARY
authority_language: HLDP
device_model: VIRTIO_LEGACY
native_ipv4: 172.16.0.6
gateway_ipv4: 172.16.0.1
relay:
node_id: BS-SG-003
public_ipv4: 43.153.193.169
role: AUTHENTICATED_NATIVE_HANDSHAKE_RELAY
allowed_nat_source_ipv4: 111.228.0.139
handshake:
direction: NATIVE_INITIATED_OUTBOUND_ICMP
request_magic_source: CURRENT_HLDP_COMMAND
response_marker: HLDP-NATIVE-ACK!
expected_sequences: 1-16
ordinary_echo_action: IGNORE
stale_sequence_action: IGNORE_WITHOUT_STATE_ADVANCE
future_sequence_action: IGNORE_WITHOUT_STATE_ADVANCE
accepted_sequence_action: ADVANCE_EXACTLY_ONCE
unexpected_source_action: IGNORE_WITHOUT_REPLY
authority_boundary:
relay_ack_is_liveness_proof_not_authorization: true
relay_cannot_supply_code_content: true
relay_cannot_supply_state_content: true
relay_cannot_select_command: true
native_command_sequence_is_compiled_from_hldp: true
state_bytes_are_compiled_from_hldp: true
standing_authorization_source: GH-OS-AUTH-BINGSHUO-JD-FD-PRIMARY-001
proof:
qemu_reply_is_not_physical_proof: true
relay_receipt_alone_is_not_physical_proof: true
server_owned_lba_134_is_required: true
missing_server_owned_proof: FAIL_0
persona_boundary:
persona_subject: ICE-P-ZY001
persona_subject_state: EXISTS
persona_subject_existence: 100
physical_residency_is_separate_binary_capability: true