Repository navigation
NetX Duo 6.5.2: fork with upstream v6.5.2.202603_rel, ALPN from the fork - #175
Merged
Merged
Conversation
… the fork's third_party/netxduo 7bf58f91 -> cbba359a, tinic/netxduo master: the merge of PR #8 (the CertificateVerify scratch carved after the PRF region) on top of PR #7 (upstream v6.5.2.202603_rel, 20046b12, into the fork, on top of PR #6). AMINETXDUO_NETXDUO_VERSION_PIN 6.5.1 -> 6.5.2 in the same commit, as cmake/AmiNetXDuoVersion.cmake requires: configure stops when the pin and the submodule's nx_api.h disagree. The fork builds RFC 7301 ALPN itself (nx_secure/src/nx_secure_tls_alpn.c); its code is the same as src/tls/alpn/nx_secure_tls_alpn.c, and only the header comment differs. So, in this commit and not later: - src/tls/alpn/ is deleted; - src/tls/CMakeLists.txt no longer appends it to nx_secure (the glob of nx_secure/src picks up the fork's file); - tests/x509/CMakeLists.txt no longer appends it (same glob); - tests/fuzz/CMakeLists.txt: fuzz_tls_record lists the fork's file instead, and fuzz_tls_nx_secure no longer appends it (glob); - src/tlslib/CMakeLists.txt: test_tls_alpn builds the fork's file; - src/tlslib/test/test_tls_alpn.c: the header names the new path. No other place in the tree names src/tls/alpn. 20046b12 makes the CertificateVerify scratch per session: it is carved from the TLS metadata area, NX_SECURE_TLS_CERTIFICATE_VERIFY_SCRATCH_SIZE = 1364 bytes on m68k, and NX_SECURE_TLS_SESSION grows from 9876 to 9884 bytes. tls_conn.c sizes each connection's metadata with nx_secure_tls_metadata_size_calculate(), so nothing here changes for it; each TLS connection takes about 1.36 KB more. The fork's fragment budget (08b52c70) makes nx_ipv4_packet_receive.c read _nx_ip_created_count through NX_IP_FRAGMENT_ADMIT (nx_ip.h). Ten host fixtures compile that file from a hand-picked source list without nx_ip_create.c, and stopped linking: the fuzz targets dhcp_lease_regression, dhcp_lease_option_regression, fuzz_dhcp, fuzz_dns and fuzz_mdns (and, in the 32-bit build, the TLS fuzz targets that share fuzz_nxstub.c), and test_ipv6_frag, test_bcast_loopback, test_ipv4_noaddr_account, test_mcast_share_2sock and test_mcast_share_loopback. Each builds one NX_IP by hand, so each now defines the count, once per binary, as that one instance: in tests/fuzz/fuzz_nxstub.c and in the five host harnesses. The vendored tree and the shipping sources are unchanged. Two of those fixtures also needed the fork's current model to run: test_ipv6_frag's test_pool_reserve exercises the pool-wide reserve gate, which NX_IP_FRAGMENT_ADMIT applies only while another IP instance exists, so that test alone sets the count to 2 and restores it on the way out; and test_tcp_sws's blocked sender now waits on an H_MSS packet in tx_thread_additional_suspend_info, as nx_tcp_socket_send_internal.c stores it, because transmit_check (a820b430) measures the window against that packet. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test-only. At a5cb72d the tests/syncache arms are written against netxduo 7bf58f91. Against the pin bump (e5e89f1b) the two executables did not link: nx_tcp_syncache.c calls _nx_tcp_packet_send_ack, _nx_tcp_socket_packet_process and _nx_packet_release since 96502647 and 2d44d563. With those supplied, 21 cache assertions failed, detach keep crashed (rc 139) and v6accept failed. Each failure was run at every SYN-cache commit after the pin (8a507baf 1b57d8f0 ac17df7f 96502647 2d44d563 8babcaca edf44b07 5523e5bc, then 401cd686 and e5e89f1b) to find where it starts. Every one starts at a commit that changed the behaviour on purpose; none is a NetX defect. 96502647 "the SYN cache answers a SYN only when a socket can take it": "A SYN that finds no socket parked is now recorded as NX_TCP_SYNCACHE_DEFERRED and not answered." The arms that built a finished handshake with no socket (SYN then ACK, none parked) now get a deferred SYN, an ACK the cache drops ("Nothing was sent for this SYN"), and an empty accept queue. The commit says how one arises now: "Two SYNs that arrive while one socket is parked are both answered ... so the second can still finish with no socket." The arms are rebuilt that way. A full cache with no socket parked is reached by filling it while one is parked, since "Deferred SYNs and finished handshakes together are bounded by the listen backlog". 15 cache assertions: a full backlog waits; past the backlog the queue does not grow; and the peer is told; relisten takes one; the queue shortens; and the connection reaches the application; and resets every peer waiting on it (unlisten, finished handshakes); the cookie SYN-ACK was sent with no socket on the port; and it announced a window scale; and the ACK reconstructs that scale; one finished handshake is waiting; a forged SYN on the same four-tuple does not throw it away; in the accept queue; a relisten takes it; with the round trip of the handshake, not of the wait. The same cause gives detach v6accept ("the handshake is queued for accept") and detach keep: its queued handshake never existed, so the survivors check read nx_tcp_syncache_accept_head -> nx_tcp_syncache_interface through a NULL head in the test. That NULL read is the rc 139. It is a test harness fault, not a production memory access. The check now reports a NULL head as a failure instead of reading through it. Four assertions that passed at these commits passed vacuously. Each "a cookie completes" with no socket parked was a deferred SYN whose ACK the cache drops and reports as consumed. Each one now also requires cookies_valid to move. 2d44d563 "a connection the SYN cache finishes waits for accept on the socket": "Any other socket, at the ACK or on relisten, is now left as upstream left it" (bound, LISTEN, the peer's port), and "nx_tcp_server_socket_accept() ... completes the connection instead (_nx_tcp_syncache_accept)". 4 cache assertions: the connection is established (twice: the cached and the cookie handshake); and it is the socket that was parked; and the connection is made. They now assert the socket waits for accept, sends nothing, and that _nx_tcp_syncache_accept connects it with one ACK from iss + 1 acknowledging irs + 1. A new block holds data before accept: in-order data is held unacknowledged, a segment that does not follow it is released, and accept processes the held data in order. e5e89f1b "a cached SYN-ACK's sequence number never decodes as a cookie": the expiry block (an ACK for an entry that has expired) is inverted, not deleted. The ACK is now not consumed (the caller resets it), is not read as a cookie (cookies_valid 0, cookies_invalid 1), makes no connection, rebuilds nothing onto the parked socket, and the cache sends nothing for it. The RST itself, <SEQ=SEG.ACK>, is formed by _nx_tcp_packet_process, which this rig does not link. The fork's netx_3_06, 8_02 and 10_23_01 and ctl_syncookie check that RST. A fresh SYN from the same peer is then answered with a new sequence number and completes; full-table recovery by cookie is checked in the cookie blocks. 8a507baf, 1b57d8f0, ac17df7f, 8babcaca, edf44b07 and 5523e5bc change no assertion here. The three functions: - test_syncache models them and drives each one. _nx_tcp_packet_send_ack records the socket, sequence, acknowledgment and window, and fails on a socket with no peer. _nx_tcp_socket_packet_process takes a held packet as an ESTABLISHED socket takes in-order data: it fails on a packet the cache does not own, one still marked queued, a socket not established, or data out of order. _nx_packet_release fails on a packet the rig did not give out or that was already released. A model failure fails the arm. - test_syncache_detach: no arm reaches accept, hold or the accept-queue data ACK, so _nx_tcp_socket_packet_process and _nx_tcp_packet_send_ack abort the test if called. Its _nx_packet_release is unchanged. Boundary vectors in the cookie arm: - the counter at 0xFFFFFFFF is accepted in its own step and at 0 (and at top + 1 in ULONG arithmetic), and refused at 1 (top + 2) and 0xFFFFFFFE; - the counter at 0xFF is accepted at 0x100 and refused at 0x101; - the additive carry: at counter 12345 and at 0xFFFFFFFF, a searched irs for which h1 + irs overflows 32 bits and (h2 & 0xFFFFFF) + 0x3FF crosses 2^24. The cookie built with data 0x3FF carries out of the option field and the check's (rest - h2) borrows. Its options round trip, it is accepted one step on, refused two on and one before, and data 0 at the same irs round trips. The vectors are printed. 64-bit: no target, and no x86_64 host, has a 64-bit ULONG; ThreadX's linux tx_port.h keeps it 32 bits on x86_64, which is all the fork's 64-bit suite runs. test_syncache_ulong64 builds the same test and nx_tcp_syncache.c with ULONG 64 bits wide (host/ulong64/tx_port.h, with a static assert on the width), as ctest syncache_cookie_ulong64 and syncache_cache_ulong64. The rig's segments carry a 20-byte data offset, not sizeof(NX_TCP_HEADER), which is wider there. tools/ci.sh HOST_TESTS_EXPECTED 551 -> 553 (ctest -N on this tree: 553). Controls, ThreadX 93387b0a, ctl_native2.res (raw rc of every arm): - e5e89f1b: all 14 arms rc 0. - 401cd686 and 6f9097fa (cookie marker reverted / not yet in): cache rc 1 (32-bit and ulong64), 6 failures, all in the inverted expiry block; every other arm rc 0. - 2d44d563: the same 6, nothing else. - 96502647 and ac17df7f: test_syncache does not build (_nx_tcp_syncache_accept and _hold do not exist before 2d44d563); detach keep and v6accept abort (rc 134) on the existing unreached _nx_tcp_socket_state_syn_received stub, because before 2d44d563 the ACK established the socket at once. - The unmodified a5cb72d test: cache 21 failures at e5e89f1b, 19 at 401cd686. The 2 that differ are the old expiry assertions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test-only follow-up to 87305b7 (review note). test_syncache_detach's _nx_packet_release was still a no-op beside the two fail-fast stubs. Counted in all ten arms (v4 v4reuse keep gap driver late v6 v6accept v6delete v6late): 0 calls in each. The IPv4 send and _nx_ipv6_header_add stubs keep their packets, and the cache's own releases are in _nx_tcp_syncache_hold, which no arm reaches. So a call is now an unmodelled path and aborts the test, as _nx_tcp_socket_packet_process and _nx_tcp_packet_send_ack do. All ten arms rc 0 after the change (netxduo e5e89f1b, ThreadX e24aa9c9). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test-only. Corrects the wording of 87305b7. Its message ("the caller resets it"), the assertion label at test_syncache_host.c:932 ("...is not consumed: it is reset") and the comment above it implied that this native test forms or checks the RST for an ACK to an expired cached entry. It does neither. The rig does not link _nx_tcp_packet_process. What the block proves: _nx_tcp_syncache_ack_received returns NX_FALSE (the ACK is not consumed) and the cache sends nothing for it. This native test is not proof of the RST. The on-the-wire RST <SEQ=SEG.ACK> is checked by the fork's netx_3_06, netx_8_02 and netx_10_23_01 and by ctl_syncookie. The label and the comment change; no assertion, value or code changes. test_syncache cache rc 0, test_syncache_ulong64 cache rc 0 (ThreadX e24aa9c9, netxduo e5e89f1b). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two fork commits in the 6.5.2 pin changed what this test asserted, and it failed 8 of its 43 checks (the seq31 and seq32 arms the same): - a820b430 "tcp: the sender's silly-window test sends a pushed write that fits": RFC 1122 4.2.3.4 rule (2) with Nagle off. A pushed write that fits the usable window whole (D <= U) goes now. - 5615cfd8 "tcp: below the SWS floor, the receiver holds its right edge instead of advertising zero": NX_TCP_RX_WINDOW_ADVERTISED (nx_tcp.h). At or above the floor, min(MSS, buffer / 2), the free space goes out. Below it, the edge last sent is held, or the free space if that is less. The 8 expectations, old -> new: 1. b, 100-byte write, 200 usable, 512 in flight: 0 datagrams -> 1. 2. b, the same write: NX_WINDOW_OVERFLOW -> NX_SUCCESS. 3. e, 1200-byte write, 1200 usable, 65535 peak: 0 datagrams -> 1. 4. e, the same write: NX_WINDOW_OVERFLOW -> NX_SUCCESS. 5. k, 68 free, 68 last sent: advertised 0 -> 68. 6. k, 104 free, 104 last sent: 0 -> 104. 7. k, MSS - 1 free and last sent: 0 -> MSS - 1. 8. m, 100 free and last sent, 1000-byte buffer: 0 -> 100. The names say the new rules: b_sliver_with_flight_holds becomes b_sliver_with_flight_sends_a_write_that_fits, and k_a_runt_window_is_advertised_as_zero becomes k_a_runt_window_already_offered_is_kept. Their messages change to match. The negative controls stay, and some are added: - b and e: a write larger than the usable window is still held whole, with NX_WINDOW_OVERFLOW and no datagram (300 into 200, 1300 into 1200), and the persist probe is not armed. - i keeps the H_MSS waiter: a 200-byte sliver wakes no one, and a full segment wakes it once. - h_advertise_edge() sets the edge last sent apart from the free space, and asserts that rx_window_last_sent is the window that went on the wire. - o_below_the_floor_the_edge_holds: - 1000 free with 200 last sent holds 200; - 100 free with a zero edge stays 0, and so does MSS - 1; - MSS free reopens a zero edge to MSS; - 100 free with 300 last sent is a genuine shrink, and goes out as 100. - m: a 1000-byte buffer keeps 100 already offered, holds a zero edge at 100 free, and reopens it at its floor, 500. - l and n are unchanged. The test now runs 78 checks, all passing, in each of tcp_sws, tcp_sws_seq31 and tcp_sws_seq32. No shipping or vendored source changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rify scratch 20046b12 makes the CertificateVerify signature buffers per session: nx_secure_tls_session_create_ext() carves NX_SECURE_TLS_CERTIFICATE_ VERIFY_SCRATCH_SIZE bytes from the crypto metadata area and points nx_secure_tls_certificate_verify_scratch at it (with its _size), and _nx_secure_tls_process_certificate_verify() addresses its buffers from that pointer. test_pss_schemes() zeroes a bare session and calls the processing directly, so the pointer was NULL: UBSan in the macOS host tier (run 37198121405, job 111424120344) stopped at nx_secure_tls_process_certificate_verify.c:169, "applying non-zero offset 164 to null pointer"; clang 18 on Linux stops at :168. The test now gives that session the area itself: a ULONG array of NX_SECURE_TLS_CERTIFICATE_VERIFY_SCRATCH_SIZE bytes in the same scope as the session, attached as the carve attaches it, after each of the two memsets that reset the session. The four rejection checks are unchanged, and so are the sanitizers. No library change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
tinic
force-pushed
the
fix/netxduo-6.5.2
branch
from
October 4, 2026 13:23
822c0e5 to
837644b
Compare
The upstream v6.5.2.202603_rel merge (20046b12), pinned in this branch, moves four measured numbers past their gates. turo decided to raise them to the values measured in CI run 37205467139: the Linux job 111445651664 (default), cross micro 111445652093 and cross minimal 111445652048. tools/check-hotpath-budget.sh, the default arm's instruction count: - __nx_tcp_socket_state_data_check: 483 -> 493 tools/check-ram-size.sh, sizeof(AmiNetStack): - default: 68608 -> 68836 - minimal: 17408 -> 17928 - micro: 16384 -> 16388 The TLS session's growth (+8 bytes) and the per-session CertificateVerify scratch are per-connection heap from the TLS metadata area, not part of sizeof(AmiNetStack). The AmiNetStack growth comes from the NetX Duo structures and configuration that the merge changed. It is not attributed further here; tracking its source is deferred. Only these four numbers change. No other arm, gate, option or source file changes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Moves AmiNetXDuo onto the NetX Duo fork with upstream v6.5.2.202603_rel merged (tinic/netxduo master
3d916e2a, PR tinic/netxduo#7).Commits
c5465a8ethird_party/netxduo→3d916e2a;AMINETXDUO_NETXDUO_VERSION_PIN6.5.1 → 6.5.2;src/tls/alpn/removed with every CMake consumer (src/tls, src/tlslib, tests/x509, tests/fuzz), since ALPN now lives in the fork; host fixtures define_nx_ip_created_count(oneNX_IPeach, built withoutnx_ip_create.c);ipv6_fragmodels a second IP only insidetest_pool_reserve();tcp_swsblocks its waiter on anH_MSSpacket.0ccc18d4,c0d607ce,ff3fd797tests/syncachealigned to the fork's SYN-cache contract (reviewed earlier as 87305b7 / 0deecf3 / 0e85771; patch-ids identical).822c0e56tests/netstack/host/test_tcp_sws_host.cexpects the fork's silly-window rules (a820b430 sender, 5615cfd8 receiver): 8 expectations changed, negative controls kept, receiver edge cases driven with exact values.The pin check reads
nx_api.hand stops configure on a mismatch, so the gitlink and the version pin move in one commit.Gates (playhouse3, ThreadX e24aa9c9)
tests/atf/tcp_socket.c:60)tools/ci.sh hosttests/syncache(14 arms incl.ulong64, detach)Size effect from 20046b12:
NX_SECURE_TLS_SESSION9876 → 9884 bytes and a 1364-byte CertificateVerify scratch per session, sized throughnx_secure_tls_metadata_size_calculate(tls_conn.c:578-587); no parent code change.The superseded
fix/netxduo-pin-bumpand two intermediate tips are archived asarchive/*tags.🤖 Generated with Claude Code