Page
Library
Module
Module type
Parameter
Class
Class type
Source
This repository contains a TCP stack with a pure functional core. Its design is close to the HOL4 specification developed in the Netsem project - have a look at the overview paper if interested. The GitHub repository is the current development head - and the code in here uses the FreeBSD-CURRENT branch. If you find function names that are confusing, its worth to look into the NetSem specification, there may exist a rule with the same name with same behaviour.
In contrast to the basic TCP RFC 793, some features are excluded:
Very informative to read is RFC 7414 - a roadmap for TCP specification documents, and RFC 9293 TCP specification (which combines and obsoletes several RFCs).
Initially, I thought timestamp option would be a good idea, but then they mainly are privacy risks exposing a global counter (you could do a per-connection timestamp), and add 12 bytes to every segment for basically no benefit (see https://www.snellman.net/blog/archive/2017-07-20-s3-mystery/ for some discussion thereof).
In contrast to above specifications, the state transition diagram is different in this implementation. The reason is that not the full Unix sockets API is implemented, especially listening sockets are treat specially instead of being fused into the state machine: each (passive) connection starts in the SYN_RECEIVED state, there is no LISTEN state. There is also no CLOSED state - a connection which would end up in this state is directly dropped.
Features included in this implementation that have been specified in later RFCs:
The specification covers all valid executions of what is known as TCP. This is an implementation taking choices (sometimes early) and not implementing the full specification - sometimes even violating it on purpose!
A plan is to use the specification and the test harness (+packetdrill and the FreeBSD TCP testsuite) to validate that the implementation behaves according to the specification. Since the specification is at the moment specialised on FreeBSD-12, this will likely need some work. In this place, I attempt to document which bits and pieces need to be touched. For reference, all comments and line numbers are refering to git commit 2374ad26b2f4f32f62aaea62ac641c3a91b2efbc (mostly actually 409966517e3468bc677d58f46756957d4a1dddb0, because the other is rather private).
We'll likely need to define a new ARCH for this implementation in the model and then hope it's good enough ;) (or only run tests which behave similar to FreeBSD).
Model anomalies:
When to output segments?
I copied over various functions which need to be properly tested:
downside is we need to develop/adapt a syntax for packet building (and expected answers within time boundaries), and write the test cases (but then I'm not really able to find well-engineered tests with packetdrill
a matrix from testing LISTEN and CLOSED ports, tested with FreeBSD and Linux:
LISTEN CLOSED
FreeBSD Linux FreeBSD Linux
NONE - - RST+ACK(2) RST+ACK(2)
FIN - - RST+ACK(2) RST+ACK(2)
FIN+ACK(+data) RST RST RST RST
ACK(+data) RST RST RST RST
RST(+ACK)(+SYN)(+FIN)- - - -
SYN SYN+ACK SYN+ACK RST+ACK(2) RST+ACK(2)
SYN+ACK RST RST RST RST
SYN+FIN(+data)SYN+ACK(1) - RST+ACK(2) RST+ACK(2)
SYN+data SYN+ACK(1) SYN+ACK(1) RST+ACK(2) RST+ACK(2)1: only the SYN is acked, not FIN or data! 2: ACK includes data and fin
st IN {CLOSE_WAIT, LAST_ACK, CLOSING; TIME_WAIT; CLOSED}. And FIN_WAIT_1??? invariants.txt:101 says "If cantrcvmore is set, then rcvq never grows." Hypothesis: cantrcvmore <== st IN { CLOSE_WAIT; LAST_ACK; FIN_WAIT_1; FIN_WAIT_2; CLOSING; TIME_WAIT } ~cantrcvmore <== st IN { ESTABLISHED; SYN_SENT; SYN_RCVD } think we don't care in LISTEN or CLOSED. ==> if we believe this, we should remove cantrcvmore. (note that cantsndmore is different; it merely records that we intend to send a FIN (and change state) at some point in the future (not necessarily now).)