#include "tcp_receiver.hh" // Dummy implementation of a TCP receiver // For Lab 2, please replace with a real implementation that passes the // automated checks run by `make check_lab2`. template void DUMMY_CODE(Targs &&.../* unused */) {} using namespace std; void TCPReceiver::segment_received(const TCPSegment &seg) { if (seg.header().syn) { _syn = true; // there's no way to know whether connection has been established from bytestream status, // so a special member is needed _isn = seg.header().seqno; } if (!_syn) return; // abandon packets before SYN uint64_t checkpoint = stream_out().bytes_written(); uint64_t abs_seqno = unwrap(seg.header().seqno, _isn, checkpoint); // In your TCP implementation, you’ll use the index of the last reassembled byte as the checkpoint. // So, the bytes_written-1 (Stream Indices) should be this value // Watch out for the case when no bytes have been assembled if (abs_seqno == 0 && !seg.header().syn) return; // assertion: when abs_seqno is 0, this packet must be syn uint64_t index = abs_seqno - (abs_seqno ? 1 : 0); // special case for SYN&FIN _reassembler.push_substring(seg.payload().copy(), index, seg.header().fin); auto _abs_ackno = stream_out().bytes_written() + 1 + (stream_out().input_ended() ? 1 : 0); _ackno = wrap(_abs_ackno, _isn); } optional TCPReceiver::ackno() const { if (_syn) return _ackno; return {}; } size_t TCPReceiver::window_size() const { // capacity minus the number of bytes holding in the byte stream return _capacity - stream_out().buffer_size(); }