//! outbound queue of segments that the TCPConnection wants sent std::queue<TCPSegment> _segments_out{};
//! Should the TCPConnection stay active (and keep ACKing) //! for 10 * _cfg.rt_timeout milliseconds after both streams have ended, //! in case the remote TCPConnection doesn't know we've received its whole stream? bool _linger_after_streams_finish{true};
// connection active flag. bool _active{true};
// Has sent syn or not. bool _sent_syn{false};
// Time since last segment received. size_t _time_since_last_received{0};
// Grip segments from _sender, and push them to _segments_out. voidsend_segments();
// Send segment with rst flag. voidsend_rst_segment();
if (header.rst) { // set both to error state, and end connection. _sender.stream_in().set_error(); _receiver.stream_out().set_error(); _active = false; _linger_after_streams_finish = false; return; }
// Sender. // Has sent syn and is ack seg: normal ack. if (_sent_syn && header.ack) { _sender.ack_received(header.ackno, header.win); }
// Try to connect, send syn ack. if (TCPState::state_summary(_receiver) == TCPReceiverStateSummary::SYN_RECV && TCPState::state_summary(_sender) == TCPSenderStateSummary::CLOSED) { connect(); return; }
// Try to set _linger_after_streams_finish = false. // CLOSE_WAIT. if (TCPState::state_summary(_receiver) == TCPReceiverStateSummary::FIN_RECV && TCPState::state_summary(_sender) == TCPSenderStateSummary::SYN_ACKED) { _linger_after_streams_finish = false; }
// If _reciever has closed, directly close cleanly without lingering. // CLOSED. if (TCPState::state_summary(_receiver) == TCPReceiverStateSummary::FIN_RECV && TCPState::state_summary(_sender) == TCPSenderStateSummary::FIN_ACKED && _linger_after_streams_finish == false) { _active = false; return; }
// Receiver reply. // If seg is a single ack segment, don't need to re-ack. if (seg.length_in_sequence_space() != 0) { _sender.send_empty_segment(); } send_segments(); }
//! \param[in] ms_since_last_tick number of milliseconds since the last call to this method voidTCPConnection::tick(constsize_t ms_since_last_tick){ _time_since_last_received += ms_since_last_tick;
if (!_sent_syn) { return; }
// Transformsmission too many times, abort. if (_sender.consecutive_retransmissions() >= _cfg.MAX_RETX_ATTEMPTS) { send_rst_segment(); return; }