A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
packet-sink.cc
Go to the documentation of this file.
1/*
2 * Copyright 2007 University of Washington
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Author: Tom Henderson (tomhend@u.washington.edu)
7 */
8#include "packet-sink.h"
9
10#include "ns3/address-utils.h"
11#include "ns3/address.h"
12#include "ns3/boolean.h"
13#include "ns3/inet-socket-address.h"
14#include "ns3/inet6-socket-address.h"
15#include "ns3/ipv4-packet-info-tag.h"
16#include "ns3/ipv6-packet-info-tag.h"
17#include "ns3/log.h"
18#include "ns3/node.h"
19#include "ns3/packet.h"
20#include "ns3/simulator.h"
21#include "ns3/socket-factory.h"
22#include "ns3/socket.h"
23#include "ns3/trace-source-accessor.h"
24#include "ns3/udp-socket-factory.h"
25#include "ns3/udp-socket.h"
26
27namespace ns3
28{
29
30NS_LOG_COMPONENT_DEFINE("PacketSink");
31
33
34TypeId
36{
37 static TypeId tid =
38 TypeId("ns3::PacketSink")
40 .SetGroupName("Applications")
41 .AddConstructor<PacketSink>()
42 .AddAttribute("Local",
43 "The Address on which to Bind the rx socket.",
47 .AddAttribute("Protocol",
48 "The type id of the protocol to use for the rx socket.",
52 .AddAttribute("EnableSeqTsSizeHeader",
53 "Enable optional header tracing of SeqTsSizeHeader",
54 BooleanValue(false),
57 .AddTraceSource("Rx",
58 "A packet has been received",
60 "ns3::Packet::AddressTracedCallback")
61 .AddTraceSource("RxWithAddresses",
62 "A packet has been received",
64 "ns3::Packet::TwoAddressTracedCallback")
65 .AddTraceSource("RxWithSeqTsSize",
66 "A packet with SeqTsSize header has been received",
68 "ns3::PacketSink::SeqTsSizeCallback");
69 return tid;
70}
71
73{
74 NS_LOG_FUNCTION(this);
75 m_socket = nullptr;
76 m_totalRx = 0;
77}
78
83
84uint64_t
86{
87 NS_LOG_FUNCTION(this);
88 return m_totalRx;
89}
90
93{
94 NS_LOG_FUNCTION(this);
95 return m_socket;
96}
97
98std::list<Ptr<Socket>>
100{
101 NS_LOG_FUNCTION(this);
102 return m_socketList;
103}
104
105void
107{
108 NS_LOG_FUNCTION(this);
109 m_socket = nullptr;
110 m_socketList.clear();
111
112 // chain up
114}
115
116// Application Methods
117void
118PacketSink::StartApplication() // Called at time specified by Start
119{
120 NS_LOG_FUNCTION(this);
121 // Create the socket if not already
122 if (!m_socket)
123 {
125 NS_ABORT_MSG_IF(m_local.IsInvalid(), "'Local' attribute not properly set");
126 if (m_socket->Bind(m_local) == -1)
127 {
128 NS_FATAL_ERROR("Failed to bind socket");
129 }
130 m_socket->Listen();
133 {
135 if (udpSocket)
136 {
137 // equivalent to setsockopt (MCAST_JOIN_GROUP)
138 udpSocket->MulticastJoinGroup(0, m_local);
139 }
140 else
141 {
142 NS_FATAL_ERROR("Error: joining multicast on a non-UDP socket");
143 }
144 }
145 }
146
148 {
150 }
152 {
154 }
155 else
156 {
157 m_localPort = 0;
158 }
165}
166
167void
168PacketSink::StopApplication() // Called at time specified by Stop
169{
170 NS_LOG_FUNCTION(this);
171 while (!m_socketList.empty()) // these are accepted sockets, close them
172 {
173 Ptr<Socket> acceptedSocket = m_socketList.front();
174 m_socketList.pop_front();
175 acceptedSocket->Close();
176 }
177 if (m_socket)
178 {
179 m_socket->Close();
181 }
182}
183
184void
186{
187 NS_LOG_FUNCTION(this << socket);
188 Ptr<Packet> packet;
189 Address from;
190 Address localAddress;
191 while ((packet = socket->RecvFrom(from)))
192 {
193 if (packet->GetSize() == 0)
194 { // EOF
195 break;
196 }
197 m_totalRx += packet->GetSize();
199 {
200 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " packet sink received "
201 << packet->GetSize() << " bytes from "
202 << InetSocketAddress::ConvertFrom(from).GetIpv4() << " port "
203 << InetSocketAddress::ConvertFrom(from).GetPort() << " total Rx "
204 << m_totalRx << " bytes");
205 }
207 {
208 NS_LOG_INFO("At time " << Simulator::Now().As(Time::S) << " packet sink received "
209 << packet->GetSize() << " bytes from "
210 << Inet6SocketAddress::ConvertFrom(from).GetIpv6() << " port "
212 << " total Rx " << m_totalRx << " bytes");
213 }
214
215 if (!m_rxTrace.IsEmpty() || !m_rxTraceWithAddresses.IsEmpty() ||
217 {
218 Ipv4PacketInfoTag interfaceInfo;
219 Ipv6PacketInfoTag interface6Info;
220 if (packet->RemovePacketTag(interfaceInfo))
221 {
222 localAddress = InetSocketAddress(interfaceInfo.GetAddress(), m_localPort);
223 }
224 else if (packet->RemovePacketTag(interface6Info))
225 {
226 localAddress = Inet6SocketAddress(interface6Info.GetAddress(), m_localPort);
227 }
228 else
229 {
230 socket->GetSockName(localAddress);
231 }
232 m_rxTrace(packet, from);
233 m_rxTraceWithAddresses(packet, from, localAddress);
234
236 {
237 PacketReceived(packet, from, localAddress);
238 }
239 }
240 }
241}
242
243void
244PacketSink::PacketReceived(const Ptr<Packet>& p, const Address& from, const Address& localAddress)
245{
246 SeqTsSizeHeader header;
247 Ptr<Packet> buffer;
248
249 auto itBuffer = m_buffer.find(from);
250 if (itBuffer == m_buffer.end())
251 {
252 itBuffer = m_buffer.insert(std::make_pair(from, Create<Packet>(0))).first;
253 }
254
255 buffer = itBuffer->second;
256 buffer->AddAtEnd(p);
257 buffer->PeekHeader(header);
258
259 NS_ABORT_IF(header.GetSize() == 0);
260
261 while (buffer->GetSize() >= header.GetSize())
262 {
263 NS_LOG_DEBUG("Removing packet of size " << header.GetSize() << " from buffer of size "
264 << buffer->GetSize());
265 Ptr<Packet> complete = buffer->CreateFragment(0, static_cast<uint32_t>(header.GetSize()));
266 buffer->RemoveAtStart(static_cast<uint32_t>(header.GetSize()));
267
268 complete->RemoveHeader(header);
269
270 m_rxTraceWithSeqTsSize(complete, from, localAddress, header);
271
272 if (buffer->GetSize() > header.GetSerializedSize())
273 {
274 buffer->PeekHeader(header);
275 }
276 else
277 {
278 break;
279 }
280 }
281}
282
283void
285{
286 NS_LOG_FUNCTION(this << socket);
287}
288
289void
291{
292 NS_LOG_FUNCTION(this << socket);
293}
294
295void
297{
298 NS_LOG_FUNCTION(this << s << from);
299 s->SetRecvCallback(MakeCallback(&PacketSink::HandleRead, this));
300 m_socketList.push_back(s);
301}
302
303} // Namespace ns3
a polymophic address class
Definition address.h:90
bool IsInvalid() const
Definition address.cc:60
The base class for all ns3 applications.
Definition application.h:51
void DoDispose() override
Destructor implementation.
Ptr< Node > GetNode() const
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.
Receive and consume traffic generated to an IP address and port.
Definition packet-sink.h:64
static TypeId GetTypeId()
Get the type ID.
std::unordered_map< Address, Ptr< Packet >, AddressHash > m_buffer
Buffer for received packets.
TracedCallback< Ptr< const Packet >, const Address &, const Address & > m_rxTraceWithAddresses
Callback for tracing the packet Rx events, includes source and destination addresses.
void StopApplication() override
Application specific shutdown code.
TypeId m_tid
Protocol TypeId.
Ptr< Socket > GetListeningSocket() const
uint16_t m_localPort
Local port to bind to.
Address m_local
Local address to bind to (address and port)
std::list< Ptr< Socket > > m_socketList
the accepted sockets
void HandleRead(Ptr< Socket > socket)
Handle a packet received by the application.
uint64_t GetTotalRx() const
void HandleAccept(Ptr< Socket > socket, const Address &from)
Handle an incoming connection.
void HandlePeerError(Ptr< Socket > socket)
Handle an connection error.
TracedCallback< Ptr< const Packet >, const Address &, const Address &, const SeqTsSizeHeader & > m_rxTraceWithSeqTsSize
Callbacks for tracing the packet Rx events, includes source, destination addresses,...
uint64_t m_totalRx
Total bytes received.
~PacketSink() override
void StartApplication() override
Application specific startup code.
void DoDispose() override
Destructor implementation.
bool m_enableSeqTsSizeHeader
Enable or disable the export of SeqTsSize header.
std::list< Ptr< Socket > > GetAcceptedSockets() const
void HandlePeerClose(Ptr< Socket > socket)
Handle an connection close.
Ptr< Socket > m_socket
Listening socket.
void PacketReceived(const Ptr< Packet > &p, const Address &from, const Address &localAddress)
Packet received: assemble byte stream to extract SeqTsSizeHeader.
TracedCallback< Ptr< const Packet >, const Address & > m_rxTrace
Traced Callback: received packets, source address.
Smart pointer class similar to boost::intrusive_ptr.
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:197
void SetRecvPktInfo(bool flag)
Enable/Disable receive packet information to socket.
Definition socket.cc:343
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:94
virtual int ShutdownSend()=0
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:85
void SetRecvCallback(Callback< void, Ptr< Socket > > receivedData)
Notify application when new data is available to be read.
Definition socket.cc:117
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:61
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.
@ S
second
Definition nstime.h:105
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
static TypeId GetTypeId()
Get the type ID.
Callback< R, Args... > MakeNullCallback()
Definition callback.h:727
#define NS_FATAL_ERROR(msg)
Report a fatal error with a message and terminate.
#define NS_ABORT_MSG_IF(cond, msg)
Abnormal program termination if a condition is true, with a message.
Definition abort.h:97
#define NS_ABORT_IF(cond)
Abnormal program termination if a condition is true.
Definition abort.h:65
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition log.h:191
#define NS_LOG_DEBUG(msg)
Use NS_LOG to output a message of level LOG_DEBUG.
Definition log.h:257
#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:264
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition object-base.h:35
Ptr< T > Create(Ts &&... args)
Create class instances by constructors with varying numbers of arguments and return them by Ptr.
Definition ptr.h:436
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:113
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:684
Ptr< const AttributeChecker > MakeAddressChecker()
Definition address.cc:169
Ptr< T1 > DynamicCast(const Ptr< T2 > &p)
Cast a Ptr.
Definition ptr.h:580
Ptr< const AttributeChecker > MakeTypeIdChecker()
Definition type-id.cc:1320
Ptr< const AttributeAccessor > MakeBooleanAccessor(T1 a1)
Definition boolean.h:70
Ptr< const AttributeAccessor > MakeAddressAccessor(T1 a1)
Definition address.h:275
Ptr< const AttributeAccessor > MakeTypeIdAccessor(T1 a1)
Definition type-id.h:617