A Discrete-Event Network Simulator
API
packet-sink.cc
Go to the documentation of this file.
1 /*
2  * Copyright 2007 University of Washington
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Tom Henderson (tomhend@u.washington.edu)
18  */
19 #include "packet-sink.h"
20 
21 #include "ns3/address-utils.h"
22 #include "ns3/address.h"
23 #include "ns3/boolean.h"
24 #include "ns3/inet-socket-address.h"
25 #include "ns3/inet6-socket-address.h"
26 #include "ns3/ipv4-packet-info-tag.h"
27 #include "ns3/ipv6-packet-info-tag.h"
28 #include "ns3/log.h"
29 #include "ns3/node.h"
30 #include "ns3/packet.h"
31 #include "ns3/simulator.h"
32 #include "ns3/socket-factory.h"
33 #include "ns3/socket.h"
34 #include "ns3/trace-source-accessor.h"
35 #include "ns3/udp-socket-factory.h"
36 #include "ns3/udp-socket.h"
37 
38 namespace ns3
39 {
40 
41 NS_LOG_COMPONENT_DEFINE("PacketSink");
42 
43 NS_OBJECT_ENSURE_REGISTERED(PacketSink);
44 
45 TypeId
47 {
48  static TypeId tid =
49  TypeId("ns3::PacketSink")
51  .SetGroupName("Applications")
52  .AddConstructor<PacketSink>()
53  .AddAttribute("Local",
54  "The Address on which to Bind the rx socket.",
55  AddressValue(),
56  MakeAddressAccessor(&PacketSink::m_local),
57  MakeAddressChecker())
58  .AddAttribute("Protocol",
59  "The type id of the protocol to use for the rx socket.",
63  .AddAttribute("EnableSeqTsSizeHeader",
64  "Enable optional header tracing of SeqTsSizeHeader",
65  BooleanValue(false),
68  .AddTraceSource("Rx",
69  "A packet has been received",
71  "ns3::Packet::AddressTracedCallback")
72  .AddTraceSource("RxWithAddresses",
73  "A packet has been received",
75  "ns3::Packet::TwoAddressTracedCallback")
76  .AddTraceSource("RxWithSeqTsSize",
77  "A packet with SeqTsSize header has been received",
79  "ns3::PacketSink::SeqTsSizeCallback");
80  return tid;
81 }
82 
84 {
85  NS_LOG_FUNCTION(this);
86  m_socket = nullptr;
87  m_totalRx = 0;
88 }
89 
91 {
92  NS_LOG_FUNCTION(this);
93 }
94 
95 uint64_t
97 {
98  NS_LOG_FUNCTION(this);
99  return m_totalRx;
100 }
101 
104 {
105  NS_LOG_FUNCTION(this);
106  return m_socket;
107 }
108 
109 std::list<Ptr<Socket>>
111 {
112  NS_LOG_FUNCTION(this);
113  return m_socketList;
114 }
115 
116 void
118 {
119  NS_LOG_FUNCTION(this);
120  m_socket = nullptr;
121  m_socketList.clear();
122 
123  // chain up
125 }
126 
127 // Application Methods
128 void
129 PacketSink::StartApplication() // Called at time specified by Start
130 {
131  NS_LOG_FUNCTION(this);
132  // Create the socket if not already
133  if (!m_socket)
134  {
136  if (m_socket->Bind(m_local) == -1)
137  {
138  NS_FATAL_ERROR("Failed to bind socket");
139  }
140  m_socket->Listen();
143  {
144  Ptr<UdpSocket> udpSocket = DynamicCast<UdpSocket>(m_socket);
145  if (udpSocket)
146  {
147  // equivalent to setsockopt (MCAST_JOIN_GROUP)
148  udpSocket->MulticastJoinGroup(0, m_local);
149  }
150  else
151  {
152  NS_FATAL_ERROR("Error: joining multicast on a non-UDP socket");
153  }
154  }
155  }
156 
158  {
160  }
162  {
164  }
165  else
166  {
167  m_localPort = 0;
168  }
170  m_socket->SetRecvPktInfo(true);
175 }
176 
177 void
178 PacketSink::StopApplication() // Called at time specified by Stop
179 {
180  NS_LOG_FUNCTION(this);
181  while (!m_socketList.empty()) // these are accepted sockets, close them
182  {
183  Ptr<Socket> acceptedSocket = m_socketList.front();
184  m_socketList.pop_front();
185  acceptedSocket->Close();
186  }
187  if (m_socket)
188  {
189  m_socket->Close();
191  }
192 }
193 
194 void
196 {
197  NS_LOG_FUNCTION(this << socket);
198  Ptr<Packet> packet;
199  Address from;
200  Address localAddress;
201  while ((packet = socket->RecvFrom(from)))
202  {
203  if (packet->GetSize() == 0)
204  { // EOF
205  break;
206  }
207  m_totalRx += packet->GetSize();
209  {
210  NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " packet sink received "
211  << packet->GetSize() << " bytes from "
212  << InetSocketAddress::ConvertFrom(from).GetIpv4() << " port "
213  << InetSocketAddress::ConvertFrom(from).GetPort() << " total Rx "
214  << m_totalRx << " bytes");
215  }
216  else if (Inet6SocketAddress::IsMatchingType(from))
217  {
218  NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " packet sink received "
219  << packet->GetSize() << " bytes from "
220  << Inet6SocketAddress::ConvertFrom(from).GetIpv6() << " port "
222  << " total Rx " << m_totalRx << " bytes");
223  }
224 
225  if (!m_rxTrace.IsEmpty() || !m_rxTraceWithAddresses.IsEmpty() ||
227  {
228  Ipv4PacketInfoTag interfaceInfo;
229  Ipv6PacketInfoTag interface6Info;
230  if (packet->RemovePacketTag(interfaceInfo))
231  {
232  localAddress = InetSocketAddress(interfaceInfo.GetAddress(), m_localPort);
233  }
234  else if (packet->RemovePacketTag(interface6Info))
235  {
236  localAddress = Inet6SocketAddress(interface6Info.GetAddress(), m_localPort);
237  }
238  else
239  {
240  socket->GetSockName(localAddress);
241  }
242  m_rxTrace(packet, from);
243  m_rxTraceWithAddresses(packet, from, localAddress);
244 
246  {
247  PacketReceived(packet, from, localAddress);
248  }
249  }
250  }
251 }
252 
253 void
254 PacketSink::PacketReceived(const Ptr<Packet>& p, const Address& from, const Address& localAddress)
255 {
256  SeqTsSizeHeader header;
257  Ptr<Packet> buffer;
258 
259  auto itBuffer = m_buffer.find(from);
260  if (itBuffer == m_buffer.end())
261  {
262  itBuffer = m_buffer.insert(std::make_pair(from, Create<Packet>(0))).first;
263  }
264 
265  buffer = itBuffer->second;
266  buffer->AddAtEnd(p);
267  buffer->PeekHeader(header);
268 
269  NS_ABORT_IF(header.GetSize() == 0);
270 
271  while (buffer->GetSize() >= header.GetSize())
272  {
273  NS_LOG_DEBUG("Removing packet of size " << header.GetSize() << " from buffer of size "
274  << buffer->GetSize());
275  Ptr<Packet> complete = buffer->CreateFragment(0, static_cast<uint32_t>(header.GetSize()));
276  buffer->RemoveAtStart(static_cast<uint32_t>(header.GetSize()));
277 
278  complete->RemoveHeader(header);
279 
280  m_rxTraceWithSeqTsSize(complete, from, localAddress, header);
281 
282  if (buffer->GetSize() > header.GetSerializedSize())
283  {
284  buffer->PeekHeader(header);
285  }
286  else
287  {
288  break;
289  }
290  }
291 }
292 
293 void
295 {
296  NS_LOG_FUNCTION(this << socket);
297 }
298 
299 void
301 {
302  NS_LOG_FUNCTION(this << socket);
303 }
304 
305 void
307 {
308  NS_LOG_FUNCTION(this << s << from);
310  m_socketList.push_back(s);
311 }
312 
313 } // Namespace ns3
a polymophic address class
Definition: address.h:101
The base class for all ns3 applications.
Definition: application.h:62
void DoDispose() override
Destructor implementation.
Definition: application.cc:86
Ptr< Node > GetNode() const
Definition: application.cc:108
An Inet6 address class.
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
uint16_t GetPort() const
Get the port.
static bool IsMatchingType(const Address &addr)
If the address match.
Ipv6Address GetIpv6() const
Get the IPv6 address.
an Inet address class
static bool IsMatchingType(const Address &address)
Ipv4Address GetIpv4() const
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
Ipv4Address GetAddress() const
Get the tag's address.
This class implements a tag that carries socket ancillary data to the socket interface.
Ipv6Address GetAddress() const
Get the tag's address.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:967
uint32_t RemoveHeader(Header &header)
Deserialize and remove the header from the internal buffer.
Definition: packet.cc:294
void AddAtEnd(Ptr< const Packet > packet)
Concatenate the input packet at the end of the current packet.
Definition: packet.cc:354
uint32_t GetSize() const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:861
void RemoveAtStart(uint32_t size)
Remove size bytes from the start of the current packet.
Definition: packet.cc:384
uint32_t PeekHeader(Header &header) const
Deserialize but does not remove the header from the internal buffer.
Definition: packet.cc:305
Ptr< Packet > CreateFragment(uint32_t start, uint32_t length) const
Create a new packet which contains a fragment of the original packet.
Definition: packet.cc:238
Receive and consume traffic generated to an IP address and port.
Definition: packet-sink.h:75
static TypeId GetTypeId()
Get the type ID.
Definition: packet-sink.cc:46
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer
Buffer for received packets.
Definition: packet-sink.h:189
TracedCallback< Ptr< const Packet >, const Address &, const Address & > m_rxTraceWithAddresses
Callback for tracing the packet Rx events, includes source and destination addresses.
Definition: packet-sink.h:206
void StopApplication() override
Application specific shutdown code.
Definition: packet-sink.cc:178
TypeId m_tid
Protocol TypeId.
Definition: packet-sink.h:199
Ptr< Socket > GetListeningSocket() const
Definition: packet-sink.cc:103
uint16_t m_localPort
Local port to bind to.
Definition: packet-sink.h:197
Address m_local
Local address to bind to (address and port)
Definition: packet-sink.h:196
std::list< Ptr< Socket > > m_socketList
the accepted sockets
Definition: packet-sink.h:194
void HandleRead(Ptr< Socket > socket)
Handle a packet received by the application.
Definition: packet-sink.cc:195
uint64_t GetTotalRx() const
Definition: packet-sink.cc:96
void HandleAccept(Ptr< Socket > socket, const Address &from)
Handle an incoming connection.
Definition: packet-sink.cc:306
void HandlePeerError(Ptr< Socket > socket)
Handle an connection error.
Definition: packet-sink.cc:300
TracedCallback< Ptr< const Packet >, const Address &, const Address &, const SeqTsSizeHeader & > m_rxTraceWithSeqTsSize
Callbacks for tracing the packet Rx events, includes source, destination addresses,...
Definition: packet-sink.h:210
uint64_t m_totalRx
Total bytes received.
Definition: packet-sink.h:198
~PacketSink() override
Definition: packet-sink.cc:90
void StartApplication() override
Application specific startup code.
Definition: packet-sink.cc:129
void DoDispose() override
Destructor implementation.
Definition: packet-sink.cc:117
bool m_enableSeqTsSizeHeader
Enable or disable the export of SeqTsSize header.
Definition: packet-sink.h:201
std::list< Ptr< Socket > > GetAcceptedSockets() const
Definition: packet-sink.cc:110
void HandlePeerClose(Ptr< Socket > socket)
Handle an connection close.
Definition: packet-sink.cc:294
Ptr< Socket > m_socket
Listening socket.
Definition: packet-sink.h:193
void PacketReceived(const Ptr< Packet > &p, const Address &from, const Address &localAddress)
Packet received: assemble byte stream to extract SeqTsSizeHeader.
Definition: packet-sink.cc:254
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
Traced Callback: received packets, source address.
Definition: packet-sink.h:204
Header with a sequence, a timestamp, and a "size" attribute.
uint32_t GetSerializedSize() const override
uint64_t GetSize() const
Get the size information that the header is carrying.
static Time Now()
Return the current simulation virtual time.
Definition: simulator.cc:208
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition: socket.cc:354
void SetCloseCallbacks(Callback< void, Ptr< Socket >> normalClose, Callback< void, Ptr< Socket >> errorClose)
Detect socket recv() events such as graceful shutdown or error.
Definition: socket.cc:96
void SetAcceptCallback(Callback< bool, Ptr< Socket >, const Address & > connectionRequest, Callback< void, Ptr< Socket >, const Address & > newConnectionCreated)
Accept connection requests from remote hosts.
Definition: socket.cc:105
void SetRecvCallback(Callback< void, Ptr< Socket >> receivedData)
Notify application when new data is available to be read.
Definition: socket.cc:128
virtual int ShutdownSend()=0
virtual int GetSockName(Address &address) const =0
Get socket address.
static Ptr< Socket > CreateSocket(Ptr< Node > node, TypeId tid)
This method wraps the creation of sockets that is performed on a given node by a SocketFactory specif...
Definition: socket.cc:72
virtual int Close()=0
Close a socket.
virtual int Bind(const Address &address)=0
Allocate a local endpoint for this socket.
virtual int Listen()=0
Listen for incoming connections.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)=0
Read a single packet from the socket and retrieve the sender address.
@ S
second
Definition: nstime.h:116
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:931
static TypeId GetTypeId()
Get the type ID.
Callback< R, Args... > MakeNullCallback()
Definition: callback.h:747
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
Definition: fatal-error.h:179
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition: abort.h:76
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition: log.h:268
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by ",...
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:46
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
bool IsMulticast(const Address &ad)
Address family-independent test for a multicast address.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeBooleanChecker()
Definition: boolean.cc:124
Callback< R, Args... > MakeCallback(R(T::*memPtr)(Args...), OBJ objPtr)
Build Callbacks for class method members which take varying numbers of arguments and potentially retu...
Definition: callback.h:704
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition: type-id.cc:1250
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition: boolean.h:86
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Definition: type-id.h:598