* Implement send buffer
* Window scaling
* Handle retransmission
+ - Proper timeout handling
TODO v2.0:
Does this need special care or can we rely on higher level MACs?
+RFCs
+----
+
+793 Transmission Control Protocol (Functional Specification)
+2581 TCP Congestion Control
+2988 Computing TCP's Retransmission Timer
+
+
+
INVARIANTS
----------
- SYN and FIN each count as one byte for the sequence numbering, but no actual byte is transferred in the payload.
+CONNECTION TIMEOUT
+------------------
+
+This timer is intended to catch the case when we are waiting very long for a response but nothing happens.
+The timeout is in the order of minutes.
+
+- The conn timeout is set whenever there is unacknowledged data, or when we are in the TIME_WAIT status.
+- If snd.una is advanced while the timeout is set, we re-set the timeout.
+- If the conn timeout expires, close the connection immediately.
+
+RETRANSMIT TIMEOUT
+------------------
+
+(See RFC 2988, 3366)
+
+This timer is intended to catch the case where we didn't get an ACK from the peer.
+In principle, the timeout should be slightly longer than the maximum latency along the path.
+
+
+- The rtrx timeout is set whenever snd.nxt is advanced.
+- If the rtrx timeout expires, retransmit at least one packet, and re-set the timeout.
+
STATES
------
-CLOSED: this connection is cloed, all packets received will result in RST.
+CLOSED: this connection is closed, all packets received will result in RST.
+ RX: RST
+ TX: return error
+ RT: clear timers
+ RST: ignore
LISTEN: (= no connection yet): only allow SYN packets, it application does not accept, return RST|ACK, else SYN|ACK.
+ RX: on accept, send SYNACK, go to SYN_RECEIVED
+ TX: cannot happen
+ RT: cannot happen
+ RST: ignore
SYN_SENT: we sent a SYN, now expecting SYN|ACK
+ RX: must be valid SYNACK, send ACK, go to ESTABLISHED
+ TX: put in send buffer (TODO: send SYN again with data?)
+ RT: send SYN again
SYN_RECEIVED: we received a SYN, sent back a SYN|ACK, now expecting an ACK
+ RX: must be valid ACK, go to ESTABLISHED
+ TX: put in send buffer (TODO: send SYNACK again with data?)
+ RT: send SYNACK again
ESTABLISHED: SYN is acked, we can now send/receive normal data.
+ RX: process data, return ACK. If FIN set, go to CLOSE_WAIT
+ TX: put in send buffer, segmentize and send
+ RT: send unACKed data again
FIN_WAIT_1: we want to close the connection, and just sent a FIN, waiting for it to be ACKed.
+ RX: process data, return ACK. If our FIN is acked, go to FIN_WAIT_2, if a FIN was also received, go to CLOSING
+ TX: return error
+ RT: send unACKed data or else FIN again
-FIN_WAIT_2: FIXME
+FIN_WAIT_2: our FIN is ACKed, just waiting for more data or FIN from the peer.
+ RX: process data, return ACK. If a FIN was also received, go to CLOSING
+ TX: return error
+ RT: should not happen, clear timeouts
CLOSE_WAIT: we received a FIN, we sent back an ACK
+ RX: only return an ACK.
+ TX: put in send buffer, segmentize and send
+ RT: send unACKed data again
CLOSING: we had already sent a FIN, and we received a FIN back, now waiting for it to be ACKed.
+ RX: if it's ACKed, set conn timeout, go to TIME_WAIT
+ TX: return an error
+ RT: send unACKed data or else FIN again
LAST_ACK: we are waiting for the last ACK before we can CLOSE
+ RX: if it's ACKed, go to CLOSED
+ TX: return an error
+ RT: send FIN again
TIME_WAIT: connection is in princple closed, but our last ACK might not have been received, so just wait a while to see if a FIN gets retransmitted so we can resend the ACK.
+ RX: if we receive anything, reset conn timeout.
+ TX: return an error
+ RT: should not happen, clear rtrx timeout
SEND PACKET
-----------
- Drop invalid packets:
- Invalid flags or state
+ - ACK always set
- hdr.seq not within our receive window
- hdr.ack ahead of snd.nxt
- Handle RST packets