diff --git a/libsponge/tcp_sender.cc b/libsponge/tcp_sender.cc index eeff693..03c4f1a 100644 --- a/libsponge/tcp_sender.cc +++ b/libsponge/tcp_sender.cc @@ -20,9 +20,8 @@ using namespace std; TCPSender::TCPSender(const size_t capacity, const uint16_t retx_timeout, const std::optional fixed_isn) : _isn(fixed_isn.value_or(WrappingInt32{random_device()()})) , _initial_retransmission_timeout{retx_timeout} - , _stream(capacity) { - _timer.reinit(_initial_retransmission_timeout); -} + , _stream(capacity) + , _timer(retx_timeout) {} uint64_t TCPSender::bytes_in_flight() const { return _next_seqno - _unack_seqno; } @@ -50,6 +49,7 @@ void TCPSender::fill_window() { _next_seqno += seg.length_in_sequence_space(); hdr.syn = false; hdr.seqno = next_seqno(); + _timer.start(); if (sendptr >= data.size()) break; payload = data.substr(sendptr, TCPConfig::MAX_PAYLOAD_SIZE); @@ -65,8 +65,8 @@ void TCPSender::fill_window() { _segments_out.push(seg); _outstandings.push(seg); _next_seqno += seg.length_in_sequence_space(); + _timer.start(); } - _timer.start(); } //! \param ackno The remote receiver's ackno (acknowledgment number) @@ -81,7 +81,7 @@ void TCPSender::ack_received(const WrappingInt32 ackno, const uint16_t window_si if (abs_ackno >= _unack_seqno + _outstandings.front().length_in_sequence_space()) { _unack_seqno += _outstandings.front().length_in_sequence_space(); _outstandings.pop(); - _timer.reinit(_initial_retransmission_timeout); + _timer.reset_init(_initial_retransmission_timeout); } else { break; } @@ -95,18 +95,19 @@ void TCPSender::ack_received(const WrappingInt32 ackno, const uint16_t window_si //! \param[in] ms_since_last_tick the number of milliseconds since the last call to this method void TCPSender::tick(const size_t ms_since_last_tick) { - if (!_timer.started()) + if (!_timer.is_started()) return; - _timer.count_down(ms_since_last_tick); - if (!_timer.expired()) + _timer.tick(ms_since_last_tick); + if (!_timer.is_expired()) return; _segments_out.push(_outstandings.front()); if (_window_size > 0) - _timer.consec_retrans(); + _timer.retransmit(); _timer.reset(); + _timer.start(); } -unsigned int TCPSender::consecutive_retransmissions() const { return _timer.consec_retrans_count(); } +unsigned int TCPSender::consecutive_retransmissions() const { return _timer.consecutive_retransmissions(); } void TCPSender::send_empty_segment() { TCPHeader hdr; diff --git a/libsponge/tcp_sender.hh b/libsponge/tcp_sender.hh index d878aff..a4b5abf 100644 --- a/libsponge/tcp_sender.hh +++ b/libsponge/tcp_sender.hh @@ -14,36 +14,39 @@ //! God knows what this class does class TCPTimer { private: - size_t RTO{0}; - size_t rt_count{0}; - size_t ti_count{0}; - bool timer_on{false}; + size_t RTO; + size_t _cr_count{0}; + size_t _ti_count; + bool _is_started{false}; public: - TCPTimer() = default; - void reinit(uint32_t initial_RTO) { - RTO = initial_RTO; - ti_count = RTO; - rt_count = 0; - timer_on = false; + TCPTimer(uint32_t initial_retransmission_timeout) + : RTO(initial_retransmission_timeout), _ti_count(initial_retransmission_timeout) {} + void reset_init(uint32_t initial_retransmission_timeout) { + RTO = initial_retransmission_timeout; + _ti_count = RTO; + _cr_count = 0; + _is_started = false; } - void reset() { ti_count = RTO; } - size_t cur_RTO() const { return RTO; } - void start() { timer_on = true; } - bool started() const { return timer_on; } - void stop() { timer_on = false; } - bool expired() const { return ti_count == 0; } - void count_down(size_t milli_sec) { - if (ti_count >= milli_sec) - ti_count -= milli_sec; + void reset() { + _ti_count = RTO; + _is_started = false; + } + void start() { _is_started = true; } + void stop() { _is_started = false; } + void tick(size_t milli_sec) { + if (_ti_count >= milli_sec) + _ti_count -= milli_sec; else - ti_count = 0; + _ti_count = 0; } - void consec_retrans() { - rt_count++; + void retransmit() { + _cr_count++; RTO <<= 1; } - size_t consec_retrans_count() const { return rt_count; } + bool is_started() const { return _is_started; } + bool is_expired() const { return _ti_count == 0; } + size_t consecutive_retransmissions() const { return _cr_count; } }; //! \brief The "sender" part of a TCP implementation. @@ -73,7 +76,7 @@ class TCPSender { //! current window size, default (and at least) should be 1 byte according to the handout uint16_t _window_size{1}; std::queue _outstandings{}; - TCPTimer _timer{}; + TCPTimer _timer; public: //! Initialize a TCPSender