A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
tcp-option-sack.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2011 Adrian Sai-wah Tam
3 * Copyright (c) 2015 ResiliNets, ITTC, University of Kansas
4 *
5 * SPDX-License-Identifier: GPL-2.0-only
6 *
7 * Original Author: Adrian Sai-wah Tam <adrian.sw.tam@gmail.com>
8 * Documentation, test cases: Truc Anh N. Nguyen <annguyen@ittc.ku.edu>
9 * ResiliNets Research Group https://resilinets.org/
10 * The University of Kansas
11 * James P.G. Sterbenz <jpgs@ittc.ku.edu>, director
12 */
13
14#include "tcp-option-sack.h"
15
16#include "ns3/log.h"
17
18namespace ns3
19{
20
21NS_LOG_COMPONENT_DEFINE("TcpOptionSack");
22
23NS_OBJECT_ENSURE_REGISTERED(TcpOptionSack);
24
29
33
36{
37 static TypeId tid = TypeId("ns3::TcpOptionSack")
39 .SetGroupName("Internet")
40 .AddConstructor<TcpOptionSack>();
41 return tid;
42}
43
44void
45TcpOptionSack::Print(std::ostream& os) const
46{
47 os << "blocks: " << GetNumSackBlocks() << ",";
48 for (auto it = m_sackList.begin(); it != m_sackList.end(); ++it)
49 {
50 os << "[" << it->first << "," << it->second << "]";
51 }
52}
53
56{
57 NS_LOG_FUNCTION(this);
58 NS_LOG_LOGIC("Serialized size: " << 2 + GetNumSackBlocks() * 8);
59 return 2 + GetNumSackBlocks() * 8;
60}
61
62void
64{
65 NS_LOG_FUNCTION(this);
66 Buffer::Iterator i = start;
67 i.WriteU8(GetKind()); // Kind
68 auto length = static_cast<uint8_t>(GetNumSackBlocks() * 8 + 2);
69 i.WriteU8(length); // Length
70
71 for (auto it = m_sackList.begin(); it != m_sackList.end(); ++it)
72 {
73 SequenceNumber32 leftEdge = it->first;
74 SequenceNumber32 rightEdge = it->second;
75 i.WriteHtonU32(leftEdge.GetValue()); // Left edge of the block
76 i.WriteHtonU32(rightEdge.GetValue()); // Right edge of the block
77 }
78}
79
82{
83 NS_LOG_FUNCTION(this);
84 Buffer::Iterator i = start;
85 uint8_t readKind = i.ReadU8();
86 if (readKind != GetKind())
87 {
88 NS_LOG_WARN("Malformed SACK option, wrong type");
89 return 0;
90 }
91
92 uint8_t size = i.ReadU8();
93 NS_LOG_LOGIC("Size: " << static_cast<uint32_t>(size));
94 m_sackList.clear();
95 uint8_t sackCount = (size - 2) / 8;
96 while (sackCount)
97 {
98 SequenceNumber32 leftEdge(i.ReadNtohU32());
99 SequenceNumber32 rightEdge(i.ReadNtohU32());
100 SackBlock s(leftEdge, rightEdge);
101 AddSackBlock(s);
102 sackCount--;
103 }
104
105 return GetSerializedSize();
106}
107
108uint8_t
110{
111 return TcpOption::SACK;
112}
113
114void
116{
117 NS_LOG_FUNCTION(this);
118 m_sackList.push_back(s);
119}
120
123{
124 NS_LOG_FUNCTION(this);
125 NS_LOG_LOGIC("Number of SACK blocks appended: " << m_sackList.size());
126 return static_cast<uint32_t>(m_sackList.size());
127}
128
129void
134
137{
138 NS_LOG_FUNCTION(this);
139 return m_sackList;
140}
141
142std::ostream&
143operator<<(std::ostream& os, const TcpOptionSack& sackOption)
144{
145 std::stringstream ss;
146 ss << "{";
147 for (auto it = sackOption.m_sackList.begin(); it != sackOption.m_sackList.end(); ++it)
148 {
149 ss << *it;
150 }
151 ss << "}";
152 os << ss.str();
153 return os;
154}
155
156std::ostream&
157operator<<(std::ostream& os, const TcpOptionSack::SackBlock& sackBlock)
158{
159 std::stringstream ss;
160 ss << "[" << sackBlock.first << ";" << sackBlock.second << "]";
161 os << ss.str();
162 return os;
163}
164
165} // namespace ns3
iterator in a Buffer instance
Definition buffer.h:89
void WriteU8(uint8_t data)
Definition buffer.h:870
uint32_t ReadNtohU32()
Definition buffer.h:967
void WriteHtonU32(uint32_t data)
Definition buffer.h:922
NUMERIC_TYPE GetValue() const
Extracts the numeric value of the sequence number.
Base class for all kinds of TCP options.
Definition tcp-option.h:27
Defines the TCP option of kind 5 (selective acknowledgment option) as in RFC 2018
void ClearSackList()
Clear the SACK list.
std::list< SackBlock > SackList
SACK list definition.
uint32_t GetNumSackBlocks() const
Count the total number of SACK blocks.
uint8_t GetKind() const override
Get the ‘kind’ (as in RFC 793 ) of this option.
void Print(std::ostream &os) const override
Print the Option contents.
void Serialize(Buffer::Iterator start) const override
Serialize the Option to a buffer iterator.
std::pair< SequenceNumber32, SequenceNumber32 > SackBlock
SACK block definition.
static TypeId GetTypeId()
Get the type ID.
void AddSackBlock(SackBlock s)
Add a SACK block.
uint32_t Deserialize(Buffer::Iterator start) override
Deserialize the Option from a buffer iterator.
uint32_t GetSerializedSize() const override
Returns number of bytes required for Option serialization.
SackList m_sackList
the list of SACK blocks
SackList GetSackList() const
Get the SACK list.
a unique identifier for an interface.
Definition type-id.h:49
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition log.h:271
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition log.h:250
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Every class exported by the ns3 library is enclosed in the ns3 namespace.
std::ostream & operator<<(std::ostream &os, const Angles &a)
Definition angles.cc:148