A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
packet-socket.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2007 Emmanuelle Laprise, INRIA
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 *
6 * Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
7 * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
8 */
9
10#include "packet-socket.h"
11
13
14#include "ns3/log.h"
15#include "ns3/node.h"
16#include "ns3/packet.h"
17#include "ns3/trace-source-accessor.h"
18#include "ns3/uinteger.h"
19
20#include <algorithm>
21
22namespace ns3
23{
24
25NS_LOG_COMPONENT_DEFINE("PacketSocket");
26
27NS_OBJECT_ENSURE_REGISTERED(PacketSocket);
28
29TypeId
31{
32 static TypeId tid = TypeId("ns3::PacketSocket")
34 .SetGroupName("Network")
35 .AddConstructor<PacketSocket>()
36 .AddTraceSource("Drop",
37 "Drop packet due to receive buffer overflow",
39 "ns3::Packet::TracedCallback")
40 .AddAttribute("RcvBufSize",
41 "PacketSocket maximum receive buffer size (bytes)",
42 UintegerValue(131072),
45 return tid;
46}
47
49 : m_rxAvailable(0)
50{
51 NS_LOG_FUNCTION(this);
53 m_shutdownSend = false;
54 m_shutdownRecv = false;
56 m_isSingleDevice = false;
57 m_device = 0;
58}
59
60void
62{
63 NS_LOG_FUNCTION(this << node);
64 m_node = node;
65}
66
71
72void
78
81{
82 NS_LOG_FUNCTION(this);
83 return m_errno;
84}
85
88{
89 NS_LOG_FUNCTION(this);
90 return NS3_SOCK_RAW;
91}
92
95{
96 NS_LOG_FUNCTION(this);
97 return m_node;
98}
99
100int
102{
103 NS_LOG_FUNCTION(this);
104 PacketSocketAddress address;
105 address.SetProtocol(0);
106 address.SetAllDevices();
107 return DoBind(address);
108}
109
110int
112{
113 NS_LOG_FUNCTION(this);
114 return Bind();
115}
116
117int
119{
120 NS_LOG_FUNCTION(this << address);
122 {
124 return -1;
125 }
127 return DoBind(ad);
128}
129
130int
132{
133 NS_LOG_FUNCTION(this << address);
135 {
137 return -1;
138 }
139 if (m_state == STATE_CLOSED)
140 {
142 return -1;
143 }
144 Ptr<NetDevice> dev;
145 if (address.IsSingleDevice())
146 {
147 dev = m_node->GetDevice(address.GetSingleDevice());
148 }
149 else
150 {
151 dev = nullptr;
152 }
154 address.GetProtocol(),
155 dev);
157 m_protocol = address.GetProtocol();
158 m_isSingleDevice = address.IsSingleDevice();
159 m_device = address.GetSingleDevice();
160 m_boundnetdevice = dev;
161 return 0;
162}
163
164int
166{
167 NS_LOG_FUNCTION(this);
168 if (m_state == STATE_CLOSED)
169 {
171 return -1;
172 }
173 m_shutdownSend = true;
174 return 0;
175}
176
177int
179{
180 NS_LOG_FUNCTION(this);
181 if (m_state == STATE_CLOSED)
182 {
184 return -1;
185 }
186 m_shutdownRecv = true;
187 return 0;
188}
189
190int
192{
193 NS_LOG_FUNCTION(this);
194 if (m_state == STATE_CLOSED)
195 {
197 return -1;
198 }
199 else if (m_state == STATE_BOUND || m_state == STATE_CONNECTED)
200 {
202 }
204 m_shutdownSend = true;
205 m_shutdownRecv = true;
206 return 0;
207}
208
209int
211{
212 NS_LOG_FUNCTION(this << ad);
213
214 if (m_state == STATE_CLOSED)
215 {
217 goto error;
218 }
219 if (m_state == STATE_OPEN)
220 {
221 // connect should happen _after_ bind.
222 m_errno = ERROR_INVAL; // generic error condition.
223 goto error;
224 }
226 {
228 goto error;
229 }
231 {
233 goto error;
234 }
235 m_destAddr = ad;
238 return 0;
239error:
241 return -1;
242}
243
244int
246{
247 NS_LOG_FUNCTION(this);
249 return -1;
250}
251
252int
254{
255 NS_LOG_FUNCTION(this << p << flags);
257 {
259 return -1;
260 }
261 return SendTo(p, flags, m_destAddr);
262}
263
266{
267 NS_LOG_FUNCTION(this << ad);
268 if (ad.IsSingleDevice())
269 {
271 return device->GetMtu();
272 }
273 else
274 {
275 uint32_t minMtu = 0xffff;
276 for (uint32_t i = 0; i < m_node->GetNDevices(); i++)
277 {
278 Ptr<NetDevice> device = m_node->GetDevice(i);
279 minMtu = std::min(minMtu, (uint32_t)device->GetMtu());
280 }
281 return minMtu;
282 }
283}
284
287{
288 NS_LOG_FUNCTION(this);
290 {
292 return GetMinMtu(ad);
293 }
294 // If we are not connected, we return a 'safe' value by default.
295 return 0xffff;
296}
297
298int
300{
301 NS_LOG_FUNCTION(this << p << flags << address);
303 if (m_state == STATE_CLOSED)
304 {
305 NS_LOG_LOGIC("ERROR_BADF");
307 return -1;
308 }
309 if (m_shutdownSend)
310 {
311 NS_LOG_LOGIC("ERROR_SHUTDOWN");
313 return -1;
314 }
316 {
317 NS_LOG_LOGIC("ERROR_AFNOSUPPORT");
319 return -1;
320 }
322 if (p->GetSize() > GetMinMtu(ad))
323 {
325 return -1;
326 }
327
328 uint8_t priority = GetPriority();
329 if (priority)
330 {
331 SocketPriorityTag priorityTag;
332 priorityTag.SetPriority(priority);
333 p->ReplacePacketTag(priorityTag);
334 }
335
336 bool error = false;
337 Address dest = ad.GetPhysicalAddress();
338 uint32_t pktSize = p->GetSize(); // device->Send() may modify the packet
339 if (ad.IsSingleDevice())
340 {
342 if (!device->Send(p, dest, ad.GetProtocol()))
343 {
344 NS_LOG_LOGIC("error: NetDevice::Send error");
345 error = true;
346 }
347 }
348 else
349 {
350 for (uint32_t i = 0; i < m_node->GetNDevices(); i++)
351 {
352 Ptr<NetDevice> device = m_node->GetDevice(i);
353 if (!device->Send(p, dest, ad.GetProtocol()))
354 {
355 NS_LOG_LOGIC("error: NetDevice::Send error");
356 error = true;
357 }
358 }
359 }
360 if (!error)
361 {
364 }
365
366 if (error)
367 {
368 NS_LOG_LOGIC("ERROR_INVAL 2");
370 return -1;
371 }
372 else
373 {
374 return pktSize;
375 }
376}
377
378void
380 Ptr<const Packet> packet,
381 uint16_t protocol,
382 const Address& from,
383 const Address& to,
384 NetDevice::PacketType packetType)
385{
386 NS_LOG_FUNCTION(this << device << packet << protocol << from << to << packetType);
387 if (m_shutdownRecv)
388 {
389 return;
390 }
391 PacketSocketAddress address;
392 address.SetPhysicalAddress(from);
393 address.SetSingleDevice(device->GetIfIndex());
394 address.SetProtocol(protocol);
395
396 if ((m_rxAvailable + packet->GetSize()) <= m_rcvBufSize)
397 {
398 Ptr<Packet> copy = packet->Copy();
399 DeviceNameTag dnt;
400 dnt.SetDeviceName(device->GetTypeId().GetName());
401 PacketSocketTag pst;
402 pst.SetPacketType(packetType);
403 pst.SetDestAddress(to);
404 copy->AddPacketTag(pst); // Attach Packet Type and Dest Address
405 copy->AddPacketTag(dnt); // Attach device source name
406 // in case the packet still has a priority tag, remove it
407 SocketPriorityTag priorityTag;
408 copy->RemovePacketTag(priorityTag);
409 m_deliveryQueue.emplace(copy, address);
410 m_rxAvailable += packet->GetSize();
411 NS_LOG_LOGIC("UID is " << packet->GetUid() << " PacketSocket " << this);
413 }
414 else
415 {
416 // In general, this case should not occur unless the
417 // receiving application reads data from this socket slowly
418 // in comparison to the arrival rate
419 //
420 // drop and trace packet
421 NS_LOG_WARN("No receive buffer space available. Drop.");
422 m_dropTrace(packet);
423 }
424}
425
428{
429 NS_LOG_FUNCTION(this);
430 // We separately maintain this state to avoid walking the queue
431 // every time this might be called
432 return m_rxAvailable;
433}
434
437{
438 NS_LOG_FUNCTION(this << maxSize << flags);
439
440 Address fromAddress;
441 Ptr<Packet> packet = RecvFrom(maxSize, flags, fromAddress);
442 return packet;
443}
444
446PacketSocket::RecvFrom(uint32_t maxSize, uint32_t flags, Address& fromAddress)
447{
448 NS_LOG_FUNCTION(this << maxSize << flags);
449
450 if (m_deliveryQueue.empty())
451 {
452 return nullptr;
453 }
454 Ptr<Packet> p = m_deliveryQueue.front().first;
455 fromAddress = m_deliveryQueue.front().second;
456
457 if (p->GetSize() <= maxSize)
458 {
459 m_deliveryQueue.pop();
460 m_rxAvailable -= p->GetSize();
461 }
462 else
463 {
464 p = nullptr;
465 }
466 return p;
467}
468
469int
471{
472 NS_LOG_FUNCTION(this << address);
474
477 {
479 ad.SetPhysicalAddress(device->GetAddress());
481 }
482 else
483 {
485 ad.SetAllDevices();
486 }
487 address = ad;
488
489 return 0;
490}
491
492int
494{
495 NS_LOG_FUNCTION(this << address);
496
498 {
500 return -1;
501 }
502
503 address = m_destAddr;
504
505 return 0;
506}
507
508bool
510{
511 NS_LOG_FUNCTION(this << allowBroadcast);
512 return !allowBroadcast;
513}
514
515bool
517{
518 NS_LOG_FUNCTION(this);
519 return false;
520}
521
522/***************************************************************
523 * PacketSocket Tags
524 ***************************************************************/
525
529
530void
535
538{
539 return m_packetType;
540}
541
542void
547
550{
551 return m_destAddr;
552}
553
555
556TypeId
558{
559 static TypeId tid = TypeId("ns3::PacketSocketTag")
560 .SetParent<Tag>()
561 .SetGroupName("Network")
562 .AddConstructor<PacketSocketTag>();
563 return tid;
564}
565
566TypeId
568{
569 return GetTypeId();
570}
571
577
578void
584
585void
591
592void
593PacketSocketTag::Print(std::ostream& os) const
594{
595 os << "packetType=" << m_packetType;
596}
597
598/***************************************************************
599 * DeviceName Tags
600 ***************************************************************/
601
605
606void
608{
609 if (n.substr(0, 5) == "ns3::")
610 {
611 n = n.substr(5);
612 }
613 m_deviceName = n;
614}
615
616std::string
618{
619 return m_deviceName;
620}
621
623
624TypeId
626{
627 static TypeId tid = TypeId("ns3::DeviceNameTag")
628 .SetParent<Tag>()
629 .SetGroupName("Network")
630 .AddConstructor<DeviceNameTag>();
631 return tid;
632}
633
634TypeId
636{
637 return GetTypeId();
638}
639
642{
643 uint32_t s = 1 + m_deviceName.size(); // +1 for name length field
644 return s;
645}
646
647void
649{
650 const char* n = m_deviceName.c_str();
651 auto l = (uint8_t)m_deviceName.size();
652
653 i.WriteU8(l);
654 i.Write((uint8_t*)n, (uint32_t)l);
655}
656
657void
659{
660 uint8_t l = i.ReadU8();
661 char buf[256];
662
663 i.Read((uint8_t*)buf, (uint32_t)l);
664 m_deviceName = std::string(buf, l);
665}
666
667void
668DeviceNameTag::Print(std::ostream& os) const
669{
670 os << "DeviceName=" << m_deviceName;
671}
672
673} // namespace ns3
a polymophic address class
Definition address.h:90
uint32_t GetSerializedSize() const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition address.cc:144
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition address.cc:151
void Deserialize(TagBuffer buffer)
Definition address.cc:160
This class implements a tag that carries the ns3 device name from where a packet is coming.
DeviceNameTag()
Create an empty DeviceNameTag.
void Serialize(TagBuffer i) const override
static TypeId GetTypeId()
Get the type ID.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
std::string m_deviceName
Device name.
void SetDeviceName(std::string n)
Set the device name.
void Print(std::ostream &os) const override
uint32_t GetSerializedSize() const override
std::string GetDeviceName() const
Get the device name from where the corresponding packet is coming.
void Deserialize(TagBuffer i) override
PacketType
Packet types are used as they are in Linux.
Definition net-device.h:289
void UnregisterProtocolHandler(ProtocolHandler handler)
Definition node.cc:253
uint32_t GetNDevices() const
Definition node.cc:147
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition node.cc:138
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition node.cc:220
an address for a packet socket
uint32_t GetSingleDevice() const
Get the device this address is bound to.
bool IsSingleDevice() const
Checks if the address is bound to a specified NetDevice.
Address GetPhysicalAddress() const
Get the destination address.
void SetProtocol(uint16_t protocol)
Set the protocol.
static bool IsMatchingType(const Address &address)
void SetPhysicalAddress(const Address address)
Set the destination address.
static PacketSocketAddress ConvertFrom(const Address &address)
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
void SetAllDevices()
Set the address to match all the outgoing NetDevice.
uint16_t GetProtocol() const
Get the protocol.
A PacketSocket is a link between an application and a net device.
Ptr< Node > m_node
the associated node
int Bind6() override
Bind the socket to the NetDevice and register the protocol handler.
int Send(Ptr< Packet > p, uint32_t flags) override
Send data (or dummy data) to the remote host.
int Close() override
Close a socket.
Address m_destAddr
Default destination address.
int Connect(const Address &address) override
Initiate a connection to a remote host.
uint32_t m_rxAvailable
Rx queue size [Bytes].
int GetSockName(Address &address) const override
Get socket address.
Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress) override
Read a single packet from the socket and retrieve the sender address.
int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress) override
Send data to a specified peer.
std::queue< std::pair< Ptr< Packet >, Address > > m_deliveryQueue
Rx queue.
int GetPeerName(Address &address) const override
Get the peer address of a connected socket.
Ptr< Node > GetNode() const override
Return the node this socket is associated with.
int DoBind(const PacketSocketAddress &address)
Bind the socket to the NetDevice and register the protocol handler specified in the address.
int ShutdownSend() override
static TypeId GetTypeId()
Get the type ID.
bool SetAllowBroadcast(bool allowBroadcast) override
Configure whether broadcast datagram transmissions are allowed.
uint32_t m_rcvBufSize
Rx buffer size [Bytes].
void ForwardUp(Ptr< NetDevice > device, Ptr< const Packet > packet, uint16_t protocol, const Address &from, const Address &to, NetDevice::PacketType packetType)
Called by the L3 protocol when it received a packet to pass on to TCP.
bool m_isSingleDevice
Is bound to a single netDevice.
uint32_t GetMinMtu(PacketSocketAddress ad) const
Get the minimum MTU supported by the NetDevices bound to a specific address.
int Bind() override
Bind the socket to the NetDevice and register the protocol handler.
bool GetAllowBroadcast() const override
Query whether broadcast datagram transmissions are allowed.
int Listen() override
Listen for incoming connections.
uint16_t m_protocol
Socket protocol.
SocketErrno m_errno
Socket error code.
~PacketSocket() override
void SetNode(Ptr< Node > node)
Set the associated node.
uint32_t GetTxAvailable() const override
Returns the number of bytes which can be sent in a single call to Send.
SocketType GetSocketType() const override
State m_state
Socket state.
bool m_shutdownSend
Send no longer allowed.
uint32_t m_device
index of the bound NetDevice
int ShutdownRecv() override
SocketErrno GetErrno() const override
Get last error number.
TracedCallback< Ptr< const Packet > > m_dropTrace
Traced callback: dropped packets.
uint32_t GetRxAvailable() const override
Return number of bytes which can be returned from one or multiple calls to Recv.
bool m_shutdownRecv
Receive no longer allowed.
void DoDispose() override
Destructor implementation.
This class implements a tag that carries the dest address of a packet and the packet type.
Address GetDestAddress() const
Get the destination address of the corresponding packet.
Address m_destAddr
Destination address.
uint32_t GetSerializedSize() const override
NetDevice::PacketType GetPacketType() const
Get the packet type.
void Print(std::ostream &os) const override
NetDevice::PacketType m_packetType
Packet type.
static TypeId GetTypeId()
Get the type ID.
PacketSocketTag()
Create an empty PacketSocketTag.
void Serialize(TagBuffer i) const override
void SetPacketType(NetDevice::PacketType t)
Set the packet type.
void Deserialize(TagBuffer i) override
void SetDestAddress(Address a)
Set the destination address of the corresponding packet.
TypeId GetInstanceTypeId() const override
Get the most derived TypeId for this Object.
Smart pointer class similar to boost::intrusive_ptr.
A low-level Socket API based loosely on the BSD Socket API.
Definition socket.h:57
Ptr< Packet > Recv()
Read a single packet from the socket.
Definition socket.cc:163
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition socket.cc:281
SocketType
Enumeration of the possible socket types.
Definition socket.h:96
@ NS3_SOCK_RAW
Definition socket.h:100
void NotifyDataRecv()
Notify through the callback (if set) that some data have been received.
Definition socket.cc:291
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition socket.h:1070
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition socket.h:73
@ ERROR_SHUTDOWN
Definition socket.h:79
@ ERROR_INVAL
Definition socket.h:82
@ ERROR_OPNOTSUPP
Definition socket.h:80
@ ERROR_AFNOSUPPORT
Definition socket.h:81
@ ERROR_BADF
Definition socket.h:83
@ ERROR_NOTERROR
Definition socket.h:74
@ ERROR_ISCONN
Definition socket.h:75
@ ERROR_NOTCONN
Definition socket.h:76
@ ERROR_MSGSIZE
Definition socket.h:77
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition socket.cc:271
void NotifyConnectionSucceeded()
Notify through the callback (if set) that the connection has been established.
Definition socket.cc:203
uint8_t GetPriority() const
Query the priority value of this socket.
Definition socket.cc:382
void NotifyConnectionFailed()
Notify through the callback (if set) that the connection has not been established due to an error.
Definition socket.cc:213
indicates whether the socket has a priority set.
Definition socket.h:1307
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition socket.cc:843
read and write tag data
Definition tag-buffer.h:41
void Read(uint8_t *buffer, uint32_t size)
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition tag-buffer.h:161
TAG_BUFFER_INLINE uint8_t ReadU8()
Definition tag-buffer.h:185
void Write(const uint8_t *buffer, uint32_t size)
tag a set of bytes in a packet
Definition tag.h:28
a unique identifier for an interface.
Definition type-id.h:48
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition type-id.cc:1001
Hold an unsigned integer type.
Definition uinteger.h:34
#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
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
Ptr< const AttributeChecker > MakeUintegerChecker()
Definition uinteger.h:85
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 AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition uinteger.h:35
uint32_t pktSize
packet size used for the simulation (in bytes)