code wiki / (root) / nx_connect.nx

nx_connect.nx

buildroot/runtime/nx_connect.nx

5442 B94 linesdepth 4pulls 4 transitivereach 912 importersview sourcekind librarytopic connect
docsdependenciesstructsconstsfunctions

about

nx_connect.nx -- BOUNDED, NON-BLOCKING TCP CONNECT. The missing primitive. WHY THIS EXISTS (2026-07-31, measured). Every stall this substrate has blamed on "slow peers" or "firewalled trackers" reduces to ONE fact: **** SO_RCVTIMEO / SO_SNDTIMEO DO NOT BOUND connect(). **** sys_set_socket_timeout() looks like protection and is not. A blocking connect() to a black-holed host runs to the kernel's SYN-retry exhaustion -- ~127 SECONDS -- no matter what socket timeouts are set. There were 100 sys_connect() call sites in runtime/ and NOT ONE of them was bounded. The substrate already knew, and worked AROUND it instead of fixing it. From nx_torrent_get.nx: "Run the wide announce in a DETACHED grandchild (double-fork) so a firewalled tracker's ~127s connect() hang can NEVER stall the download (nx_http_client has no connect timeout -- the very reason peers are fork-bounded)." A double-fork to dodge a missing timeout is a workaround, and it leaks the cost elsewhere: the forking parent still could not run its own reaper, so peer slots went idle and children piled up as zombies (measured: 32 zombies == the entire peer pool, parent 89.2% parked). nx_syscalls.nx's own sys_poll() comment already declared the intent -- "Used by the substrate's own network diagnostics (bounded non-blocking connect)" -- but the function was never written. This is it. MECHANISM: set O_NONBLOCK, connect() (expect -EINPROGRESS), poll(POLLOUT) with a real deadline, then re-issue connect() to learn the OUTCOME. That last step is not optional: poll reports a socket writable both when the handshake SUCCEEDED and when it FAILED (ECONNREFUSED / EHOSTUNREACH). The second connect returns 0 or -EISCONN for an established connection and the actual errno otherwise. The original file flags are SAVED and restored on every exit path, so callers get back exactly the socket they handed in -- blocking-mode callers stay blocking, and no caller needs to know this happened. That is what makes it a drop-in for the 100 existing sites. expect_exit: 0 license_tier: ORIGINAL

dependencies 2 imports · 173 importers

nx_syscalls.nx nx_fcntl.nx nx_connect.nx _galx_serve_gate.nx _galx_serve_gate_prod.nx _galx_ui_gate.nx _h2_serve_loopback_gate.nx _inet_fetch_authored.nx nx_anon_transport.nx nx_apm_collect.nx nx_aw_mtls_proxy.nx nx_aw_sni_router.nx nx_aw_tlsproxy.nx

diagram shows first 10 each side; +0 more imports, +163 more importers in the complete lists below.

imports: nx_syscalls.nxnx_fcntl.nx

imported by: _galx_serve_gate.nx_galx_serve_gate_prod.nx_galx_ui_gate.nx_h2_serve_loopback_gate.nx_inet_fetch_authored.nxnx_anon_transport.nxnx_apm_collect.nxnx_aw_mtls_proxy.nxnx_aw_sni_router.nxnx_aw_tlsproxy.nxnx_browse_text.nxnx_browser_image_demo_test.nxnx_browser_page_demo_test.nxnx_cert_autorenew.nxnx_cms_analytics_gate.nxnx_cms_argon_gate.nxnx_cms_blocks_gate.nxnx_cms_draft_gate.nxnx_cms_forms_gate.nxnx_cms_fuzz_gate.nxnx_cms_gate.nxnx_cms_multisite_gate.nxnx_cms_seo_gate.nxnx_cms_snapshot_gate.nxnx_cms_tls_front.nxnx_cms_tls_gate.nxnx_cms_webdev_gate.nxnx_code_index.nxnx_coedit_live_gate.nxnx_connect_gate.nxnx_dev_api_serve.nxnx_dist_serve.nxnx_doctor.nxnx_edge_probe.nxnx_email_live_gate.nxnx_email_webmail_gate.nxnx_embed_live_gate.nxnx_escl_probe.nxnx_f32_llm_serve.nxnx_fcntl_probe.nxnx_fin_serve.nxnx_fleet_doctor.nxnx_forge_model.nxnx_friend_video_caller.nxnx_funcheck.nxnx_gallery_gateway.nxnx_gallery_gateway_smoke.nxnx_gallery_gw_guard.nxnx_galx_bridge.nxnx_galx_seek_test.nxnx_gen.nxnx_gen_gateway.nxnx_gen_gateway_gate.nxnx_gen_live_probe.nxnx_gen_mesh_gate.nxnx_gen_multiworker_gate.nxnx_gen_orchestrator_gate.nxnx_gen_real_gate.nxnx_gen_worker_probe.nxnx_golive_dns_gate.nxnx_heal_lib.nxnx_health_eval.nxnx_health_probe.nxnx_home_auth_gate.nxnx_home_gate.nxnx_home_registry_gate.nxnx_hostctl.nxnx_http_client.nxnx_http_get_ua.nxnx_http_post.nxnx_http_post_gate.nxnx_http_proxy.nxnx_https_fetch_lib.nxnx_https_get_cli2.nxnx_https_get_happy_test.nxnx_https_loopback_test.nxnx_https_url_connect.nxnx_ipfilter_seed_gate.nxnx_ipp_transport.nxnx_kaprobe.nxnx_keeper.nxnx_lan_scan.nxnx_lan_signup_socket_gate.nxnx_legal_portal_live_gate.nxnx_lib_probe.nxnx_libprobe.nxnx_link_sentinel.nxnx_llm_batch_serve.nxnx_llm_probe.nxnx_loop_http.nxnx_media_e2e_gate.nxnx_meet_serve_gate.nxnx_mesh_autoscale.nxnx_mesh_gateway.nxnx_mesh_gen.nxnx_mesh_hostagent.nxnx_mesh_lb.nxnx_mesh_probe.nxnx_mgmt_data.nxnx_mineworld_mp_up.nx +73 more (shown cap 100 declared)

structs

none

consts

46const NX_CONN_EINPROGRESS: i64 = 115
47const NX_CONN_EISCONN: i64 = 106
48const NX_CONN_POLLOUT: i64 = 4
49const NX_CONN_PFD_SZ: i64 = 16
54const NX_CONN_DEFAULT_MS: i64 = 6000

functions

59func nx_connect_bounded(fd: i64, addr: *u8, addrlen: i64, timeout_ms: i64) -> i64
92func nx_connect_ok(fd: i64, addr: *u8, addrlen: i64) -> i64