fix(native): accept physical TCP header options

This commit is contained in:
冰朔 2026-08-07 06:06:18 +08:00
commit f0b069f850
4 changed files with 124 additions and 19 deletions

View file

@ -4,9 +4,12 @@
> >
> Persona subject: `ICE-P-ZY001 EXISTS_100`. > Persona subject: `ICE-P-ZY001 EXISTS_100`.
> >
> Current native residency remains `0` until the physical one-time boot, > Protected native residency and recovery control are `PASS_100`. Production
> automatic Linux rescue return, native default boot, and HLDP recovery return > cutover remains `0`: the 2026-08-07 physical anchor gate reached the native
> all produce server-owned receipts. > runtime and completed heartbeat sequences 1-6, but a real JD Cloud TCP SYN
> carried a 40-byte TCP header and exposed the fixed-header parser defect.
> Linux remains the unattended default while the option-aware parser is
> validated and the physical HTTP gate is rerun.
This directory is the first executable handoff from the registered HLDP This directory is the first executable handoff from the registered HLDP
language world to a native Guanghu OS. It is not a claim that Guanghu OS has language world to a native Guanghu OS. It is not a claim that Guanghu OS has

View file

@ -0,0 +1,55 @@
schema: guanghu.jd-native-anchor-physical-gate-receipt/v1
receipt_id: GH-OS-JD-FD-PRIMARY-NATIVE-ANCHOR-PHYSICAL-GATE-20260807-001
status: FAIL_0_PHYSICAL_TCP_HEADER_OPTIONS
observed_at: 2026-08-07T05:49:24+08:00
node_id: JD-FD-PRIMARY
accepted_repository_commit: 27c6ba2c4d9a9c2372d977b8adfdf802af7656e5
candidate:
lba_start: 105
sector_count: 29
sha256: 2911b5f6a067efb7b5b7ec330833cb9f8a6b965b5a05802770dd27032678f32f
cloud_firewall:
source: 43.153.193.169/32
destination: 111.228.0.139:3922
linux_listener_preflight: PASS_100
physical_cycle:
native_boot_executed: true
native_heartbeat_sequences_1_to_6: PASS_100
native_ssh_offline: PASS_100
native_anchor_http: FAIL_0_TCP_CONNECT_TIMEOUT
protected_recovery: PASS_100
linux_boot_id_before: e95b13e0-bf93-498d-a108-6ede5e947015
linux_boot_id_after: 8b39ec63-6776-4e65-94b7-099a6a6a5762
linux_default_preserved: gnulinux-simple-9e4550a0-452b-4f28-b5a5-d5364aa450f6
code_channel_http_after_recovery: 200
public_anchor_http_after_recovery: 200
physical_diagnosis:
captured_source: 43.153.193.169
captured_destination: 172.16.0.6:3922
ipv4_header_bytes: 20
tcp_header_bytes: 40
tcp_options: MSS_SACK_TIMESTAMP_WINDOW_SCALE
candidate_expected_tcp_header_bytes: 20
native_syn_ack_proof_byte: 0
native_http_response_proof_byte: 0
root_cause: FIXED_TCP_HEADER_OFFSET_REJECTED_REAL_SYN_OPTIONS
correction:
parser_accepts_ipv4_ihl: true
parser_accepts_tcp_data_offset_greater_than_5: true
request_payload_offset_is_dynamic: true
acknowledgement_payload_length_is_dynamic: true
qemu_syn_tcp_header_bytes: 40
qemu_get_tcp_header_bytes: 32
option_aware_qemu_gate: PASS_100
gates:
native_anchor_http_qemu_capability: 100
native_anchor_http_physical_capability: 0
public_front_door_native_anchor_equivalence: 0
code_channel_service_equivalence: 0
production_native_cutover: 0
server_receipt:
path: /guanghu/recovery/JD-FD-PRIMARY-native-anchor-physical-27c6ba2c4d9a9c2372d977b8adfdf802af7656e5/PHYSICAL-GATE-RECEIPT.hldp
sha256: e5f8071929a7a05fadc5b0283cef97962d53d57dd8d94bbe524e8148706af920
decision:
production_cutover: FORBIDDEN
next_action: BUILD_WITH_PRODUCTION_RECOVERY_CAPABILITY_THEN_REPEAT_ONE_TIME_PHYSICAL_HTTP_GATE

View file

