TcpOptions Deserialize should return zero if a deserialization error happens
This commit is contained in:
@@ -377,8 +377,12 @@ TcpHeader::Deserialize (Buffer::Iterator start)
|
||||
uint8_t kind = i.PeekU8 ();
|
||||
Ptr<TcpOption> op = TcpOption::CreateOption (kind);
|
||||
|
||||
optionLen -= op->Deserialize (i);
|
||||
i.Next (op->GetSerializedSize ());
|
||||
uint32_t optionSize;
|
||||
optionSize = op->Deserialize (i);
|
||||
|
||||
NS_ASSERT_MSG (optionSize, "Unable to Deserialize an Option of Kind " << int (kind) << ", sorry.");
|
||||
optionLen -= optionSize;
|
||||
i.Next (optionSize);
|
||||
|
||||
if (op->GetKind () != TcpOption::END)
|
||||
{
|
||||
|
||||
@@ -83,7 +83,7 @@ TcpOptionEnd::Deserialize (Buffer::Iterator start)
|
||||
if (readKind != GetKind ())
|
||||
{
|
||||
NS_LOG_WARN ("Malformed END option");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GetSerializedSize ();
|
||||
@@ -153,7 +153,7 @@ TcpOptionNOP::Deserialize (Buffer::Iterator start)
|
||||
if (readKind != GetKind ())
|
||||
{
|
||||
NS_LOG_WARN ("Malformed NOP option");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GetSerializedSize ();
|
||||
@@ -225,7 +225,7 @@ TcpOptionMSS::Deserialize (Buffer::Iterator start)
|
||||
if (readKind != GetKind ())
|
||||
{
|
||||
NS_LOG_WARN ("Malformed MSS option");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t size = i.ReadU8 ();
|
||||
@@ -261,6 +261,8 @@ NS_OBJECT_ENSURE_REGISTERED (TcpOptionUnknown);
|
||||
TcpOptionUnknown::TcpOptionUnknown ()
|
||||
: TcpOption ()
|
||||
{
|
||||
m_kind = 0xFF;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
TcpOptionUnknown::~TcpOptionUnknown ()
|
||||
@@ -292,15 +294,21 @@ TcpOptionUnknown::Print (std::ostream &os) const
|
||||
uint32_t
|
||||
TcpOptionUnknown::GetSerializedSize (void) const
|
||||
{
|
||||
return 0;
|
||||
return m_size;
|
||||
}
|
||||
|
||||
void
|
||||
TcpOptionUnknown::Serialize (Buffer::Iterator start) const
|
||||
TcpOptionUnknown::Serialize (Buffer::Iterator i) const
|
||||
{
|
||||
NS_LOG_WARN ("Can't Serialize an Unknown Tcp Option");
|
||||
if (m_size == 0)
|
||||
{
|
||||
NS_LOG_WARN ("Can't Serialize an Unknown Tcp Option");
|
||||
return;
|
||||
}
|
||||
|
||||
(void) start;
|
||||
i.WriteU8 (GetKind ());
|
||||
i.WriteU8 (GetSerializedSize ());
|
||||
i.Write (m_content, m_size-2);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
@@ -308,28 +316,21 @@ TcpOptionUnknown::Deserialize (Buffer::Iterator start)
|
||||
{
|
||||
Buffer::Iterator i = start;
|
||||
|
||||
uint8_t readKind = i.ReadU8 ();
|
||||
NS_LOG_WARN ("Trying to Deserialize an Unknown Option of Kind=" << readKind);
|
||||
m_kind = i.ReadU8 ();
|
||||
NS_LOG_WARN ("Trying to Deserialize an Unknown Option of Kind " << int (m_kind));
|
||||
|
||||
uint8_t size = i.ReadU8 ();
|
||||
m_size = i.ReadU8 ();
|
||||
NS_ASSERT_MSG ((m_size >= 2) && (m_size < 40), "Unable to parse an Unknown Option of Kind " << int (m_kind) << " with apparent size " << int (m_size));
|
||||
|
||||
if (size < 2)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
i.Read (m_content, m_size-2);
|
||||
|
||||
for (uint8_t j = 2; j < size; ++j)
|
||||
{
|
||||
i.ReadU8 ();
|
||||
}
|
||||
|
||||
return static_cast<uint32_t> (size);
|
||||
return m_size;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
TcpOptionUnknown::GetKind (void) const
|
||||
{
|
||||
return 100;
|
||||
return m_kind;
|
||||
}
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* Defines the TCP option of kind 0 (end of option list) as in RFC793
|
||||
* Defines the TCP option of kind 0 (end of option list) as in \RFC{793}
|
||||
*/
|
||||
class TcpOptionEnd : public TcpOption
|
||||
{
|
||||
@@ -33,6 +33,10 @@ public:
|
||||
TcpOptionEnd ();
|
||||
virtual ~TcpOptionEnd ();
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
@@ -46,7 +50,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the TCP option of kind 1 (no operation) as in RFC793
|
||||
* Defines the TCP option of kind 1 (no operation) as in \RFC{793}
|
||||
*/
|
||||
class TcpOptionNOP : public TcpOption
|
||||
{
|
||||
@@ -54,6 +58,10 @@ public:
|
||||
TcpOptionNOP ();
|
||||
virtual ~TcpOptionNOP ();
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
@@ -66,7 +74,7 @@ public:
|
||||
};
|
||||
|
||||
/**
|
||||
* Defines the TCP option of kind 2 (maximum segment size) as in RFC793
|
||||
* Defines the TCP option of kind 2 (maximum segment size) as in \RFC{793}
|
||||
*/
|
||||
class TcpOptionMSS : public TcpOption
|
||||
{
|
||||
@@ -74,6 +82,10 @@ public:
|
||||
TcpOptionMSS ();
|
||||
virtual ~TcpOptionMSS ();
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
@@ -84,14 +96,26 @@ public:
|
||||
virtual uint8_t GetKind (void) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
/**
|
||||
* \brief Get the Maximum Segment Size stored in the Option
|
||||
* \return The Maximum Segment Size
|
||||
*/
|
||||
uint16_t GetMSS (void) const;
|
||||
/**
|
||||
* \brief Set the Maximum Segment Size stored in the Option
|
||||
* \param mss The Maximum Segment Size
|
||||
*/
|
||||
void SetMSS (uint16_t mss);
|
||||
|
||||
protected:
|
||||
uint16_t m_mss; // maximum segment size
|
||||
uint16_t m_mss; //!< maximum segment size
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief An unknown tcp option
|
||||
* \brief An unknown TCP option.
|
||||
*
|
||||
* An unknown option can be deserialized and (only if deserialized previously)
|
||||
* serialized again.
|
||||
*/
|
||||
class TcpOptionUnknown : public TcpOption
|
||||
{
|
||||
@@ -99,6 +123,10 @@ public:
|
||||
TcpOptionUnknown ();
|
||||
virtual ~TcpOptionUnknown ();
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
@@ -108,6 +136,12 @@ public:
|
||||
|
||||
virtual uint8_t GetKind (void) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
private:
|
||||
uint8_t m_kind; //!< The unknown option kind
|
||||
uint32_t m_size; //!< The unknown option size
|
||||
uint8_t m_content[40]; //!< The option data
|
||||
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -84,7 +84,7 @@ TcpOptionTS::Deserialize (Buffer::Iterator start)
|
||||
if (readKind != GetKind ())
|
||||
{
|
||||
NS_LOG_WARN ("Malformed Timestamp option");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t size = i.ReadU8 ();
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* Defines the TCP option of kind 8 (timestamp option) as in RFC1323
|
||||
* Defines the TCP option of kind 8 (timestamp option) as in \RFC{1323}
|
||||
*/
|
||||
|
||||
class TcpOptionTS : public TcpOption
|
||||
@@ -36,6 +36,10 @@ public:
|
||||
TcpOptionTS ();
|
||||
virtual ~TcpOptionTS ();
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
@@ -46,9 +50,25 @@ public:
|
||||
virtual uint8_t GetKind (void) const;
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
/**
|
||||
* \brief Get the timestamp stored in the Option
|
||||
* \return the timestamp
|
||||
*/
|
||||
uint32_t GetTimestamp (void) const;
|
||||
/**
|
||||
* \brief Get the timestamp echo stored in the Option
|
||||
* \return the timestamp echo
|
||||
*/
|
||||
uint32_t GetEcho (void) const;
|
||||
/**
|
||||
* \brief Set the timestamp stored in the Option
|
||||
* \param ts the timestamp
|
||||
*/
|
||||
void SetTimestamp (uint32_t ts);
|
||||
/**
|
||||
* \brief Set the timestamp echo stored in the Option
|
||||
* \param ts the timestamp echo
|
||||
*/
|
||||
void SetEcho (uint32_t ts);
|
||||
|
||||
/**
|
||||
@@ -79,8 +99,8 @@ public:
|
||||
static Time ElapsedTimeFromTsValue (uint32_t echoTime);
|
||||
|
||||
protected:
|
||||
uint32_t m_timestamp; // local timestamp
|
||||
uint32_t m_echo; // echo timestamp
|
||||
uint32_t m_timestamp; //!< local timestamp
|
||||
uint32_t m_echo; //!< echo timestamp
|
||||
};
|
||||
|
||||
} // namespace ns3
|
||||
|
||||
@@ -83,7 +83,7 @@ TcpOptionWinScale::Deserialize (Buffer::Iterator start)
|
||||
if (readKind != GetKind ())
|
||||
{
|
||||
NS_LOG_WARN ("Malformed Window Scale option");
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
uint8_t size = i.ReadU8 ();
|
||||
NS_ASSERT (size == 3);
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
namespace ns3 {
|
||||
|
||||
/**
|
||||
* \brief Defines the TCP option of kind 3 (window scale option) as in RFC1323
|
||||
* \brief Defines the TCP option of kind 3 (window scale option) as in \RFC{1323}
|
||||
*
|
||||
* For more efficient use of high bandwidth networks, a larger TCP window size
|
||||
* may be used. The TCP window size field controls the flow of data and its
|
||||
* value is limited to between 2 and 65,535 bytes.
|
||||
*
|
||||
* Since the size field cannot be expanded, a scaling factor is used.
|
||||
* The TCP window scale option, as defined in RFC 1323, is an option used
|
||||
* The TCP window scale option, as defined in \RFC{1323}, is an option used
|
||||
* to increase the maximum window size from 65,535 bytes to 1 gigabyte.
|
||||
* Scaling up to larger window sizes is a part of what is necessary for TCP Tuning.
|
||||
*
|
||||
@@ -48,61 +48,21 @@ namespace ns3 {
|
||||
class TcpOptionWinScale : public TcpOption
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
/**
|
||||
* \brief Create the option
|
||||
*
|
||||
* The scale is initialized with a 0U value.
|
||||
*/
|
||||
TcpOptionWinScale ();
|
||||
|
||||
/**
|
||||
* \brief Deconstructor
|
||||
*/
|
||||
virtual ~TcpOptionWinScale ();
|
||||
|
||||
/**
|
||||
* \brief Print the option to a ostream
|
||||
*
|
||||
* Only the window scale (uint8_t) is printed out.
|
||||
*
|
||||
* \param os Stream to which print the option to
|
||||
*/
|
||||
virtual void Print (std::ostream &os) const;
|
||||
|
||||
/**
|
||||
* \brief Serialize the option to a Buffer
|
||||
*
|
||||
* The option writes three U8: kind, length, and the scale.
|
||||
*
|
||||
* \param start Buffer::Iterator to which write to
|
||||
*/
|
||||
virtual void Serialize (Buffer::Iterator start) const;
|
||||
|
||||
/**
|
||||
* \brief Deserialize the option from a Buffer
|
||||
*
|
||||
* The option read two U8: length, and the scale. Kind SHOULD be read
|
||||
* before call this method.
|
||||
*
|
||||
* \param start Buffer::Iterator to which read from
|
||||
*/
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start);
|
||||
|
||||
/**
|
||||
* \brief Get the kind value for this option
|
||||
*
|
||||
* \return Fixed value, TcpOption::WINSCALE
|
||||
*/
|
||||
virtual uint8_t GetKind (void) const;
|
||||
|
||||
/**
|
||||
* \brief Get the serialized size of the option
|
||||
*
|
||||
* \return Fixed value, 3
|
||||
*/
|
||||
virtual uint32_t GetSerializedSize (void) const;
|
||||
|
||||
/**
|
||||
@@ -114,7 +74,7 @@ public:
|
||||
/**
|
||||
* \brief Set the scale option
|
||||
*
|
||||
* The scale option SHOULD be <= 14 (as RFC).
|
||||
* The scale option SHOULD be <= 14 (as \RFC{1323}).
|
||||
*
|
||||
* \param scale Scale factor
|
||||
*/
|
||||
|
||||
@@ -74,7 +74,7 @@ TcpOption::CreateOption (uint8_t kind)
|
||||
{ TcpOption::WINSCALE, TcpOptionWinScale::GetTypeId () }
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(toTid) / sizeof(kindToTid); ++i)
|
||||
for (unsigned int i = 0; i < sizeof (toTid) / sizeof (kindToTid); ++i)
|
||||
{
|
||||
if (toTid[i].kind == kind)
|
||||
{
|
||||
|
||||
@@ -37,28 +37,72 @@ public:
|
||||
TcpOption ();
|
||||
virtual ~TcpOption ();
|
||||
|
||||
/**
|
||||
* \brief Get the type ID.
|
||||
* \return the object TypeId
|
||||
*/
|
||||
static TypeId GetTypeId (void);
|
||||
|
||||
virtual TypeId GetInstanceTypeId (void) const;
|
||||
|
||||
/**
|
||||
* The option Kind, as defined in the respective RFCs.
|
||||
*/
|
||||
enum Kind
|
||||
{
|
||||
END = 0,
|
||||
NOP = 1,
|
||||
MSS = 2,
|
||||
WINSCALE = 3,
|
||||
SACK_PERM = 4,
|
||||
SACK = 5,
|
||||
TS = 8
|
||||
END = 0, //!< END
|
||||
NOP = 1, //!< NOP
|
||||
MSS = 2, //!< MSS
|
||||
WINSCALE = 3, //!< WINSCALE
|
||||
SACK_PERM = 4,//!< SACK_PERM
|
||||
SACK = 5, //!< SACK
|
||||
TS = 8 //!< TS
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Print the Option contents
|
||||
* \param os the output stream
|
||||
*/
|
||||
virtual void Print (std::ostream &os) const = 0;
|
||||
/**
|
||||
* \brief Serialize the Option to a buffer iterator
|
||||
* \param start the buffer iterator
|
||||
*/
|
||||
virtual void Serialize (Buffer::Iterator start) const = 0;
|
||||
|
||||
/**
|
||||
* \brief Deserialize the Option from a buffer iterator
|
||||
* \param start the buffer iterator
|
||||
* \returns the number of deserialized bytes
|
||||
*/
|
||||
virtual uint32_t Deserialize (Buffer::Iterator start) = 0;
|
||||
|
||||
virtual uint8_t GetKind (void) const = 0; // Get the `kind' (as in RFC793) of this option
|
||||
virtual uint32_t GetSerializedSize (void) const = 0; // Get the total length of this option, >= 1
|
||||
/**
|
||||
* \brief Get the `kind' (as in \RFC{793}) of this option
|
||||
* \return the Option Kind
|
||||
*/
|
||||
virtual uint8_t GetKind (void) const = 0;
|
||||
/**
|
||||
* \brief Returns number of bytes required for Option
|
||||
* serialization.
|
||||
*
|
||||
* \returns number of bytes required for Option
|
||||
* serialization
|
||||
*/
|
||||
virtual uint32_t GetSerializedSize (void) const = 0;
|
||||
|
||||
static Ptr<TcpOption> CreateOption (uint8_t kind); // Factory method for all options
|
||||
/**
|
||||
* \brief Creates an option
|
||||
* \param kind the option kind
|
||||
* \return the requested option or an ns3::UnknownOption if the option is not supported
|
||||
*/
|
||||
static Ptr<TcpOption> CreateOption (uint8_t kind);
|
||||
|
||||
/**
|
||||
* \brief Check if the option is implemented
|
||||
* \param kind the Option kind
|
||||
* \return true if the option is known
|
||||
*/
|
||||
static bool IsKindKnown (uint8_t kind);
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user