8000 T77 — Pass a box's replies on inbound flows its ingress admitted, on both gates · Issue #1826 · gominimal/minimal · GitHub
[go: up one dir, main page]

Skip to content

T77 — Pass a box's replies on inbound flows its ingress admitted, on both gates #1826

Closed

Description

@norrietaylor

Task

slice size difficulty model who estimated lines
Own-address egress is declared and enforced L needs care strongest an agent 1000 (480 code, 520 tests)

An own-address box with deny-all egress, or an allow-list that does not name its clients, and a published port answers a host client through the forwarder, through the hostname proxy and from a sibling box, on the native lane and on a VM-backed host, decided on both gates by the same reverse-tuple rule; the box's own outbound connect to the same client is still dropped silently; a reply record is created only by an inbound opening packet the gate delivered, ends on FIN, RST, its timeout or ingress revocation, and a flood of inbound flows stops at the per-box cap with the refusal counted.

Covers:

  • NET-040
  • NET-062

Layers:

  • core:
    • crates/sessions/src/core/egress.rs: one shared decision both gates call: a box frame whose 5-tuple exactly reverses a live inbound-flow record is admitted before any egress rule is consulted, deny_subnets and the infrastructure set included, and no other box frame is admitted by a record; the record type, keyed per box, with its timers (UDP 30 s unreplied and 300 s replied; TCP ends at FIN or RST, with an established idle cap as a working value) and the per-box cap as working values the two gates read from here so both hold one number
    • cargo nextest run -p sessions reply_on_admitted_inbound_flow_passes_egress
    • cargo nextest run -p sessions box_frame_never_opens_a_reply_record
  • daemon:
    • crates/minimald/src/net/switch.rs: the relay records an inbound flow when it delivers the opening frame to an admitted port (an inbound SYN for TCP, never a mid-stream ACK; the first datagram for UDP), never from a frame the box sent; a reply on a live record passes the shared decision ahead of the egress verdict; ingress revocation and session stop end the box's records; the table is bounded per box with a bounded sweep, and at the cap a new inbound flow is refused at ingress toward the client while existing flows keep refreshing; every other egress refusal stays a NET-062 silent drop
    • cargo nextest run -p minimald deny_all_box_answers_its_published_port
    • cargo nextest run -p minimald inbound_record_created_only_by_a_delivered_opening_packet
    • cargo nextest run -p minimald repl 8000 y_records_end_on_fin_rst_timeout_and_revocation
    • cargo nextest run -p minimald inbound_flows_refused_at_the_per_box_cap
  • vmhost:
    • crates/minvmd/src/net/egress_gate.rs: the host gate keeps its own reply-flow table per registered box beside the host-side admission table, recording an inbound flow when it delivers the opening frame toward the box's switch address and passing the box's replies through the shared decision before the row's egress rules; the table is bounded and dropped with the row, and its at-cap counter appears in the VM host daemon's status
    • cargo nextest run -p minvmd host_gate_passes_replies_on_admitted_inbound_flows
    • cargo nextest run -p minvmd host_gate_reply_record_never_opened_by_the_box
    • scripts/session-e2e.sh: adds the case own_ip_deny_all_box_answers_published_port: a deny-all own-address box with a published port answers a host client through the forwarder, through the hostname proxy and from a sibling box, while its own outbound connect is still dropped
    • ./scripts/session-e2e.sh own_ip_deny_all_box_answers_published_port

Waits on:

Plan block
### T77 — Pass a box's replies on inbound flows its ingress admitted, on both gates
  slice: S4
  kind: task
  covers: NET-040, NET-062
  size: L
  est: 480 code, 520 tests
  executor: agent
  difficulty: needs care
  model: strongest
  diagnostics: the bundle's daemon and VM host daemon log tails carry one line per box when its reply-flow table first fills and one rate-limited line per inbound flow refused at the cap, and the status output carries each box's at-cap counter, so a box whose replies were or were not admitted reads so in a bundle
  observability: one info log line per box at its first inbound flow record, naming the box and the published port; one rate-limited warn line per inbound flow refused at the per-box cap; a counter per box of inbound flows refused at the cap
  layers:
    - core:
      - crates/sessions/src/core/egress.rs: one shared decision both gates call: a box frame whose 5-tuple exactly reverses a live inbound-flow record is admitted before any egress rule is consulted, deny_subnets and the infrastructure set included, and no other box frame is admitted by a record; the record type, keyed per box, with its timers (UDP 30 s unreplied and 300 s replied; TCP ends at FIN or RST, with an established idle cap as a working value) and the per-box cap as working values the two gates read from here so both hold one number
      test: cargo nextest run -p sessions reply_on_admitted_inbound_flow_passes_egress
      test: cargo nextest run -p sessions box_frame_never_opens_a_reply_record
    - daemon:
      - crates/minimald/src/net/switch.rs: the relay records an inbound flow when it delivers the opening frame to an admitted port (an inbound SYN for TCP, never a mid-stream ACK; the first datagram for UDP), never from a frame the box sent; a reply on a live record passes the shared decision ahead of the egress verdict; ingress revocation and session stop end the box's records; the table is bounded per box with a bounded sweep, and at the cap a new inbound flow is refused at ingress toward the client while existing flows keep refreshing; every other egress refusal stays a NET-062 silent drop
      test: cargo nextest run -p minimald deny_all_box_answers_its_published_port
      test: cargo nextest run -p minimald inbound_record_created_only_by_a_delivered_opening_packet
      test: cargo nextest run -p minimald reply_records_end_on_fin_rst_timeout_and_revocation
      test: cargo nextest run -p minimald inbound_flows_refused_at_the_per_box_cap
    - vmhost:
      - crates/minvmd/src/net/egress_gate.rs: the host gate keeps its own reply-flow table per registered box beside the host-side admission table, recording an inbound flow when it delivers the opening frame toward the box's switch address and passing the box's replies through the shared decision before the row's egress rules; the table is bounded and dropped with the row, and its at-cap counter appears in the VM host daemon's status
      test: cargo nextest run -p minvmd host_gate_passes_replies_on_admitted_inbound_flows
      test: cargo nextest run -p minvmd host_gate_reply_record_never_opened_by_the_box
    - e2e:
      - scripts/session-e2e.sh: adds the case own_ip_deny_all_box_answers_published_port: a deny-all own-address box with a published port answers a host client through the forwarder, through the hostname proxy and from a sibling box, while its own outbound connect is still dropped
      test: ./scripts/session-e2e.sh own_ip_deny_all_box_answers_published_port
  produces: none
  consumes:
    - crates/sessions/src/core/egress.rs
    - crates/minimald/src/net/switch.rs
    - crates/minvmd/src/net/egress_gate.rs
  proof: An own-address box with deny-all egress, or an allow-list that does not name its clients, and a published port answers a host client through the forwarder, through the hostname proxy and from a sibling box, on the native lane and on a VM-backed host, decided on both gates by the same reverse-tuple rule; the box's own outbound connect to the same client is still dropped silently; a reply record is created only by an inbound opening packet the gate delivered, ends on FIN, RST, its timeout or ingress revocation, and a flood of inbound flows stops at the per-box cap with the refusal counted.
  depends on:
    - blocked by #1808

Activity

  1. added
    kind:taskA task the plan skill rendered; the body carries ## Task
    size:L500 to 900 net lines; one PR, and the ceiling
    model:strongestThe strongest model available: unknown ground, or large work that needs care
    on Oct 2, 2026
  2. minimal-foundry commented on Oct 2, 2026

    @minimal-foundry
    Contributor

    Done. #1839 merged.

    branch agent/1826-pass-a-box-s-replies-on-inbound-flows-its-ingres · epic #1437 · PR #1839

    Updated 2026-10-28T06:17:32.453Z.

  3. added
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 3, 2026
  4. removed
    needs-humanAn agent handed off; a human must act, then clear this label. Set by defer and handoffs.
    on Oct 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind:taskA task the plan skill rendered; the body carries ## Taskmodel:strongestThe strongest model available: unknown ground, or large work that needs caresize:L500 to 900 net lines; one PR, and the ceiling

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      0