@ -1295,19 +1295,43 @@ ghal_net_try_anchor_http:
jb .not_anchor jb .not_anchor
cmp word [VIRTIO_NET_RX_BUFFER + 22], 0x0008 cmp word [VIRTIO_NET_RX_BUFFER + 22], 0x0008
jne .not_anchor jne .not_anchor
cmp byte [VIRTIO_NET_RX_BUFFER + 24], 0x45 movzx eax, byte [VIRTIO_NET_RX_BUFFER + 24]
mov ecx, eax
and eax, 0xf0
cmp eax, 0x40
jne .not_anchor jne .not_anchor
and ecx, 0x0f
cmp ecx, 5
jb .not_anchor
shl ecx, 2
mov [rel ghal_anchor_rx_ipv4_header_size], cx
lea r15d, [ecx + VIRTIO_NET_HEADER_SIZE + ETHERNET_HEADER_SIZE]
lea eax, [r15d + TCP_HEADER_SIZE]
cmp r14d, eax
jb .not_anchor
cmp byte [VIRTIO_NET_RX_BUFFER + 33], 6 cmp byte [VIRTIO_NET_RX_BUFFER + 33], 6
jne .not_anchor jne .not_anchor
cmp dword [VIRTIO_NET_RX_BUFFER + 40], GHOS_NATIVE_IPV4_DWORD cmp dword [VIRTIO_NET_RX_BUFFER + 40], GHOS_NATIVE_IPV4_DWORD
jne .not_anchor jne .not_anchor
cmp word [VIRTIO_NET_RX_BUFFER + 46], GHOS_NATIVE_ANCHOR_PORT_NETWORK cmp word [VIRTIO_NET_RX_BUFFER + r15 + 2], GHOS_NATIVE_ANCHOR_PORT_NETWORK
jne .not_anchor jne .not_anchor
cmp byte [VIRTIO_NET_RX_BUFFER + 56], 0x50 movzx ebx, byte [VIRTIO_NET_RX_BUFFER + r15 + 12]
jne .not_anchor shr ebx, 4
test byte [VIRTIO_NET_RX_BUFFER + 57], 0x02 cmp ebx, 5
jb .not_anchor
shl ebx, 2
lea eax, [r15d + ebx]
cmp r14d, eax
jb .not_anchor
mov [rel ghal_anchor_rx_tcp_offset], r15w
mov [rel ghal_anchor_rx_tcp_header_size], bx
test byte [VIRTIO_NET_RX_BUFFER + r15 + 13], 0x02
jnz .handle_syn jnz .handle_syn
cmp dword [VIRTIO_NET_RX_BUFFER + 64], 0x20544547 add eax, 4
cmp r14d, eax
jb .handled_without_reply
sub eax, 4
cmp dword [VIRTIO_NET_RX_BUFFER + rax], 0x20544547
jne .handled_without_reply jne .handled_without_reply
mov byte [rel ghal_anchor_tcp_flags], 0x19 mov byte [rel ghal_anchor_tcp_flags], 0x19
mov rsi, ghal_anchor_http_response mov rsi, ghal_anchor_http_response
@ -1375,20 +1399,24 @@ ghal_net_send_anchor_tcp:
mov eax, [VIRTIO_NET_RX_BUFFER + 36] mov eax, [VIRTIO_NET_RX_BUFFER + 36]
mov [VIRTIO_NET_TX_BUFFER + 40], eax mov [VIRTIO_NET_TX_BUFFER + 40], eax
mov word [VIRTIO_NET_TX_BUFFER + 44], GHOS_NATIVE_ANCHOR_PORT_NETWORK mov word [VIRTIO_NET_TX_BUFFER + 44], GHOS_NATIVE_ANCHOR_PORT_NETWORK
mov ax, [VIRTIO_NET_RX_BUFFER + 44] movzx ecx, word [rel ghal_anchor_rx_tcp_offset]
mov ax, [VIRTIO_NET_RX_BUFFER + rcx]
mov [VIRTIO_NET_TX_BUFFER + 46], ax mov [VIRTIO_NET_TX_BUFFER + 46], ax
mov eax, 0x534f4847 mov eax, 0x534f4847
mov [VIRTIO_NET_TX_BUFFER + 48], eax mov [VIRTIO_NET_TX_BUFFER + 48], eax
mov eax, [VIRTIO_NET_RX_BUFFER + 48] mov eax, [VIRTIO_NET_RX_BUFFER + rcx + 4]
bswap eax bswap eax
movzx ecx, word [VIRTIO_NET_RX_BUFFER + 26] movzx edx, word [VIRTIO_NET_RX_BUFFER + 26]
xchg cl, ch xchg dl, dh
sub ecx, IPV4_HEADER_SIZE + TCP_HEADER_SIZE movzx ebx, word [rel ghal_anchor_rx_ipv4_header_size]
test byte [VIRTIO_NET_RX_BUFFER + 57], 0x02 sub edx, ebx
movzx ebx, word [rel ghal_anchor_rx_tcp_header_size]
sub edx, ebx
test byte [VIRTIO_NET_RX_BUFFER + rcx + 13], 0x02
jz .ack_payload jz .ack_payload
inc ecx inc edx
.ack_payload: .ack_payload:
add eax, ecx add eax, edx
bswap eax bswap eax
mov [VIRTIO_NET_TX_BUFFER + 52], eax mov [VIRTIO_NET_TX_BUFFER + 52], eax
mov byte [VIRTIO_NET_TX_BUFFER + 56], 0x50 mov byte [VIRTIO_NET_TX_BUFFER + 56], 0x50
@ -1522,6 +1550,9 @@ ghal_net_resident_retry_count: db 0
%ifdef GHOS_NATIVE_ANCHOR_SERVICE %ifdef GHOS_NATIVE_ANCHOR_SERVICE
ghal_anchor_tcp_flags: db 0 ghal_anchor_tcp_flags: db 0
ghal_anchor_tcp_payload_size: dw 0 ghal_anchor_tcp_payload_size: dw 0
ghal_anchor_rx_ipv4_header_size: dw 0
ghal_anchor_rx_tcp_offset: dw 0
ghal_anchor_rx_tcp_header_size: dw 0
%endif %endif
msg_ghal_net_discovered: db "GHOS_GHAL_VIRTIO_NET=DISCOVERED", 13, 10, 0 msg_ghal_net_discovered: db "GHOS_GHAL_VIRTIO_NET=DISCOVERED", 13, 10, 0

