A Discrete-Event Network Simulator
API
packet-socket.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 Emmanuelle Laprise, INRIA
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Authors: Emmanuelle Laprise <emmanuelle.laprise@bluekazoo.ca>
19  * Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
20  */
21 
22 #include "packet-socket.h"
23 #include "packet-socket-address.h"
24 #include "ns3/log.h"
25 #include "ns3/node.h"
26 #include "ns3/packet.h"
27 #include "ns3/uinteger.h"
28 #include "ns3/trace-source-accessor.h"
29 
30 #include <algorithm>
31 
32 namespace ns3 {
33 
34 NS_LOG_COMPONENT_DEFINE ("PacketSocket");
35 
36 NS_OBJECT_ENSURE_REGISTERED (PacketSocket);
37 
38 TypeId
40 {
41  static TypeId tid = TypeId ("ns3::PacketSocket")
42  .SetParent<Socket> ()
43  .AddConstructor<PacketSocket> ()
44  .AddTraceSource ("Drop", "Drop packet due to receive buffer overflow",
46  "ns3::Packet::TracedCallback")
47  .AddAttribute ("RcvBufSize",
48  "PacketSocket maximum receive buffer size (bytes)",
49  UintegerValue (131072),
51  MakeUintegerChecker<uint32_t> ())
52  ;
53  return tid;
54 }
55 
56 PacketSocket::PacketSocket () : m_rxAvailable (0)
57 {
58  NS_LOG_FUNCTION (this);
60  m_shutdownSend = false;
61  m_shutdownRecv = false;
63  m_isSingleDevice = false;
64  m_device = 0;
65 }
66 
67 void
69 {
70  NS_LOG_FUNCTION (this << node);
71  m_node = node;
72 }
73 
75 {
76  NS_LOG_FUNCTION (this);
77 }
78 
79 void
81 {
82  NS_LOG_FUNCTION (this);
83  m_device = 0;
84 }
85 
88 {
89  NS_LOG_FUNCTION (this);
90  return m_errno;
91 }
92 
95 {
96  NS_LOG_FUNCTION (this);
97  return NS3_SOCK_RAW;
98 }
99 
100 Ptr<Node>
102 {
103  NS_LOG_FUNCTION (this);
104  return m_node;
105 }
106 
107 int
109 {
110  NS_LOG_FUNCTION (this);
112  address.SetProtocol (0);
113  address.SetAllDevices ();
114  return DoBind (address);
115 }
116 
117 int
119 {
120  NS_LOG_FUNCTION (this);
121  return(Bind());
122 }
123 
124 int
126 {
127  NS_LOG_FUNCTION (this << address);
129  {
131  return -1;
132  }
134  return DoBind (ad);
135 }
136 
137 int
139 {
140  NS_LOG_FUNCTION (this << address);
141  if (m_state == STATE_BOUND ||
143  {
145  return -1;
146  }
147  if (m_state == STATE_CLOSED)
148  {
150  return -1;
151  }
152  Ptr<NetDevice> dev;
153  if (address.IsSingleDevice ())
154  {
155  dev = m_node->GetDevice (address.GetSingleDevice ());
156  }
157  else
158  {
159  dev = 0;
160  }
162  address.GetProtocol (), dev);
164  m_protocol = address.GetProtocol ();
165  m_isSingleDevice = address.IsSingleDevice ();
166  m_device = address.GetSingleDevice ();
167  m_boundnetdevice = dev;
168  return 0;
169 }
170 
171 int
173 {
174  NS_LOG_FUNCTION (this);
175  if (m_state == STATE_CLOSED)
176  {
178  return -1;
179  }
180  m_shutdownSend = true;
181  return 0;
182 }
183 
184 int
186 {
187  NS_LOG_FUNCTION (this);
188  if (m_state == STATE_CLOSED)
189  {
191  return -1;
192  }
193  m_shutdownRecv = true;
194  return 0;
195 }
196 
197 int
199 {
200  NS_LOG_FUNCTION (this);
201  if (m_state == STATE_CLOSED)
202  {
204  return -1;
205  }
206  else if (m_state == STATE_BOUND || m_state == STATE_CONNECTED)
207  {
209  }
211  m_shutdownSend = true;
212  m_shutdownRecv = true;
213  return 0;
214 }
215 
216 int
218 {
219  NS_LOG_FUNCTION (this << ad);
221  if (m_state == STATE_CLOSED)
222  {
224  goto error;
225  }
226  if (m_state == STATE_OPEN)
227  {
228  // connect should happen _after_ bind.
229  m_errno = ERROR_INVAL; // generic error condition.
230  goto error;
231  }
232  if (m_state == STATE_CONNECTED)
233  {
235  goto error;
236  }
238  {
240  goto error;
241  }
242  m_destAddr = ad;
245  return 0;
246 error:
248  return -1;
249 }
250 int
252 {
253  NS_LOG_FUNCTION (this);
255  return -1;
256 }
257 
258 int
259 PacketSocket::Send (Ptr<Packet> p, uint32_t flags)
260 {
261  NS_LOG_FUNCTION (this << p << flags);
262  if (m_state == STATE_OPEN ||
263  m_state == STATE_BOUND)
264  {
266  return -1;
267  }
268  return SendTo (p, flags, m_destAddr);
269 }
270 
271 uint32_t
273 {
274  NS_LOG_FUNCTION (this << ad);
275  if (ad.IsSingleDevice ())
276  {
278  return device->GetMtu ();
279  }
280  else
281  {
282  uint32_t minMtu = 0xffff;
283  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
284  {
285  Ptr<NetDevice> device = m_node->GetDevice (i);
286  minMtu = std::min (minMtu, (uint32_t)device->GetMtu ());
287  }
288  return minMtu;
289  }
290 }
291 
292 uint32_t
294 {
295  NS_LOG_FUNCTION (this);
296  if (m_state == STATE_CONNECTED)
297  {
299  return GetMinMtu (ad);
300  }
301  // If we are not connected, we return a 'safe' value by default.
302  return 0xffff;
303 }
304 
305 int
306 PacketSocket::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
307 {
308  NS_LOG_FUNCTION (this << p << flags << address);
310  if (m_state == STATE_CLOSED)
311  {
312  NS_LOG_LOGIC ("ERROR_BADF");
314  return -1;
315  }
316  if (m_shutdownSend)
317  {
318  NS_LOG_LOGIC ("ERROR_SHUTDOWN");
320  return -1;
321  }
323  {
324  NS_LOG_LOGIC ("ERROR_AFNOSUPPORT");
326  return -1;
327  }
328  ad = PacketSocketAddress::ConvertFrom (address);
329  if (p->GetSize () > GetMinMtu (ad))
330  {
332  return -1;
333  }
334 
335  bool error = false;
336  Address dest = ad.GetPhysicalAddress ();
337  if (ad.IsSingleDevice ())
338  {
340  if (!device->Send (p, dest, ad.GetProtocol ()))
341  {
342  NS_LOG_LOGIC ("error: NetDevice::Send error");
343  error = true;
344  }
345  }
346  else
347  {
348  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
349  {
350  Ptr<NetDevice> device = m_node->GetDevice (i);
351  if (!device->Send (p, dest, ad.GetProtocol ()))
352  {
353  NS_LOG_LOGIC ("error: NetDevice::Send error");
354  error = true;
355  }
356  }
357  }
358  if (!error)
359  {
360  NotifyDataSent (p->GetSize ());
362  }
363 
364  if (error)
365  {
366  NS_LOG_LOGIC ("ERROR_INVAL 2");
368  return -1;
369  }
370  else
371  {
372  return p->GetSize ();
373  }
374 }
375 
376 void
378  uint16_t protocol, const Address &from,
379  const Address &to, NetDevice::PacketType packetType)
380 {
381  NS_LOG_FUNCTION (this << device << packet << protocol << from << to << packetType);
382  if (m_shutdownRecv)
383  {
384  return;
385  }
387  address.SetPhysicalAddress (from);
388  address.SetSingleDevice (device->GetIfIndex ());
389  address.SetProtocol (protocol);
390 
391  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
392  {
393  Ptr<Packet> copy = packet->Copy ();
394  DeviceNameTag dnt;
395  dnt.SetDeviceName (device->GetTypeId ().GetName ());
396  PacketSocketTag pst;
397  pst.SetPacketType (packetType);
398  pst.SetDestAddress (to);
399  SocketAddressTag tag;
400  tag.SetAddress (address);
401  copy->AddPacketTag (tag); // Attach From Physical Address
402  copy->AddPacketTag (pst); // Attach Packet Type and Dest Address
403  copy->AddPacketTag (dnt); // Attach device source name
404  m_deliveryQueue.push (copy);
405  m_rxAvailable += packet->GetSize ();
406  NS_LOG_LOGIC ("UID is " << packet->GetUid () << " PacketSocket " << this);
407  NotifyDataRecv ();
408  }
409  else
410  {
411  // In general, this case should not occur unless the
412  // receiving application reads data from this socket slowly
413  // in comparison to the arrival rate
414  //
415  // drop and trace packet
416  NS_LOG_WARN ("No receive buffer space available. Drop.");
417  m_dropTrace (packet);
418  }
419 }
420 
421 uint32_t
423 {
424  NS_LOG_FUNCTION (this);
425  // We separately maintain this state to avoid walking the queue
426  // every time this might be called
427  return m_rxAvailable;
428 }
429 
431 PacketSocket::Recv (uint32_t maxSize, uint32_t flags)
432 {
433  NS_LOG_FUNCTION (this << maxSize << flags);
434  if (m_deliveryQueue.empty () )
435  {
436  return 0;
437  }
438  Ptr<Packet> p = m_deliveryQueue.front ();
439  if (p->GetSize () <= maxSize)
440  {
441  m_deliveryQueue.pop ();
442  m_rxAvailable -= p->GetSize ();
443  }
444  else
445  {
446  p = 0;
447  }
448  return p;
449 }
450 
452 PacketSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
453 {
454  NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
455  Ptr<Packet> packet = Recv (maxSize, flags);
456  if (packet != 0)
457  {
458  SocketAddressTag tag;
459  bool found;
460  found = packet->PeekPacketTag (tag);
461  NS_ASSERT (found);
462  fromAddress = tag.GetAddress ();
463  }
464  return packet;
465 }
466 
467 int
469 {
470  NS_LOG_FUNCTION (this << address);
472 
473  ad.SetProtocol (m_protocol);
474  if (m_isSingleDevice)
475  {
477  ad.SetPhysicalAddress (device->GetAddress ());
479  }
480  else
481  {
482  ad.SetPhysicalAddress (Address ());
483  ad.SetAllDevices ();
484  }
485  address = ad;
486 
487  return 0;
488 }
489 
490 bool
491 PacketSocket::SetAllowBroadcast (bool allowBroadcast)
492 {
493  NS_LOG_FUNCTION (this << allowBroadcast);
494  if (allowBroadcast)
495  {
496  return false;
497  }
498  return true;
499 }
500 
501 bool
503 {
504  NS_LOG_FUNCTION (this);
505  return false;
506 }
507 
508 /***************************************************************
509  * PacketSocket Tags
510  ***************************************************************/
511 
513 {
514 }
515 
516 void
518 {
519  m_packetType = t;
520 }
521 
524 {
525  return m_packetType;
526 }
527 
528 void
530 {
531  m_destAddr = a;
532 }
533 
534 Address
536 {
537  return m_destAddr;
538 }
539 
541 
542 TypeId
544 {
545  static TypeId tid = TypeId ("ns3::PacketSocketTag")
546  .SetParent<Tag> ()
547  .AddConstructor<PacketSocketTag> ()
548  ;
549  return tid;
550 }
551 TypeId
553 {
554  return GetTypeId ();
555 }
556 uint32_t
558 {
559  return 1 + m_destAddr.GetSerializedSize();
560 }
561 void
563 {
564  i.WriteU8 (m_packetType);
565  m_destAddr.Serialize (i);
566 }
567 void
569 {
572 }
573 void
574 PacketSocketTag::Print (std::ostream &os) const
575 {
576  os << "packetType=" << m_packetType;
577 }
578 
579 /***************************************************************
580  * DeviceName Tags
581  ***************************************************************/
582 
584 {
585 }
586 
587 void
589 {
590  if ( n.substr(0,5) == "ns3::" )
591  {
592  n = n.substr (5);
593  }
594  m_deviceName = n;
595 }
596 
597 std::string
599 {
600  return m_deviceName;
601 }
602 
604 
605 TypeId
607 {
608  static TypeId tid = TypeId ("ns3::DeviceNameTag")
609  .SetParent<Tag> ()
610  .AddConstructor<DeviceNameTag> ();
611  return tid;
612 }
613 TypeId
615 {
616  return GetTypeId ();
617 }
618 uint32_t
620 {
621  uint32_t s = 1 + m_deviceName.size(); // +1 for name length field
622  s = std::min (s, (uint32_t)PacketTagList::TagData::MAX_SIZE);
623  return s;
624 }
625 void
627 {
628  const char *n = m_deviceName.c_str();
629  uint8_t l = (uint8_t) m_deviceName.size ();
630 
631  l = std::min ((uint32_t)l, (uint32_t)PacketTagList::TagData::MAX_SIZE - 1);
632 
633  i.WriteU8 (l);
634  i.Write ( (uint8_t*) n , (uint32_t) l);
635 }
636 void
638 {
639  uint8_t l = i.ReadU8();
640  char buf[256];
641 
642  i.Read ( (uint8_t* ) buf, (uint32_t) l);
643  m_deviceName = std::string (buf, l);
644 }
645 void
646 DeviceNameTag::Print (std::ostream &os) const
647 {
648  os << "DeviceName=" << m_deviceName;
649 }
650 
651 
652 } // namespace ns3
static TypeId GetTypeId(void)
Get the type ID.
uint16_t GetProtocol(void) const
Get the protocol.
Size of serialization buffer data.
void Write(const uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:125
virtual enum SocketErrno GetErrno(void) const
Get last error number.
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
std::string m_deviceName
Device name.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register an Object subclass with the TypeId system.
Definition: object-base.h:44
void NotifyDataRecv(void)
Notify through the callback (if set) that some data have been received.
Definition: socket.cc:304
Address GetDestAddress(void) const
Get the destination address of the corresponding packet.
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:174
NetDevice::PacketType m_packetType
Packet type.
Address m_destAddr
Default destination address.
void AddPacketTag(const Tag &tag) const
Add a packet tag.
Definition: packet.cc:836
void SetAddress(Address addr)
Set the tag's address.
Definition: socket.cc:522
uint64_t GetUid(void) const
Returns the packet's Uid.
Definition: packet.cc:380
void NotifyConnectionFailed(void)
Notify through the callback (if set) that the connection has not been established due to an error...
Definition: socket.cc:226
std::queue< Ptr< Packet > > m_deliveryQueue
Rx queue.
an address for a packet socket
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
Read a single packet from the socket and retrieve the sender address.
#define NS_ASSERT(condition)
At runtime, in debugging builds, if this condition is not true, the program prints the source file...
Definition: assert.h:61
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:272
static bool IsMatchingType(const Address &address)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:201
virtual void DoDispose(void)
Destructor implementation.
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:766
void SetAllDevices(void)
Set the address to match all the outgoing NetDevice.
virtual uint32_t GetSerializedSize(void) const
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
void SetPacketType(NetDevice::PacketType t)
Set the packet type.
virtual int Bind(void)
Bind the socket to the NetDevice and register the protocol handler.
virtual void Print(std::ostream &os) const
uint32_t m_rxAvailable
Rx queue size [Bytes].
virtual int GetSockName(Address &address) const
Get socket address.
uint32_t GetSingleDevice(void) const
Get the device this address is bound to.
void UnregisterProtocolHandler(ProtocolHandler handler)
Definition: node.cc:253
void SetSingleDevice(uint32_t device)
Set the address to match only a specified NetDevice.
TAG_BUFFER_INLINE uint8_t ReadU8(void)
Definition: tag-buffer.h:195
a polymophic address class
Definition: address.h:90
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Create a TraceSourceAccessor which will control access to the underlying trace source.
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
Ptr< Node > m_node
the associated node
virtual void Serialize(TagBuffer i) const
A low-level Socket API based loosely on the BSD Socket API.
Definition: socket.h:66
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
Definition: packet.cc:858
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
void SetDestAddress(Address a)
Set the destination address of the corresponding packet.
virtual int ShutdownRecv(void)
virtual void Deserialize(TagBuffer i)
Hold an unsigned integer type.
Definition: uinteger.h:44
enum State m_state
Socket state.
Ptr< SampleEmitter > s
virtual uint32_t GetSerializedSize(void) const
static TypeId GetTypeId(void)
Get the type ID.
PacketSocketTag()
Create an empty PacketSocketTag.
bool m_isSingleDevice
Is bound to a single netDevice.
Ptr< NetDevice > GetDevice(uint32_t index) const
Retrieve the index-th NetDevice associated to this node.
Definition: node.cc:134
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:951
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1290
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:284
virtual Ptr< Node > GetNode(void) const
Return the node this socket is associated with.
virtual int Listen(void)
Listen for incoming connections.
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:252
void Deserialize(TagBuffer buffer)
Definition: address.cc:163
void NotifyConnectionSucceeded(void)
Notify through the callback (if set) that the connection has been established.
Definition: socket.cc:216
uint32_t GetSerializedSize(void) const
Get the number of bytes needed to serialize the underlying Address Typically, this is GetLength () + ...
Definition: address.cc:147
uint32_t m_device
index of the bound NetDevice
uint32_t GetNDevices(void) const
Definition: node.cc:142
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
virtual uint32_t GetRxAvailable(void) const
Return number of bytes which can be returned from one or multiple calls to Recv.
tag a set of bytes in a packet
Definition: tag.h:36
Every class exported by the ns3 library is enclosed in the ns3 namespace.
void SetPhysicalAddress(const Address address)
Set the destination address.
virtual int Send(Ptr< Packet > p, uint32_t flags)
Send data (or dummy data) to the remote host.
uint32_t m_rcvBufSize
Rx buffer size [Bytes].
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &toAddress)
Send data to a specified peer.
Address GetPhysicalAddress(void) const
Get the destination address.
bool m_shutdownSend
Send no longer allowed.
TAG_BUFFER_INLINE void WriteU8(uint8_t v)
Definition: tag-buffer.h:172
This class implements a tag that carries the ns3 device name from where a packet is coming...
virtual bool GetAllowBroadcast() const
Query whether broadcast datagram transmissions are allowed.
enum SocketErrno m_errno
Socket error code.
void RegisterProtocolHandler(ProtocolHandler handler, uint16_t protocolType, Ptr< NetDevice > device, bool promiscuous=false)
Definition: node.cc:219
virtual void Deserialize(TagBuffer i)
virtual int Close(void)
Close a socket.
uint16_t m_protocol
Socket protocol.
Address m_destAddr
Destination address.
bool m_shutdownRecv
Receive no longer allowed.
void SetNode(Ptr< Node > node)
Set the associated node.
static TypeId GetTypeId(void)
Get the type ID.
read and write tag data
Definition: tag-buffer.h:51
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:914
void Serialize(TagBuffer buffer) const
Serialize this address in host byte order to a byte buffer.
Definition: address.cc:154
int DoBind(const PacketSocketAddress &address)
Bind the socket to the NetDevice and register the protocol handler specified in the address...
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
virtual void Serialize(TagBuffer i) const
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:228
Address GetAddress(void) const
Get the tag's address.
Definition: socket.cc:529
virtual ~PacketSocket()
NetDevice::PacketType GetPacketType(void) const
Get the packet type.
virtual void Print(std::ostream &os) const
bool IsSingleDevice(void) const
Checks if the address is bound to a specified NetDevice.
DeviceNameTag()
Create an empty DeviceNameTag.
void SetProtocol(uint16_t protocol)
Set the protocol.
static PacketSocketAddress ConvertFrom(const Address &address)
virtual TypeId GetInstanceTypeId(void) const
Get the most derived TypeId for this Object.
virtual int Connect(const Address &address)
Initiate a connection to a remote host.
void Read(uint8_t *buffer, uint32_t size)
Definition: tag-buffer.cc:176
uint32_t GetMinMtu(PacketSocketAddress ad) const
Get the minimum MTU supported by the NetDevices bound to a specific address.
virtual int Bind6(void)
Bind the socket to the NetDevice and register the protocol handler.
std::string GetDeviceName(void) const
Get the device name from where the corresponding packet is coming.
tuple address
Definition: first.py:37
This class implements a tag that carries the dest address of a packet and the packet type...
TracedCallback< Ptr< const Packet > > m_dropTrace
Traced callback: dropped packets.
virtual int ShutdownSend(void)
Ptr< const AttributeAccessor > MakeUintegerAccessor(T1 a1)
Create an AttributeAccessor for a class data member, or a lone class get functor or set method...
Definition: uinteger.h:45
a unique identifier for an interface.
Definition: type-id.h:51
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:294
TypeId SetParent(TypeId tid)
Definition: type-id.cc:631
virtual enum SocketType GetSocketType(void) const
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.
void SetDeviceName(std::string n)
Set the device name.