fix(native): accept physical TCP header options
This commit is contained in:
parent
bc41cf02d9
commit
f0b069f850
4 changed files with 124 additions and 19 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 = (
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue