mirror of
https://github.com/mfontanini/libtins
synced 2026-01-23 02:35:57 +01:00
Store MSS value on Flows
This commit is contained in:
@@ -99,7 +99,6 @@ void on_client_data(Stream& stream) {
|
||||
// Whenever there's new server data on the stream, this callback is executed.
|
||||
// This does the same thing as on_client_data
|
||||
void on_server_data(Stream& stream) {
|
||||
std::cout << "server data\n";
|
||||
string data(stream.server_payload().begin(), stream.server_payload().end());
|
||||
cout << server_endpoint(stream) << " >> "
|
||||
<< client_endpoint(stream) << ": " << endl << data << endl;
|
||||
|
||||
@@ -250,7 +250,24 @@ public:
|
||||
* followed to keep track of its state.
|
||||
*/
|
||||
void ignore_data_packets();
|
||||
|
||||
/**
|
||||
* \brief Returns the MSS for this Flow.
|
||||
*
|
||||
* If the MSS option wasn't provided by the peer, -1 is returned
|
||||
*/
|
||||
int mss() const;
|
||||
private:
|
||||
// Compress all flags into just one struct using bitfields
|
||||
struct flags {
|
||||
flags() : ignore_data_packets(0) {
|
||||
|
||||
}
|
||||
|
||||
uint32_t is_v6:1,
|
||||
ignore_data_packets:1;
|
||||
};
|
||||
|
||||
void store_payload(uint32_t seq, payload_type payload);
|
||||
buffered_payload_type::iterator erase_iterator(buffered_payload_type::iterator iter);
|
||||
void update_state(const TCP& tcp);
|
||||
@@ -263,8 +280,8 @@ private:
|
||||
data_available_callback_type on_data_callback_;
|
||||
out_of_order_callback_type on_out_of_order_callback_;
|
||||
State state_;
|
||||
bool is_v6_;
|
||||
bool ignore_data_packets_;
|
||||
int mss_;
|
||||
flags flags_;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -310,7 +327,7 @@ public:
|
||||
/**
|
||||
* \brief Constructs a TCP stream using the provided packet.
|
||||
*/
|
||||
Stream(const PDU& initial_packet);
|
||||
Stream(PDU& initial_packet);
|
||||
|
||||
/**
|
||||
* \brief Processes this packet.
|
||||
|
||||
@@ -78,18 +78,18 @@ int seq_compare(uint32_t seq1, uint32_t seq2) {
|
||||
|
||||
Flow::Flow(const IPv4Address& dest_address, uint16_t dest_port,
|
||||
uint32_t sequence_number)
|
||||
: seq_number_(sequence_number), dest_port_(dest_port), state_(UNKNOWN),
|
||||
is_v6_(false), ignore_data_packets_(false) {
|
||||
: seq_number_(sequence_number), dest_port_(dest_port), state_(UNKNOWN), mss_(-1) {
|
||||
OutputMemoryStream output(dest_address_.data(), dest_address_.size());
|
||||
output.write(dest_address);
|
||||
flags_.is_v6 = false;
|
||||
}
|
||||
|
||||
Flow::Flow(const IPv6Address& dest_address, uint16_t dest_port,
|
||||
uint32_t sequence_number)
|
||||
: seq_number_(sequence_number), dest_port_(dest_port), state_(UNKNOWN),
|
||||
is_v6_(true), ignore_data_packets_(false) {
|
||||
: seq_number_(sequence_number), dest_port_(dest_port), state_(UNKNOWN), mss_(-1) {
|
||||
OutputMemoryStream output(dest_address_.data(), dest_address_.size());
|
||||
output.write(dest_address);
|
||||
flags_.is_v6 = true;
|
||||
}
|
||||
|
||||
void Flow::data_callback(const data_available_callback_type& callback) {
|
||||
@@ -107,7 +107,7 @@ void Flow::process_packet(PDU& pdu) {
|
||||
if (tcp) {
|
||||
update_state(*tcp);
|
||||
}
|
||||
if (ignore_data_packets_) {
|
||||
if (flags_.ignore_data_packets) {
|
||||
return;
|
||||
}
|
||||
if (!tcp || !raw) {
|
||||
@@ -218,11 +218,15 @@ void Flow::update_state(const TCP& tcp) {
|
||||
else if (state_ == UNKNOWN && (tcp.flags() & TCP::SYN) != 0) {
|
||||
state_ = SYN_SENT;
|
||||
seq_number_ = tcp.seq();
|
||||
const TCP::option* mss_option = tcp.search_option(TCP::MSS);
|
||||
if (mss_option) {
|
||||
mss_ = mss_option->to<uint16_t>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool Flow::is_v6() const {
|
||||
return is_v6_;
|
||||
return flags_.is_v6;
|
||||
}
|
||||
|
||||
bool Flow::is_finished() const {
|
||||
@@ -289,19 +293,20 @@ void Flow::state(State new_state) {
|
||||
}
|
||||
|
||||
void Flow::ignore_data_packets() {
|
||||
ignore_data_packets_ = true;
|
||||
flags_.ignore_data_packets = true;
|
||||
}
|
||||
|
||||
int Flow::mss() const {
|
||||
return mss_;
|
||||
}
|
||||
|
||||
// Stream
|
||||
|
||||
Stream::Stream(const PDU& packet)
|
||||
Stream::Stream(PDU& packet)
|
||||
: client_flow_(extract_client_flow(packet)),
|
||||
server_flow_(extract_server_flow(packet)), auto_cleanup_(true) {
|
||||
const TCP& tcp = packet.rfind_pdu<TCP>();
|
||||
// If it's a SYN, set the proper state
|
||||
if (tcp.flags() == TCP::SYN) {
|
||||
client_flow().state(Flow::SYN_SENT);
|
||||
}
|
||||
// Update client flow state
|
||||
client_flow().process_packet(packet);
|
||||
const EthernetII* eth = packet.find_pdu<EthernetII>();
|
||||
if (eth) {
|
||||
client_hw_addr_ = eth->src_addr();
|
||||
|
||||
@@ -359,6 +359,26 @@ TEST_F(FlowTest, StreamFollower_ThreeWayHandshake) {
|
||||
EXPECT_EQ(61, stream.server_flow().sequence_number());
|
||||
}
|
||||
|
||||
TEST_F(FlowTest, StreamFollower_MSS) {
|
||||
using std::placeholders::_1;
|
||||
|
||||
vector<EthernetII> packets = three_way_handshake(29, 60, "1.2.3.4", 22, "4.3.2.1", 25);
|
||||
// Client's mss is 1220
|
||||
packets[0].rfind_pdu<TCP>().mss(1220);
|
||||
// Server's mss is 1460
|
||||
packets[1].rfind_pdu<TCP>().mss(1460);
|
||||
StreamFollower follower;
|
||||
follower.new_stream_callback(bind(&FlowTest::on_new_stream, this, _1));
|
||||
for (size_t i = 0; i < packets.size(); ++i) {
|
||||
follower.process_packet(packets[i]);
|
||||
}
|
||||
Stream& stream = follower.find_stream(IPv4Address("1.2.3.4"), 22,
|
||||
IPv4Address("4.3.2.1"), 25);
|
||||
EXPECT_EQ(1220, stream.client_flow().mss());
|
||||
EXPECT_EQ(1460, stream.server_flow().mss());
|
||||
}
|
||||
|
||||
|
||||
TEST_F(FlowTest, StreamFollower_RSTClosesStream) {
|
||||
using std::placeholders::_1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user