aboutsummaryrefslogtreecommitdiffstats
path: root/link/link-protocol.h
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-29 16:42:45 +0100
committereunhhu <[email protected]>2026-09-29 16:42:45 +0100
commita06b652768a8643fe76efdc80a0c6eb729268fc5 (patch)
treeaa425cbbd98037177035ef224045369262b9d2e3 /link/link-protocol.h
parent393804bee74311ef00e39502d7979ca00bd38cb2 (diff)
downloadpure-a06b652768a8643fe76efdc80a0c6eb729268fc5.tar.gz
pure-a06b652768a8643fe76efdc80a0c6eb729268fc5.zip
Say why a stream is refused (REFUSED), and try it again seldom
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.
Diffstat (limited to 'link/link-protocol.h')
-rw-r--r--link/link-protocol.h25
1 files changed, 20 insertions, 5 deletions
diff --git a/link/link-protocol.h b/link/link-protocol.h
index b9a3eeb..df15246 100644
--- a/link/link-protocol.h
+++ b/link/link-protocol.h
@@ -106,6 +106,11 @@
* its epoch for lost offers epoch 1 again with another)
* 0x0b LOST u64 a packet's number: a receiver knows no epoch of its run
* (sealed in epoch 0, in a run of answers of its own)
+ * 0x0c REFUSED source, input (as STREAM), u8 why (PURE_LINK_NO_INPUT and
+ * on): the receiver takes no records of that stream; its
+ * sender sends one packet of them a wait from then (a
+ * second, twice as long each time, 64 s at most) until one
+ * is stored
* 0x00 PADDING to the end of the packet: a full packet sent in a burst is
* a whole datagram
* Losses are detected as RFC 9002 says, with RACK's patience for packets
@@ -123,18 +128,23 @@
* stream not yet stored). */
enum { PURE_LINK_DATAGRAM = 1200, PURE_LINK_DATAGRAM_MOST = 1452, PURE_LINK_NAME = 64, PURE_LINK_ADDRESS = 48,
PURE_LINK_RECORD_MOST = 16 << 20 };
+/* Why a receiver refuses a stream (REFUSED): no input of that name takes
+ * messages, the input takes messages of another shape, or the sender's key
+ * may not send as that source. */
+enum { PURE_LINK_NO_INPUT = 1, PURE_LINK_OTHER_SHAPE = 2, PURE_LINK_NOT_ALLOWED = 3 };
/* Counts for a host's report: packets and records sent, records sent again,
* packets lost and acknowledged, packets received, deliveries handed over,
* the last number stored; packets called lost that came late, and
* congestion events undone for it; runs keyed (keys made from a secret),
* secrets made (X25519), epochs begun, and a sender's epochs taken for lost
- * (begun again from the nodes' keys); a receiver's senders woken (their
- * active state made), of them with a secret remembered (no X25519), let go
- * when idle, and active now. */
+ * (begun again from the nodes' keys); streams refused (a receiver's said, a
+ * sender's heard); a receiver's senders woken (their active state made), of
+ * them with a secret remembered (no X25519), let go when idle, and active
+ * now. */
typedef struct {
uint64_t packets, records, resent, lost, acknowledged, received, deliveries, stored, late, undone, keyed, secrets,
- epochs, fallbacks, woken, remembered, swept, active;
+ epochs, fallbacks, refused, woken, remembered, swept, active;
} PureLinkCounts;
/* ---- The sending side: one output's saved sends to a receiver's input, as
@@ -177,6 +187,9 @@ uint64_t pure_link_sender_due(const PureLinkSender *);
/* Probes in a row that nothing answered (0 once anything is): the path, or
* the receiver where it was, may be gone. */
unsigned pure_link_sender_probes(const PureLinkSender *);
+/* Why the receiver refuses the stream (PURE_LINK_NO_INPUT and on), or 0:
+ * cleared once it stores one of its records. */
+unsigned pure_link_sender_refusal(const PureLinkSender *);
/* How often it moves on to a new epoch (ns), and after how many bytes sent
* (an hour and a GiB at first). */
void pure_link_sender_epochs(PureLinkSender *, uint64_t every_ns, uint64_t bytes);
@@ -189,7 +202,9 @@ void pure_link_sender_free(PureLinkSender *);
/* ---- The receiving side: packets from the senders allowed (a source name
* and the key it seals with, a few bytes each however many there are: see
* pure_link_idle). A stream (a source to an input) goes to the host's input
- * its name and shape find (its number, or -1: the stream is refused). Whole
+ * its name and shape find: its number, or -PURE_LINK_OTHER_SHAPE when it
+ * takes another shape, or -1 (PURE_LINK_NO_INPUT) when none takes messages
+ * by that name; a stream refused is said to be (REFUSED). Whole
* records of a stream, in order, go to deliver as one delivery; the host
* applies them from the one after the source's last heard number, stops at
* a gap, saves, and then says so with a done (pure_link_receiver_turn).