aboutsummaryrefslogtreecommitdiffstats
path: root/link/link.c
Commit message (Collapse)AuthorAgeFilesLines
* Say why a stream is refused (REFUSED), and try it again seldomeunhhu2026-09-291-3/+13
| | | | | | | | | | | | | | | | | | | A receiver that took no records of a stream (a source the key may not send as, no input of that name, an input of another shape) said nothing: its sender heard them acknowledged, never stored, and sent them all again every second, for ever, and its operator saw nothing. Now the receiver answers REFUSED (0x0c: the names, and why), and the sender sends no records for a second, then a packet of them to learn whether they are taken now, the wait twice as long each time (64 s at most). A refusal ends when that packet is acknowledged with no REFUSED beside, or a record is stored. link.c says it once on stderr, as a wire says a receiver does not take its sends; serve's input says which of the two the app lacks. test-link: each of the three is refused seven times in 90 s with nine packets, and a stream refused until the app has its input goes on then, all 200 records stored. check.py links a node to an input its receiver lacks: said once, two packets in 2.5 s.
* Look for a link's receiver at once when the system says it cannot get thereeunhhu2026-09-291-3/+16
| | | | | | | | | | A send that fails with no route, nobody at the port, or the network gone (ECONNREFUSED, EHOSTUNREACH, ENETUNREACH, ENETDOWN, EADDRNOTAVAIL) now has the link look its receiver's name up again before its next packet, not three unanswered probes later: a receiver moved away from an address that is gone costs a sender one probe's wait, not three. Such a failure no longer turns GSO off either (it said nothing of GSO). In the check that moves a receiver, the sender sent 24 records again, not 243.
* Look for a link's receiver again when its probes go unansweredeunhhu2026-09-291-26/+52
| | | | | | | | | | | | | | | | | | | A link resolved its receiver's name once, at its start: a receiver whose store moved to another machine (another address under the same name) was never found, and a sender whose own network changed kept a socket that no longer went anywhere. Now, when three probes in a row go unanswered, and at each probe after (a second apart at most), the link looks the name up again and sends from a new socket connected there. It looks before the probe goes, so the probe's answer comes to the new socket (looking after it lost every answer, one socket after another). A sender at rest does not look: only probes unanswered count. make check moves a receiver (H3 of docs/design/011-pure-transport.md): in namespaces of its own, the sender links to pure://receiver.test at 127.0.0.2; the receiver is killed, its store, key and memo copied, the old address made unreachable, the name pointed at 127.0.0.3 and the copy started there. Every order is applied once, and the moved receiver makes no X25519.
* Answer a link's packet from the address it came toeunhhu2026-09-291-14/+59
| | | | | | | | | | | | | | The listener's socket takes packets to any address of the node, and its answers went out from whichever address the system chose for the way back. A sender whose socket is connected to another of the node's addresses (a node with many, or a name that points at a second one) takes answers only from the address it sent to: it heard none, and its records went on arriving unacknowledged. Now the listener asks for the address each packet came to (IP_PKTINFO; IPv4 as ::ffff:a.b.c.d on a socket of both) and answers from it. The path a receiver keeps for a run is both addresses (48 bytes, not 28): a packet that comes to another of the node's addresses moves it, and is checked, as one from elsewhere is. Found by a receiver moved to 127.0.0.2 (the check that follows).
* Find how large a packet the path carries: 1,452 bytes once a probe is ↵eunhhu2026-09-291-13/+50
| | | | | | | | | | | | | | | acknowledged A link starts at 1,200 bytes; once an RTT is known it sends a PING padded to 1,452 (DPLPMTUD, RFC 8899), alone and with the don't-fragment bit, and uses that size once it is acknowledged. A probe lost is no congestion; it is tried again a second on, three times, then ten minutes on. GSO is asked for each burst (a control message), not the socket, so a packet sent alone is never cut. CUBIC counts in the datagram. On loopback packets fall by 19-27%; the CPU a record falls 13% at 1 KiB and 7% at 16 KiB; in the simulator of a 50 Mbit/s path with 1% loss the goodput rises from 6.1 to 7.0 Mbit/s (5%: 2.3 to 3.0).
* Measure a link on a path of loss, reordering and a bottleneck (M6 harness)eunhhu2026-09-291-2/+4
| | | | | | | | | 020-lossy-paths/run.py runs each case in an unprivileged namespace: a 50 Mbit/s tbf bottleneck under netem's delay, jitter and loss, both ways. A link may send without UDP GSO (pure_link_gso), as netem takes a burst as one packet; quinn the same (QUIC_GSO=0). transport.c and the quinn harness give the records handed over in each 100 ms, and at a steady rate the time each took; TCP CUBIC flows run beside them.
* Keep a link's two sides as state alone, the sockets and threads aparteunhhu2026-09-291-1446/+68
| | | | | | | | | | | | link/link-protocol.h is the protocol with no socket, thread or clock of its own: packets and time in, packets out. link/link.h carries it over UDP as before. A sender starts small (8 flights, 16 records, a 4 KiB ring) so one thread can hold many. The transport's CPU a record is the same within 2% (five rounds each way, 61 B to 16 KiB). test-link runs both sides through a network of its own: loss, packets held back and doubled, failed saves, an idle sweep, and both sides starting again, every record applied once as sent.
* Let links know nothing of the core: the host names inputs and shapeseunhhu2026-09-291-70/+40
| | | | | | A sender takes its messages' shape, and a listener asks its host which input a stream goes to. The core gives the shape (pure_module_shape); link/ now builds without the core's headers.
* Put the links and the crypto they use in link/, a part of their owneunhhu2026-09-291-0/+1862
libpure-link.a holds them; pure-serve and the M5 harness link it instead of naming its source files.