What the datagram sequence does between two real ND machines¶
Full path: E:\Dev\Ronny\NDInsight\SINTRAN\XMSG\DOC\captures\TRIO-SEQUENCE-2026-08-11\FINDINGS.md
Measured 2026-08-11. Three real SINTRAN machines were brought up (D100, D102, D103) and several file listings were run back to back with nothing restarted between them - which is the only way to see what a counter does across conversations.
Capture: trio.pcapng, 38410 frames, 2410 SINTRAN datagrams.
Reproduce: python seqtrace.py trio.pcapng
1. Flags 1 is PER SENDER. Counted, not eyeballed.¶
| Data frames D100 sent | 602 |
| Data frames D102 sent | 602 |
| Distinct Flags 1 values used | 602 (0x0000 .. 0x0259) |
| Total data frames on the wire | 1204 |
If the two machines shared one counter, 1204 frames would have consumed about 1204 values. They consumed 602. So each machine ran its own counter 0..601 and sent exactly one frame per value.
They look shared and are not. The exchange is perfectly symmetric - one data frame each per exchange - so the two counters stay level for the whole capture:
100 -> 102 Data 0000 102 -> 100 Ack 0000
102 -> 100 Data 0000 100 -> 102 Ack 0000
100 -> 102 Data 0001 102 -> 100 Ack 0001
102 -> 100 Data 0001 100 -> 102 Ack 0001
Reading that ladder alone, "one shared counter that steps per exchange" fits every line. The
frame COUNT is what separates the two models, and it is the check
xmsg-flags1-is-per-sender-not-shared asked for. That memory is CONFIRMED, not overturned.
An acknowledgement carries the number of the data frame it answers, so acks say nothing about the sender's own counter and are excluded from the count above.
2. Nothing resets it across conversations¶
Three separate LIST-FILES conversations ran in this capture. The counter climbed straight
through all of them:
| event | Flags 1 |
|---|---|
| link comes up, reachability exchange | FFFF both ways |
| first datagram after it | 0000 |
| end of conversation 1 | 0091 |
| end of conversation 2 | 0123 |
| end of conversation 3 | 01C7 |
| end of capture | 0259 |
No restart, no wrap, no gap. A conversation ending does not reset anything. The number is a property of the LINK, not of the conversation.
3. It starts at zero only after a reachability exchange¶
The whole capture contains exactly two FFFF frames, both at the very start:
100 -> 102 ReachReq FFFF
102 -> 100 ReachReply FFFF
100 -> 102 Data 0000 <- counting starts here
FFFF is the "I am not claiming a sequence" form. The kernel carve agrees: the send path at
ram:b3d6 picks between XMSEQ = 0xFFFF and XMSEQ = XNSEQ | 0x8000 on a flag, and XNSEQ
has exactly one writer - an increment - and no reset anywhere in the image. So zeroing is not
something a message does; it is what a fresh link block starts as.
4. The only anomalies are the four teardown rejects¶
seqtrace.py flags every place a sender's number fails to step by +1. In 2410 datagrams there
are four, all identical in shape:
0091 FFED 0123 FFED 01C7 FFED 0259 FFED
One per conversation teardown - a subtype-07 network error carrying 0xFFED = XEIMA. Already
established as NORMAL (see FaServerConversation.BuildClose): a real server's close gets the
same reject from a real client. They repeat the previous number rather than advancing because
an error frame answers the frame that offended it.
What this means for D19999¶
Our node's problem was never the file-access protocol. D100 keeps a per-sender expectation for
each peer, it starts at zero only when the link block is created, and nothing in normal
traffic ever puts it back. When our runner restarts and opens at 0x0000, D100 is still
counting from wherever the previous run left it, and refuses us - silently, or with XENSE once
we announce.
So there are only two honest ways forward, and this capture rules the middle ground out:
- Persist our counter across restarts, which is exactly what
xmsg-sequence.stateis for. Deleting it - which the old live-test protocol says to do after an XMSG restart - is right ONLY when the peer really did reset. On Ethernet it does not, so deleting the file is what puts us out of step. - Make the link block be created again, which is what a reachability exchange accompanies.
Sending
FFFFalone did not do it (measured), so what triggers the rebuild is still open.
5. ANSWERED: the counter is PER PEER as well as per sender¶
threeway.pcapng - D100 listing D19999 and then D102, in one session, nothing restarted.
D100 ran two separate counters at the same time:
| D100 -> peer | first | last | data frames | check |
|---|---|---|---|---|
| D102 | 0x0410 |
0x04A1 |
146 | 145 steps + 1 = 146 |
| D19999 | 0x000E |
0x0025 |
24 | 23 steps + 1 = 24 |
Both runs are exact and they are nowhere near each other. If the counter belonged to the
MACHINE, the run toward D19999 would have carried on from 0x04A1, not started near zero.
So: one counter per (sender, peer) pair, and it survives everything short of the peer block being rebuilt.
The 0x0410 also continues exactly from allpairs.pcapng, which ended at 0x040F - across a
separate capture, a twenty-minute gap, six conversations and a live DEF-NETWORK-CONN. Three
captures in a row, one unbroken run:
trio.pcapng 0x0000 .. 0x0259 (602 frames)
allpairs.pcapng 0x025A .. 0x040F (438 frames)
threeway.pcapng 0x0410 .. 0x04A1 (146 frames)
6. Confirmed on a THIRD machine and a SECOND transport¶
D103 was brought into the trio over HDLC through our relay
(--relay-listen 10366 --relay-inbound-node 103) and listed D19999's files.
hdlc-trio.pcapng:
19999 -> 103 FFFF reachability
103 -> 19999 FFFF
103 -> 19999 0x0000 .. 0x0017 its own run, from zero
19999 -> 103 0x0000 .. 0x0017 ours, from zero
Same law on a different wire: a reachability exchange at link bring-up, then each side counting its own run from zero. D103's counter toward D19999 started at zero while D19999 was already mid-run toward D100 - a third independent (sender, peer) counter, and on HDLC rather than Ethernet. So the rule is not an artefact of the Ethernet path.
Why D103 could not use the segment - it has no ENNS0¶
Two separate faults, found in order:
- Its XMSG kernel table area was never initialised.
LIST-SYSTEMSin X-C printedXMSG kernel table area initialised.- it created the tables at that moment. EveryDEF-REMOTEfrom the earlier bring-up had landed on a table that did not exist and did nothing, which is why XROUT answered "Unknown name (of server or system)". Afterwards all sixDEF-REMOTEreturnedOk. - ENNS0 is not installed on D103 at all.
LIST-RT-DESCRIPTION ENNS0returnsILLEGAL PARAMETER, where the same command on D100 returns a real descriptor (PASSIVE, segment101B, start address32241B). SoSTART-NET-SERVER,ENNS0and everyDEF-NETWORK-CONNfail with "Error in communicating with XROUT" - there is no Ethernet network server to communicate with.
An earlier draft of this document said D100 was "presumably routing D103 over HDLC". That was wrong and is withdrawn: D100 was not routing it anywhere. D103 has no Ethernet software.
The HDLC path needed START-LINK,1360,,,-1,, on BOTH ends. The bring-up script starts LU 1362
by default; LU 1360 is the one on controller 1, which is the port the relay uses.
START-LINK,1360 on its own is refused - the command prompts for a timeout, so the whole
parameter list is required.
Also unexplained: the third D100 -> D102 listing returned one file where the first two
returned 67, with no error. Same command, same pair, nothing restarted. Worth its own run.