111 lines
4.4 KiB
C++
111 lines
4.4 KiB
C++
#include "tcp_state.hh"
|
|
|
|
using namespace std;
|
|
|
|
bool TCPState::operator==(const TCPState &other) const {
|
|
return _active == other._active and _linger_after_streams_finish == other._linger_after_streams_finish and
|
|
_sender == other._sender and _receiver == other._receiver;
|
|
}
|
|
|
|
bool TCPState::operator!=(const TCPState &other) const { return not operator==(other); }
|
|
|
|
string TCPState::name() const {
|
|
return "sender=`" + _sender + "`, receiver=`" + _receiver + "`, active=" + to_string(_active) +
|
|
", linger_after_streams_finish=" + to_string(_linger_after_streams_finish);
|
|
}
|
|
|
|
TCPState::TCPState(const TCPState::State state) {
|
|
switch (state) {
|
|
case TCPState::State::LISTEN:
|
|
_receiver = TCPReceiverStateSummary::LISTEN;
|
|
_sender = TCPSenderStateSummary::CLOSED;
|
|
break;
|
|
case TCPState::State::SYN_RCVD:
|
|
_receiver = TCPReceiverStateSummary::SYN_RECV;
|
|
_sender = TCPSenderStateSummary::SYN_SENT;
|
|
break;
|
|
case TCPState::State::SYN_SENT:
|
|
_receiver = TCPReceiverStateSummary::LISTEN;
|
|
_sender = TCPSenderStateSummary::SYN_SENT;
|
|
break;
|
|
case TCPState::State::ESTABLISHED:
|
|
_receiver = TCPReceiverStateSummary::SYN_RECV;
|
|
_sender = TCPSenderStateSummary::SYN_ACKED;
|
|
break;
|
|
case TCPState::State::CLOSE_WAIT:
|
|
_receiver = TCPReceiverStateSummary::FIN_RECV;
|
|
_sender = TCPSenderStateSummary::SYN_ACKED;
|
|
_linger_after_streams_finish = false;
|
|
break;
|
|
case TCPState::State::LAST_ACK:
|
|
_receiver = TCPReceiverStateSummary::FIN_RECV;
|
|
_sender = TCPSenderStateSummary::FIN_SENT;
|
|
_linger_after_streams_finish = false;
|
|
break;
|
|
case TCPState::State::CLOSING:
|
|
_receiver = TCPReceiverStateSummary::FIN_RECV;
|
|
_sender = TCPSenderStateSummary::FIN_SENT;
|
|
break;
|
|
case TCPState::State::FIN_WAIT_1:
|
|
_receiver = TCPReceiverStateSummary::SYN_RECV;
|
|
_sender = TCPSenderStateSummary::FIN_SENT;
|
|
break;
|
|
case TCPState::State::FIN_WAIT_2:
|
|
_receiver = TCPReceiverStateSummary::SYN_RECV;
|
|
_sender = TCPSenderStateSummary::FIN_ACKED;
|
|
break;
|
|
case TCPState::State::TIME_WAIT:
|
|
_receiver = TCPReceiverStateSummary::FIN_RECV;
|
|
_sender = TCPSenderStateSummary::FIN_ACKED;
|
|
break;
|
|
case TCPState::State::RESET:
|
|
_receiver = TCPReceiverStateSummary::ERROR;
|
|
_sender = TCPSenderStateSummary::ERROR;
|
|
_linger_after_streams_finish = false;
|
|
_active = false;
|
|
break;
|
|
case TCPState::State::CLOSED:
|
|
_receiver = TCPReceiverStateSummary::FIN_RECV;
|
|
_sender = TCPSenderStateSummary::FIN_ACKED;
|
|
_linger_after_streams_finish = false;
|
|
_active = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
TCPState::TCPState(const TCPSender &sender, const TCPReceiver &receiver, const bool active, const bool linger)
|
|
: _sender(state_summary(sender))
|
|
, _receiver(state_summary(receiver))
|
|
, _active(active)
|
|
, _linger_after_streams_finish(active ? linger : false) {}
|
|
|
|
string TCPState::state_summary(const TCPReceiver &receiver) {
|
|
if (receiver.stream_out().error()) {
|
|
return TCPReceiverStateSummary::ERROR;
|
|
} else if (not receiver.ackno().has_value()) {
|
|
return TCPReceiverStateSummary::LISTEN;
|
|
} else if (receiver.stream_out().input_ended()) {
|
|
return TCPReceiverStateSummary::FIN_RECV;
|
|
} else {
|
|
return TCPReceiverStateSummary::SYN_RECV;
|
|
}
|
|
}
|
|
|
|
string TCPState::state_summary(const TCPSender &sender) {
|
|
if (sender.stream_in().error()) {
|
|
return TCPSenderStateSummary::ERROR;
|
|
} else if (sender.next_seqno_absolute() == 0) {
|
|
return TCPSenderStateSummary::CLOSED;
|
|
} else if (sender.next_seqno_absolute() == sender.bytes_in_flight()) {
|
|
return TCPSenderStateSummary::SYN_SENT;
|
|
} else if (not sender.stream_in().eof()) {
|
|
return TCPSenderStateSummary::SYN_ACKED;
|
|
} else if (sender.next_seqno_absolute() < sender.stream_in().bytes_written() + 2) {
|
|
return TCPSenderStateSummary::SYN_ACKED;
|
|
} else if (sender.bytes_in_flight()) {
|
|
return TCPSenderStateSummary::FIN_SENT;
|
|
} else {
|
|
return TCPSenderStateSummary::FIN_ACKED;
|
|
}
|
|
}
|