Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/tins/tcp.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class TINS_API TCP : public PDU {
SACK = 5,
TSOPT = 8,
ALTCHK = 14,
SCPS_CAPABILITIES = 20,
RFC_EXPERIMENT_1 = 253,
RFC_EXPERIMENT_2 = 254
};
Expand Down
6 changes: 4 additions & 2 deletions src/tcp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -385,8 +385,10 @@ uint32_t TCP::calculate_options_size() const {
for (options_type::const_iterator iter = options_.begin(); iter != options_.end(); ++iter) {
const option& opt = *iter;
options_size += sizeof(uint8_t);
// SACK_OK contains length but not data
if (opt.data_size() || opt.option() == SACK_OK) {
// Options 0 and 1 are exactly one octet which is their kind field.
// All other options have their one octet kind field,
// followed by a one octet length field (even if the option payload is empty)
if (opt.option() != 0 && opt.option() != 1) {
options_size += sizeof(uint8_t);
options_size += static_cast<uint16_t>(opt.data_size());
}
Expand Down
8 changes: 8 additions & 0 deletions tests/src/tcp_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,14 @@ TEST_F(TCPTest, SpoofedOptions) {
EXPECT_EQ(pdu.serialize().size(), pdu.size());
}

TEST_F(TCPTest, OptionWithEmptyPayload) {
TCP pdu;
// it has a payload, it's just empty (unlike EOL/NOP options which have no payload)
pdu.add_option(TCP::option(TCP::SCPS_CAPABILITIES, 2));
EXPECT_EQ(1U, pdu.options().size());
EXPECT_EQ(pdu.serialize().size(), pdu.size());
}

TEST_F(TCPTest, MalformedOptionAfterEOL) {
TCP tcp(malformed_option_after_eol_packet, sizeof(malformed_option_after_eol_packet));
EXPECT_EQ(0U, tcp.options().size());
Expand Down