View file

@ -104,7 +104,10 @@ def tcp_frame(
sequence: int, sequence: int,
acknowledgement: int, acknowledgement: int,
payload: bytes = b"", payload: bytes = b"",
options: bytes = b"",
) -> bytes: ) -> bytes:
if len(options) % 4 or len(options) > 40:
raise ValueError("TCP options must be 32-bit aligned and no more than 40 bytes")
tcp = bytearray( tcp = bytearray(
struct.pack( struct.pack(
"!HHIIBBHHH", "!HHIIBBHHH",
@ -112,12 +115,13 @@ def tcp_frame(
ANCHOR_PORT, ANCHOR_PORT,
sequence, sequence,
acknowledgement, acknowledgement,
5 << 4, (5 + len(options) // 4) << 4,
flags, flags,
16384, 16384,
0, 0,
0, 0,
) )
+ options
+ payload + payload
) )
pseudo = GATEWAY_IP + GUEST_IP + b"\0\x06" + struct.pack("!H", len(tcp)) pseudo = GATEWAY_IP + GUEST_IP + b"\0\x06" + struct.pack("!H", len(tcp))
@ -228,6 +232,7 @@ def main() -> None:
ANCHOR_CLIENT_SEQUENCE + 1, ANCHOR_CLIENT_SEQUENCE + 1,
server_sequence + 1, server_sequence + 1,
request, request,
options=b"\x01\x01\x08\x0a\xd8\x8d\xec\x56\x00\x00\x00\x01",
), ),
qemu, qemu,
) )
@ -284,7 +289,18 @@ def main() -> None:
and sequence == 6 and sequence == 6
and not anchor_syn_sent and not anchor_syn_sent
): ):
peer.sendto(tcp_frame(0x02, ANCHOR_CLIENT_SEQUENCE, 0), qemu) peer.sendto(
tcp_frame(
0x02,
ANCHOR_CLIENT_SEQUENCE,
0,
options=(
b"\x02\x04\x05\x90\x04\x02\x08\x0a"
b"\xd8\x8d\xec\x56\x00\x00\x00\x00\x01\x03\x03\x07"
),
),
qemu,
)
anchor_syn_sent = True anchor_syn_sent = True
terminal = ( terminal = (