Deliver an ordered byte stream
Send binary data, acknowledge progress, and discard duplicates and gaps.
Jump to code and terminal ↓The next number is the next byte
Five bytes beginning at sequence 101 occupy positions 101 through 105. Their cumulative ACK is 106. The sender must retain a copy until that ACK arrives. Return the number accepted by tcp_send, limited by MAX_DATA and c->mss; flow control is added in the next stages.
Own the outstanding buffer
Accept sends only in ESTABLISHED, with no active pending timer. Save pending_seq, PSH|ACK flags, bytes and length; set sent_at, rto=100, retries=0, timer_active=1. Emit at the old snd_nxt, then advance it by the byte count. Ignore ACKs other than snd_una or snd_nxt; the latter retires a pending segment. A valid in-order ACK also updates peer_window.
A gap is not a stream
In ESTABLISHED, process ACK-bearing segments without SYN/FIN/RST. Deliver payload only when seq==rcv_nxt, it fits local_window, and delivered has capacity. Copy bytes and advance rcv_nxt. Acknowledge every data segment, including old duplicates and future segments, with the current rcv_nxt. This small receiver discards out-of-order data and relies on a later retransmission.
The boundary you own
Your callbacks run as a real C program in RV64 Linux. /course/netlab.h supplies bounded Ethernet/IP/TCP encoding, checksum validation, a virtual clock, and packet capture. You own the transport state and sequence numbers. emit_tcp(c, flags, seq, ack, bytes, length) emits actual packet bytes; the browser's program trace decodes them. Test injects packets and timer events rather than inspecting source text. This is a deliberately bounded active-open, stop-and-wait TCP implementation, not a replacement for the kernel TCP stack.
snd_una: first unacknowledged byte snd_nxt: next unsent byte rcv_nxt: next peer byte expected peer_window: advertised capacity pending_seq/flags/len/pending[]: one segment awaiting ACK sent_at, rto, retries, timer_active: retransmission ownership delivered[] / delivered_len: bytes accepted by the application lab_now: deterministic clock in milliseconds
Your goal
Implement a one-segment sender and receiver: retain unacknowledged data, advance sequence numbers by bytes, and deliver peer bytes exactly once in order.
What the tests observe
- Binary send and cumulative ACK
- No overwrite of pending data
- Out-of-order and duplicate receive
- Bounded receive storage
Need a nudge?
Hint 1
The sender must copy binary data with memcpy, not strlen or strcpy. Mark the buffer outstanding before returning.
Hint 2
Accept a cumulative ACK only if it names the current snd_una or snd_nxt; future ACKs must not release the buffer.
Hint 3
Append in-order bytes to c->delivered + c->delivered_len. For a duplicate or gap, leave lengths unchanged and emit ACK with the current rcv_nxt.
What happens inside Linux
TCP delivers a stream rather than individual messages. The tests inject segment two before segment one, repeat segment one, then retransmit segment two. A correct receiver exposes onetwo once, despite that arrival order.
Optional account sync. Exercises work without an account.