70 lines
2.4 KiB
C++
70 lines
2.4 KiB
C++
#ifndef SPONGE_LIBSPONGE_TCP_RECEIVER_HH
|
|
#define SPONGE_LIBSPONGE_TCP_RECEIVER_HH
|
|
|
|
#include "byte_stream.hh"
|
|
#include "stream_reassembler.hh"
|
|
#include "tcp_segment.hh"
|
|
#include "wrapping_integers.hh"
|
|
|
|
#include <optional>
|
|
|
|
//! \brief The "receiver" part of a TCP implementation.
|
|
|
|
//! Receives and reassembles segments into a ByteStream, and computes
|
|
//! the acknowledgment number and window size to advertise back to the
|
|
//! remote TCPSender.
|
|
class TCPReceiver {
|
|
//! Our data structure for re-assembling bytes.
|
|
StreamReassembler _reassembler;
|
|
|
|
//! The maximum number of bytes we'll store.
|
|
size_t _capacity;
|
|
WrappingInt32 _isn{0};
|
|
WrappingInt32 _ackno{0};
|
|
bool _syn{};
|
|
|
|
public:
|
|
//! \brief Construct a TCP receiver
|
|
//!
|
|
//! \param capacity the maximum number of bytes that the receiver will
|
|
//! store in its buffers at any give time.
|
|
TCPReceiver(const size_t capacity) : _reassembler(capacity), _capacity(capacity) {}
|
|
|
|
//! \name Accessors to provide feedback to the remote TCPSender
|
|
//!@{
|
|
|
|
//! \brief The ackno that should be sent to the peer
|
|
//! \returns empty if no SYN has been received
|
|
//!
|
|
//! This is the beginning of the receiver's window, or in other words, the sequence number
|
|
//! of the first byte in the stream that the receiver hasn't received.
|
|
std::optional<WrappingInt32> ackno() const;
|
|
|
|
//! \brief The window size that should be sent to the peer
|
|
//!
|
|
//! Operationally: the capacity minus the number of bytes that the
|
|
//! TCPReceiver is holding in its byte stream (those that have been
|
|
//! reassembled, but not consumed).
|
|
//!
|
|
//! Formally: the difference between (a) the sequence number of
|
|
//! the first byte that falls after the window (and will not be
|
|
//! accepted by the receiver) and (b) the sequence number of the
|
|
//! beginning of the window (the ackno).
|
|
size_t window_size() const;
|
|
//!@}
|
|
|
|
//! \brief number of bytes stored but not yet reassembled
|
|
size_t unassembled_bytes() const { return _reassembler.unassembled_bytes(); }
|
|
|
|
//! \brief handle an inbound segment
|
|
void segment_received(const TCPSegment &seg);
|
|
|
|
//! \name "Output" interface for the reader
|
|
//!@{
|
|
ByteStream &stream_out() { return _reassembler.stream_out(); }
|
|
const ByteStream &stream_out() const { return _reassembler.stream_out(); }
|
|
//!@}
|
|
};
|
|
|
|
#endif // SPONGE_LIBSPONGE_TCP_RECEIVER_HH
|