Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4b96de0
netstack runs ToyOS's own stack: the shell is the loop, the pipes and…
Japabu Oct 9, 2026
fe2b47f
The churn job reads departed owners and the places bound; a peer of t…
Japabu Oct 9, 2026
4d526be
The churn job asks a receive of netstack before its datagram exists
Japabu Oct 9, 2026
dd169bc
Merge main into the move
Japabu Oct 9, 2026
2bdb3d7
The move's record: six issues closed by named tests, the rest restate…
Japabu Oct 9, 2026
2ecf5bb
The streams job says which half is missing when its wakes do not come
Japabu Oct 9, 2026
ac3da90
The streams test dials its second peer once QEMU carries the first
Japabu Oct 9, 2026
803dc0d
Merge main, which carries the name's probing (#793), into the move
Japabu Oct 9, 2026
fa02cf7
Merge main, which carries the virtio crate and the shared device boun…
Japabu Oct 9, 2026
6e181c1
The DHCP client's refusals reach the log as the stack's do: one line …
Japabu Oct 9, 2026
a0b6f86
netstack: one receive waits on a socket, an accept the kernel refuses…
Japabu Oct 9, 2026
14a1f54
The pipe ABI's three missing words are an issue, the track's idle-str…
Japabu Oct 9, 2026
083d490
Merge wt/toyos-finreset (#803), the node's stream-end order, into the…
Japabu Oct 9, 2026
12ce152
Merge main, which carries the kernel's ChaCha20 generator (#802), the…
Japabu Oct 9, 2026
1f08141
netstack_streams reads the stream's end again, now that the node keep…
Japabu Oct 9, 2026
2d0b0aa
libc reads a stream's end as std does, and one boot of tests/netcase …
Japabu Oct 9, 2026
f3308fb
Merge main, which carries the lost name's retry (#800) and the node's…
Japabu Oct 9, 2026
04a46fb
The stream-ends peer's shut_first arm is one chain of calls, as clipp…
Japabu Oct 9, 2026
01bb4c8
The node ships no getter that only its tests read, and the two lookup…
Japabu Oct 9, 2026
409a4fa
The track records the node's link-down and INIT-REBOOT as unread on h…
Japabu Oct 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 7 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions issues/a-connect-between-two-accepts-is-reset.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,22 @@ metal harness's swapping boots, which that row was the one user of, and
`issues/the-host-cannot-reach-the-t14-while-it-runs-toyos.md` records the commit
that restores those.

netstack's listener is the node's now, whose queue is [tcp]'s: a connect
that arrives while another waits to be accepted is queued
(`a_connect_between_two_accepts_is_queued_not_reset`,
`userland/netstack/node/tests/listeners.rs`), and in a guest two host peers
that dial before any accept are both accepted (`netstack_streams`, which on
smoltcp ended `the listener was woken for 1 of two peers`). What is left of the
exit is `lan_swap`.

QEMU's own forward is a third place such a reset can come from, and it was
not ruled out of the reading above: its listener queues one connection, and a
host dial that arrives while one is queued is reset by QEMU with no SYN sent to
the guest. Measured while `netstack_streams` was written, with the host at a
load of 30 and twelve guests beside it: 3 of 8 runs red, the host's second
dial ending `Connection reset by peer (os error 54)` and the frames recorded
on the guest's card holding one SYN; none of 5 once the harness dialled its
second peer only after QEMU's table showed the first carried.

**Exit**: a listener that queues a connect arriving between two accepts, and
`lan_swap` restored and green.
31 changes: 0 additions & 31 deletions issues/a-handshake-nobody-finishes-holds-a-listeners-port-shut.md

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,8 @@ loopback delivers in. A red there prints the host's name and both answers.
The pipe ABI carries both halves (`toyos/src/net.rs`): a bind's request
carries its listener's options and `MsgType::TcpListenerSetOption` sets one
afterwards, and an accept's answer says what its connection holds
(`TcpOptions`). netstack answers the rule for both
(`userland/netstack/src/listen.rs`), but for the connection after a reset
handshake
(`issues/a-handshake-reset-before-it-ends-hands-its-option-to-the-next-connection.md`),
(`TcpOptions`). netstack answers the rule for both by the node's calls
(`userland/netstack/src/serve.rs`, `userland/netstack/node/src/listeners.rs`),
and the `libc_sockets` guest test reads it: `nodelay_accepted` by `toyos::net`, for a connection that
waited when the option was set, its wake read first, and for the next one
dialled; `tests/netcase/nodelay_kept.c` by libc's `setsockopt` and
Expand Down
58 changes: 0 additions & 58 deletions issues/a-netstack-client-cannot-tell-a-reset-from-the-peers-fin.md

This file was deleted.

9 changes: 6 additions & 3 deletions issues/a-received-handle-has-no-knowable-type.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ typed can be ended by whoever sent it.** The sender needs nothing but
- A window client receives its buffer the same way (`userland/toyos-window/src/lib.rs`).
- blockd maps the region a client sends with its open (`Region::adopt` in
`userland/blockd/src/region.rs`), so a *client* holding its connector ends it.
- netd adopts as pipes the two handles a client sends with a piped socket
(`DataPipes::take`) and the one with a piped bind (`handle_tcp_bind_piped`),
both in `userland/netd/src/main.rs`: a *client* ends it the same way.
- netstack adopts as pipes the two handles a client sends with a piped socket
(`data_pipes`) and the one with a piped bind (`Sockets::listen`), both in
`userland/netstack/src/serve.rs`: a handle that is no pipe end answers a
refusal the node ends that client's stream or listener for
(`userland/netstack/src/pipes.rs`), and a datagram socket's are netstack's
own to read and write.

Nothing in the tree is hostile today, so nothing fails. The property the
architecture claims — that a process cannot be harmed by what it was not given —
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ opened: 2026-10-08

# A stream its peer reset refuses the option requests a host answers

netstack lets a piped connection's socket and id go once the wire is finished
and it has closed both of its pipe ends (`bridge_piped`,
`userland/netstack/src/main.rs`). A peer's reset does both at once, so a
client that still holds the stream names an id netstack no longer has, and
`handle_tcp_set_option` answers it `ERR_NOT_CONNECTED`. Before the socket left
with its bridge it answered from the kept socket.
The node lets a stream go once it holds neither of its pipe ends
(`userland/netstack/node/src/streams.rs`), and netstack's id for it goes with
it (`userland/netstack/src/serve.rs`, `Sockets::settle`). A peer's reset ends
both pipes at once, so a client that still holds the stream names an id
netstack no longer has, and `Sockets::set_option` answers it
`ERR_NOT_CONNECTED`.

What a host answers `std::net::TcpStream` on a stream whose peer reset it,
after the read that reported the reset:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ one bit: the peer's FIN, or a failure. The node knows which failure
(`toyos_net_tcp::Failure`: a reset, R2's timeout, an ICMP error), and std
answers every one `ConnectionReset`, where Linux answers a connection [tcp]
gave up on `ETIMEDOUT` and one an ICMP error ended `EHOSTUNREACH` or
`ENETUNREACH`. libc reads no failure yet
(`issues/a-netstack-client-cannot-tell-a-reset-from-the-peers-fin.md`), and
the change the move carries for it answers every one `ECONNRESET`.
`ENETUNREACH`. libc answers every one `ECONNRESET`
(`userland/libc/src/streamend.rs`).

A pipe's end carries no word, and every other carrier costs what this one does
not: a third pipe or a kept request connection is a 2 MiB page each
Expand Down
6 changes: 2 additions & 4 deletions issues/libc-answers-epipe-and-raises-no-sigpipe.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,8 @@ and none of those
`issues/a-childs-end-is-an-event-and-a-parent-takes-its-children-down.md`
has it imitate is `SIGPIPE`. So every write behaves as if `MSG_NOSIGNAL` were
given, and a C program that relies on the default action to stop writing into a
closed pipe runs on, and stops only if it reads the error. `send` on a stream answers `EIO` for every refusal today; the libc
change the move carries for
`issues/a-netstack-client-cannot-tell-a-reset-from-the-peers-fin.md` answers
`EPIPE` after `shutdown(SHUT_WR)`, and raises nothing either.
closed pipe runs on, and stops only if it reads the error. `send` on a stream answers `EPIPE` after
`shutdown(SHUT_WR)` (`userland/libc/src/socket.rs`), and raises nothing either.

Whether libc raises `SIGPIPE` on these, or states the departure as it states
others, is a decision of libc's design that nobody has made.
Expand Down
10 changes: 10 additions & 0 deletions issues/most-t14-leases-land-one-dhcp-retry-late.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,16 @@ The network track owns it: netd leaves smoltcp in stage 5 of
`issues/the-loader-does-only-what-must-precede-the-handover.md`
waits on it.

netstack runs `toyos-dhcp` now (`userland/netstack/node`): an unanswered
DISCOVER is sent again on RFC 2131 §4.1's schedule, and a link that comes up
with no lease starts the exchange over
(`a_link_that_returns_with_no_lease_starts_discovery_over_at_once`,
`userland/netstack/node/tests/lease.rs`). Every reading above is of the
smoltcp client. On this one, four T14 boots of pull request #801's
measurement branches took their leases 3,419, 7,206, 8,172 and 8,397 ms after
netstack came up; netstack logs no DISCOVER and no OFFER, so what became of
the first DISCOVER of each is unread.

**Exit**: netd logs each DISCOVER it sends and each OFFER it receives, and a
T14 boot's log shows what became of the DISCOVER sent as the link came up; on
every boot of a T14 run an unanswered DISCOVER is sent again within RFC 2131
Expand Down
Loading
Loading