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 * 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 * Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
18 * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19 */
20
21#include "packet-socket.h"
22
24
25#include "ns3/log.h"
26#include "ns3/node.h"
27#include "ns3/packet.h"
28#include "ns3/trace-source-accessor.h"
29#include "ns3/uinteger.h"
30
31#include <algorithm>
32
33namespace ns3
34{
35
36NS_LOG_COMPONENT_DEFINE("PacketSocket");
37
38NS_OBJECT_ENSURE_REGISTERED(PacketSocket);
39
40TypeId
42{
43 static TypeId tid = TypeId("ns3::PacketSocket")
45 .SetGroupName("Network")
46 .AddConstructor<PacketSocket>()
47 .AddTraceSource("Drop",
48 "Drop packet due to receive buffer overflow",
50 "ns3::Packet::TracedCallback")
51 .AddAttribute("RcvBufSize",
52 "PacketSocket maximum receive buffer size (bytes)",
53 UintegerValue(131072),
55 MakeUintegerChecker<uint32_t>());
56 return tid;
57}
58
60 : m_rxAvailable(0)
61{
62 NS_LOG_FUNCTION(this);
64 m_shutdownSend = false;
65 m_shutdownRecv = false;
67 m_isSingleDevice = false;
68 m_device = 0;
69}
70
71void
73{
74 NS_LOG_FUNCTION(this << node);
75 m_node = node;
76}
77
79{
80 NS_LOG_FUNCTION(this);
81}
82
83void
85{
86 NS_LOG_FUNCTION(this);
87 m_device = 0;
88}
89
92{
93 NS_LOG_FUNCTION(this);
94 return m_errno;
95}
96
99{
100 NS_LOG_FUNCTION(this);
101 return NS3_SOCK_RAW;
102}
103
106{
107 NS_LOG_FUNCTION(this);
108 return m_node;
109}
110
111int
113{
114 NS_LOG_FUNCTION(this);
115 PacketSocketAddress address;
116 address.SetProtocol(0);
117 address.SetAllDevices();
118 return DoBind(address);
119}
120
121int
123{
124 NS_LOG_FUNCTION(this);
125 return Bind();
126}
127
128int
130{
131 NS_LOG_FUNCTION(this << address);
133 {
135 return -1;
136 }
138 return DoBind(ad);
139}
140
141int
143{
144 NS_LOG_FUNCTION(this << address);
146 {
148 return -1;
149 }
150 if (m_state == STATE_CLOSED)
151 {
153 return -1;
154 }
155 Ptr<NetDevice> dev;
156 if (address.IsSingleDevice())
157 {
158 dev = m_node->GetDevice(address.GetSingleDevice());
159 }
160 else
161 {
162 dev = nullptr;
163 }
165 address.GetProtocol(),
166 dev);
168 m_protocol = address.GetProtocol();
169 m_isSingleDevice = address.IsSingleDevice();
170 m_device = address.GetSingleDevice();
171 m_boundnetdevice = dev;
172 return 0;
173}
174
175int
177{
178 NS_LOG_FUNCTION(this);
179 if (m_state == STATE_CLOSED)
180 {
182 return -1;
183 }
184 m_shutdownSend = true;
185 return 0;
186}
187
188int
190{
191 NS_LOG_FUNCTION(this);
192 if (m_state == STATE_CLOSED)
193 {
195 return -1;
196 }
197 m_shutdownRecv = true;
198 return 0;
199}
200
201int
203{
204 NS_LOG_FUNCTION(this);
205 if (m_state == STATE_CLOSED)
206 {
208 return -1;
209 }
210 else if (m_state == STATE_BOUND || m_state == STATE_CONNECTED)
211 {
213 }
215 m_shutdownSend = true;
216 m_shutdownRecv = true;
217 return 0;
218}
219
220int
222{
223 NS_LOG_FUNCTION(this << ad);
224 PacketSocketAddress address;
225 if (m_state == STATE_CLOSED)
226 {
228 goto error;
229 }
230 if (m_state == STATE_OPEN)
231 {
232 // connect should happen _after_ bind.
233 m_errno = ERROR_INVAL; // generic error condition.
234 goto error;
235 }
237 {
239 goto error;
240 }
242 {
244 goto error;
245 }
246 m_destAddr = ad;
249 return 0;
250error:
252 return -1;
253}
254
255int
257{
258 NS_LOG_FUNCTION(this);
260 return -1;
261}
262
263int
265{
266 NS_LOG_FUNCTION(this << p << flags);
268 {
270 return -1;
271 }
272 return SendTo(p, flags, m_destAddr);
273}
274
277{
278 NS_LOG_FUNCTION(this << ad);
279 if (ad.IsSingleDevice())
280 {
282 return device->GetMtu();
283 }
284 else
285 {
286 uint32_t minMtu = 0xffff;
287 for (uint32_t i = 0; i < m_node->GetNDevices(); i++)
288 {
289 Ptr<NetDevice> device = m_node->GetDevice(i);
290 minMtu = std::min(minMtu, (uint32_t)device->GetMtu());
291 }
292 return minMtu;
293 }
294}
295
298{
299 NS_LOG_FUNCTION(this);
301 {
303 return GetMinMtu(ad);
304 }
305 // If we are not connected, we return a 'safe' value by default.
306 return 0xffff;
307}
308
309int
311{
312 NS_LOG_FUNCTION(this << p << flags << address);
314 if (m_state == STATE_CLOSED)
315 {
316 NS_LOG_LOGIC("ERROR_BADF");
318 return -1;
319 }
320 if (m_shutdownSend)
321 {
322 NS_LOG_LOGIC("ERROR_SHUTDOWN");
324 return -1;
325 }
327 {
328 NS_LOG_LOGIC("ERROR_AFNOSUPPORT");
330 return -1;
331 }
333 if (p->GetSize() > GetMinMtu(ad))
334 {
336 return -1;
337 }
338
339 uint8_t priority = GetPriority();
340 if (priority)
341 {
342 SocketPriorityTag priorityTag;
343 priorityTag.SetPriority(priority);
344 p->ReplacePacketTag(priorityTag);
345 }
346
347 bool error = false;
348 Address dest = ad.GetPhysicalAddress();
349 uint32_t pktSize = p->GetSize(); // device->Send() may modify the packet
350 if (ad.IsSingleDevice())
351 {
353 if (!device->Send(p, dest, ad.GetProtocol()))
354 {
355 NS_LOG_LOGIC("error: NetDevice::Send error");
356 error = true;
357 }
358 }
359 else
360 {
361 for (uint32_t i = 0; i < m_node->GetNDevices(); i++)
362 {
363 Ptr<NetDevice> device = m_node->GetDevice(i);
364 if (!device->Send(p, dest, ad.GetProtocol()))
365 {
366 NS_LOG_LOGIC("error: NetDevice::Send error");
367 error = true;
368 }
369 }
370 }
371 if (!error)
372 {
375 }
376
377 if (error)
378 {
379 NS_LOG_LOGIC("ERROR_INVAL 2");
381 return -1;
382 }
383 else
384 {
385 return pktSize;
386 }
387}
388
389void
391 Ptr<const Packet> packet,
392 uint16_t protocol,
393 const Address& from,
394 const Address& to,
395 NetDevice::PacketType packetType)
396{
397 NS_LOG_FUNCTION(this << device << packet << protocol << from << to << packetType);
398 if (m_shutdownRecv)
399 {
400 return;
401 }
402 PacketSocketAddress address;
403 address.SetPhysicalAddress(from);
404 address.SetSingleDevice(device->GetIfIndex());
405 address.SetProtocol(protocol);
406
407 if ((m_rxAvailable + packet->GetSize()) <= m_rcvBufSize)
408 {
409 Ptr<Packet> copy = packet->Copy();
410 DeviceNameTag dnt;
411 dnt.SetDeviceName(device->GetTypeId().GetName());
412 PacketSocketTag pst;
413 pst.SetPacketType(packetType);
414 pst.SetDestAddress(to);
415 copy->AddPacketTag(pst); // Attach Packet Type and Dest Address
416 copy->AddPacketTag(dnt); // Attach device source name
417 // in case the packet still has a priority tag, remove it
418 SocketPriorityTag priorityTag;
419 copy->RemovePacketTag(priorityTag);
420 m_deliveryQueue.emplace(copy, address);
421 m_rxAvailable += packet->GetSize();
422 NS_LOG_LOGIC("UID is " << packet->GetUid() << " PacketSocket " << this);
424 }
425 else
426 {
427 // In general, this case should not occur unless the
428 // receiving application reads data from this socket slowly
429 // in comparison to the arrival rate
430 //
431 // drop and trace packet
432 NS_LOG_WARN("No receive buffer space available. Drop.");
433 m_dropTrace(packet);
434 }
435}
436
439{
440 NS_LOG_FUNCTION(this);
441 // We separately maintain this state to avoid walking the queue
442 // every time this might be called
443 return m_rxAvailable;
444}
445
448{
449 NS_LOG_FUNCTION(this << maxSize << flags);
450
451 Address fromAddress;
452 Ptr<Packet> packet = RecvFrom(maxSize, flags, fromAddress);
453 return packet;
454}
455
457PacketSocket::RecvFrom(uint32_t maxSize, uint32_t flags, Address& fromAddress)
458{
459 NS_LOG_FUNCTION(this << maxSize << flags);
460
461 if (m_deliveryQueue.empty())
462 {
463 return nullptr;
464 }
465 Ptr<Packet> p = m_deliveryQueue.front().first;
466 fromAddress = m_deliveryQueue.front().second;
467
468 if (p->GetSize() <= maxSize)
469 {
470 m_deliveryQueue.pop();
471 m_rxAvailable -= p->GetSize();
472 }
473 else
474 {
475 p = nullptr;
476 }
477 return p;
478}
479
480int
482{
483 NS_LOG_FUNCTION(this << address);
485
488 {
490 ad.SetPhysicalAddress(device->GetAddress());
492 }
493 else
494 {
496 ad.SetAllDevices();
497 }
498 address = ad;
499
500 return 0;
501}
502
503int
505{
506 NS_LOG_FUNCTION(this << address);
507
509 {
511 return -1;
512 }
513
514 address = m_destAddr;
515
516 return 0;
517}
518
519bool
521{
522 NS_LOG_FUNCTION(this << allowBroadcast);
523 return !allowBroadcast;
524}
525
526bool
528{
529 NS_LOG_FUNCTION(this);
530 return false;
531}
532
533/***************************************************************
534 * PacketSocket Tags
535 ***************************************************************/
536
538{
539}
540
541void
543{
544 m_packetType = t;
545}
546
549{
550 return m_packetType;
551}
552
553void
555{
556 m_destAddr = a;
557}
558
561{
562 return m_destAddr;
563}
564
566
567TypeId
569{
570 static TypeId tid = TypeId("ns3::PacketSocketTag")
571 .SetParent<Tag>()
572 .SetGroupName("Network")
573 .AddConstructor<PacketSocketTag>();
574 return tid;
575}
576
577TypeId
579{
580 return GetTypeId();
581}
582
585{
586 return 1 + m_destAddr.GetSerializedSize();
587}
588
589void
591{
594}
595
596void
598{
601}
602
603void
604PacketSocketTag::Print(std::ostream& os) const
605{
606 os << "packetType=" << m_packetType;
607}
608
609/***************************************************************
610 * DeviceName Tags
611 ***************************************************************/
612
614{
615}
616
617void
619{
620 if (n.substr(0, 5) == "ns3::")
621 {
622 n = n.substr(5);
623 }
624 m_deviceName = n;
625}
626
627std::string
629{
630 return m_deviceName;
631}
632
634
635TypeId
637{
638 static TypeId tid = TypeId("ns3::DeviceNameTag")
639 .SetParent<Tag>()
640 .SetGroupName("Network")
641 .AddConstructor<DeviceNameTag>();
642 return tid;
643}
644
645TypeId
647{
648 return GetTypeId();
649}
650
653{
654 uint32_t s = 1 + m_deviceName.size(); // +1 for name length field
655 return s;
656}
657
658void
660{
661 const char* n = m_deviceName.c_str();
662 auto l = (uint8_t)m_deviceName.size();
663
664 i.WriteU8(l);
665 i.Write((uint8_t*)n, (uint32_t)l);
666}
667
668void
670{
671 uint8_t l = i.ReadU8();
672 char buf[256];
673
674 i.Read((uint8_t*)buf, (uint32_t)l);
675 m_deviceName = std::string(buf, l);
676}
677
678void
679DeviceNameTag::Print(std::ostream& os) const
680{
681 os << "DeviceName=" << m_deviceName;
682}
683
684} // namespace ns3
a polymophic address class
Definition: address.h:101
uint32_t GetSerializedSize() const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition: address.cc:155
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition: address.cc:162
void Deserialize(TagBuffer buffer)
Definition: address.cc:171
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:300
void UnregisterProtocolHandler(ProtocolHandler handler)
Definition: node.cc:264
uint32_t GetNDevices() const
Definition: node.cc:158
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:149
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:231
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.
Definition: packet-socket.h:95
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.
Definition: ptr.h:77
A low-level Socket API based loosely on the BSD Socket API.
Definition: socket.h:68
Ptr< Packet > Recv()
Read a single packet from the socket.
Definition: socket.cc:174
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:292
SocketType
Enumeration of the possible socket types.
Definition: socket.h:107
@ NS3_SOCK_RAW
Definition: socket.h:111
void NotifyDataRecv()
Notify through the callback (if set) that some data have been received.
Definition: socket.cc:302
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:1081
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:84
@ ERROR_SHUTDOWN
Definition: socket.h:90
@ ERROR_INVAL
Definition: socket.h:93
@ ERROR_OPNOTSUPP
Definition: socket.h:91
@ ERROR_AFNOSUPPORT
Definition: socket.h:92
@ ERROR_BADF
Definition: socket.h:94
@ ERROR_NOTERROR
Definition: socket.h:85
@ ERROR_ISCONN
Definition: socket.h:86
@ ERROR_NOTCONN
Definition: socket.h:87
@ ERROR_MSGSIZE
Definition: socket.h:88
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:282
void NotifyConnectionSucceeded()
Notify through the callback (if set) that the connection has been established.
Definition: socket.cc:214
uint8_t GetPriority() const
Query the priority value of this socket.
Definition: socket.cc:393
void NotifyConnectionFailed()
Notify through the callback (if set) that the connection has not been established due to an error.
Definition: socket.cc:224
indicates whether the socket has a priority set.
Definition: socket.h:1318
void SetPriority(uint8_t priority)
Set the tag's priority.
Definition: socket.cc:854
read and write tag data
Definition: tag-buffer.h:52
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:183
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:172
TAG_BUFFER_INLINE uint8_t ReadU8()
Definition: tag-buffer.h:196
void Write(const uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:129
tag a set of bytes in a packet
Definition: tag.h:39
a unique identifier for an interface.
Definition: type-id.h:59
TypeId SetParent(TypeId tid)
Set the parent TypeId.
Definition: type-id.cc:932
Hold an unsigned integer type.
Definition: uinteger.h:45
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Definition: uinteger.h:46
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:282
#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:261
#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.
Every class exported by the ns3 library is enclosed in the ns3 namespace.
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
uint32_t pktSize
packet size used for the simulation (in bytes)