A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 NS_LOG_COMPONENT_DEFINE ("PacketSocket");
33 
34 namespace ns3 {
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  .AddAttribute ("RcvBufSize",
47  "PacketSocket maximum receive buffer size (bytes)",
48  UintegerValue (131072),
49  MakeUintegerAccessor (&PacketSocket::m_rcvBufSize),
50  MakeUintegerChecker<uint32_t> ())
51  ;
52  return tid;
53 }
54 
55 PacketSocket::PacketSocket () : m_rxAvailable (0)
56 {
57  NS_LOG_FUNCTION (this);
59  m_shutdownSend = false;
60  m_shutdownRecv = false;
62  m_isSingleDevice = false;
63  m_device = 0;
64 }
65 
66 void
68 {
69  NS_LOG_FUNCTION (this << node);
70  m_node = node;
71 }
72 
74 {
75  NS_LOG_FUNCTION (this);
76 }
77 
78 void
80 {
81  NS_LOG_FUNCTION (this);
82  m_device = 0;
83 }
84 
87 {
88  NS_LOG_FUNCTION (this);
89  return m_errno;
90 }
91 
94 {
95  NS_LOG_FUNCTION (this);
96  return NS3_SOCK_RAW;
97 }
98 
101 {
102  NS_LOG_FUNCTION (this);
103  return m_node;
104 }
105 
106 int
108 {
109  NS_LOG_FUNCTION (this);
111  address.SetProtocol (0);
112  address.SetAllDevices ();
113  return DoBind (address);
114 }
115 
116 int
118 {
119  NS_LOG_FUNCTION (this);
120  return(Bind());
121 }
122 
123 int
125 {
126  NS_LOG_FUNCTION (this << address);
128  {
130  return -1;
131  }
133  return DoBind (ad);
134 }
135 
136 int
138 {
139  NS_LOG_FUNCTION (this << address);
140  if (m_state == STATE_BOUND ||
142  {
144  return -1;
145  }
146  if (m_state == STATE_CLOSED)
147  {
149  return -1;
150  }
151  Ptr<NetDevice> dev;
152  if (address.IsSingleDevice ())
153  {
154  dev = m_node->GetDevice (address.GetSingleDevice ());
155  }
156  else
157  {
158  dev = 0;
159  }
161  address.GetProtocol (), dev);
163  m_protocol = address.GetProtocol ();
164  m_isSingleDevice = address.IsSingleDevice ();
165  m_device = address.GetSingleDevice ();
166  m_boundnetdevice = dev;
167  return 0;
168 }
169 
170 int
172 {
173  NS_LOG_FUNCTION (this);
174  if (m_state == STATE_CLOSED)
175  {
177  return -1;
178  }
179  m_shutdownSend = true;
180  return 0;
181 }
182 
183 int
185 {
186  NS_LOG_FUNCTION (this);
187  if (m_state == STATE_CLOSED)
188  {
190  return -1;
191  }
192  m_shutdownRecv = true;
193  return 0;
194 }
195 
196 int
198 {
199  NS_LOG_FUNCTION (this);
200  if (m_state == STATE_CLOSED)
201  {
203  return -1;
204  }
205  else if (m_state == STATE_BOUND || m_state == STATE_CONNECTED)
206  {
208  }
210  m_shutdownSend = true;
211  m_shutdownRecv = true;
212  return 0;
213 }
214 
215 int
217 {
218  NS_LOG_FUNCTION (this << ad);
220  if (m_state == STATE_CLOSED)
221  {
223  goto error;
224  }
225  if (m_state == STATE_OPEN)
226  {
227  // connect should happen _after_ bind.
228  m_errno = ERROR_INVAL; // generic error condition.
229  goto error;
230  }
231  if (m_state == STATE_CONNECTED)
232  {
234  goto error;
235  }
237  {
239  goto error;
240  }
241  m_destAddr = ad;
244  return 0;
245 error:
247  return -1;
248 }
249 int
251 {
252  NS_LOG_FUNCTION (this);
254  return -1;
255 }
256 
257 int
258 PacketSocket::Send (Ptr<Packet> p, uint32_t flags)
259 {
260  NS_LOG_FUNCTION (this << p << flags);
261  if (m_state == STATE_OPEN ||
262  m_state == STATE_BOUND)
263  {
265  return -1;
266  }
267  return SendTo (p, flags, m_destAddr);
268 }
269 
270 uint32_t
272 {
273  NS_LOG_FUNCTION (this << ad);
274  if (ad.IsSingleDevice ())
275  {
277  return device->GetMtu ();
278  }
279  else
280  {
281  uint32_t minMtu = 0xffff;
282  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
283  {
284  Ptr<NetDevice> device = m_node->GetDevice (i);
285  minMtu = std::min (minMtu, (uint32_t)device->GetMtu ());
286  }
287  return minMtu;
288  }
289 }
290 
291 uint32_t
293 {
294  NS_LOG_FUNCTION (this);
295  if (m_state == STATE_CONNECTED)
296  {
298  return GetMinMtu (ad);
299  }
300  // If we are not connected, we return a 'safe' value by default.
301  return 0xffff;
302 }
303 
304 int
305 PacketSocket::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
306 {
307  NS_LOG_FUNCTION (this << p << flags << address);
309  if (m_state == STATE_CLOSED)
310  {
311  NS_LOG_LOGIC ("ERROR_BADF");
313  return -1;
314  }
315  if (m_shutdownSend)
316  {
317  NS_LOG_LOGIC ("ERROR_SHUTDOWN");
319  return -1;
320  }
322  {
323  NS_LOG_LOGIC ("ERROR_AFNOSUPPORT");
325  return -1;
326  }
327  ad = PacketSocketAddress::ConvertFrom (address);
328  if (p->GetSize () > GetMinMtu (ad))
329  {
331  return -1;
332  }
333 
334  bool error = false;
335  Address dest = ad.GetPhysicalAddress ();
336  if (ad.IsSingleDevice ())
337  {
339  if (!device->Send (p, dest, ad.GetProtocol ()))
340  {
341  NS_LOG_LOGIC ("error: NetDevice::Send error");
342  error = true;
343  }
344  }
345  else
346  {
347  for (uint32_t i = 0; i < m_node->GetNDevices (); i++)
348  {
349  Ptr<NetDevice> device = m_node->GetDevice (i);
350  if (!device->Send (p, dest, ad.GetProtocol ()))
351  {
352  NS_LOG_LOGIC ("error: NetDevice::Send error");
353  error = true;
354  }
355  }
356  }
357  if (!error)
358  {
359  NotifyDataSent (p->GetSize ());
361  }
362 
363  if (error)
364  {
365  NS_LOG_LOGIC ("ERROR_INVAL 2");
367  return -1;
368  }
369  else
370  {
371  return p->GetSize ();
372  }
373 }
374 
375 void
377  uint16_t protocol, const Address &from,
378  const Address &to, NetDevice::PacketType packetType)
379 {
380  NS_LOG_FUNCTION (this << device << packet << protocol << from << to << packetType);
381  if (m_shutdownRecv)
382  {
383  return;
384  }
386  address.SetPhysicalAddress (from);
387  address.SetSingleDevice (device->GetIfIndex ());
388  address.SetProtocol (protocol);
389 
390  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
391  {
392  Ptr<Packet> copy = packet->Copy ();
393  DeviceNameTag dnt;
394  dnt.SetDeviceName (device->GetTypeId ().GetName ());
395  PacketSocketTag pst;
396  pst.SetPacketType (packetType);
397  pst.SetDestAddress (to);
398  SocketAddressTag tag;
399  tag.SetAddress (address);
400  copy->AddPacketTag (tag); // Attach From Physical Address
401  copy->AddPacketTag (pst); // Attach Packet Type and Dest Address
402  copy->AddPacketTag (dnt); // Attach device source name
403  m_deliveryQueue.push (copy);
404  m_rxAvailable += packet->GetSize ();
405  NS_LOG_LOGIC ("UID is " << packet->GetUid () << " PacketSocket " << this);
406  NotifyDataRecv ();
407  }
408  else
409  {
410  // In general, this case should not occur unless the
411  // receiving application reads data from this socket slowly
412  // in comparison to the arrival rate
413  //
414  // drop and trace packet
415  NS_LOG_WARN ("No receive buffer space available. Drop.");
416  m_dropTrace (packet);
417  }
418 }
419 
420 uint32_t
422 {
423  NS_LOG_FUNCTION (this);
424  // We separately maintain this state to avoid walking the queue
425  // every time this might be called
426  return m_rxAvailable;
427 }
428 
430 PacketSocket::Recv (uint32_t maxSize, uint32_t flags)
431 {
432  NS_LOG_FUNCTION (this << maxSize << flags);
433  if (m_deliveryQueue.empty () )
434  {
435  return 0;
436  }
437  Ptr<Packet> p = m_deliveryQueue.front ();
438  if (p->GetSize () <= maxSize)
439  {
440  m_deliveryQueue.pop ();
441  m_rxAvailable -= p->GetSize ();
442  }
443  else
444  {
445  p = 0;
446  }
447  return p;
448 }
449 
451 PacketSocket::RecvFrom (uint32_t maxSize, uint32_t flags, Address &fromAddress)
452 {
453  NS_LOG_FUNCTION (this << maxSize << flags << fromAddress);
454  Ptr<Packet> packet = Recv (maxSize, flags);
455  if (packet != 0)
456  {
457  SocketAddressTag tag;
458  bool found;
459  found = packet->PeekPacketTag (tag);
460  NS_ASSERT (found);
461  fromAddress = tag.GetAddress ();
462  }
463  return packet;
464 }
465 
466 int
468 {
469  NS_LOG_FUNCTION (this << address);
471 
472  ad.SetProtocol (m_protocol);
473  if (m_isSingleDevice)
474  {
476  ad.SetPhysicalAddress (device->GetAddress ());
478  }
479  else
480  {
481  ad.SetPhysicalAddress (Address ());
482  ad.SetAllDevices ();
483  }
484  address = ad;
485 
486  return 0;
487 }
488 
489 bool
490 PacketSocket::SetAllowBroadcast (bool allowBroadcast)
491 {
492  NS_LOG_FUNCTION (this << allowBroadcast);
493  if (allowBroadcast)
494  {
495  return false;
496  }
497  return true;
498 }
499 
500 bool
502 {
503  NS_LOG_FUNCTION (this);
504  return false;
505 }
506 
507 /***************************************************************
508  * PacketSocket Tags
509  ***************************************************************/
510 
512 {
513 }
514 
515 void
517 {
518  m_packetType = t;
519 }
520 
523 {
524  return m_packetType;
525 }
526 
527 void
529 {
530  m_destAddr = a;
531 }
532 
533 Address
535 {
536  return m_destAddr;
537 }
538 
540 
541 TypeId
543 {
544  static TypeId tid = TypeId ("ns3::PacketSocketTag")
545  .SetParent<Tag> ()
546  .AddConstructor<PacketSocketTag> ()
547  ;
548  return tid;
549 }
550 TypeId
552 {
553  return GetTypeId ();
554 }
555 uint32_t
557 {
558  return 1 + m_destAddr.GetSerializedSize();
559 }
560 void
562 {
563  i.WriteU8 (m_packetType);
564  m_destAddr.Serialize (i);
565 }
566 void
568 {
571 }
572 void
573 PacketSocketTag::Print (std::ostream &os) const
574 {
575  os << "packetType=" << m_packetType;
576 }
577 
578 /***************************************************************
579  * DeviceName Tags
580  ***************************************************************/
581 
583 {
584 }
585 
586 void
588 {
589  if ( n.substr(0,5) == "ns3::" )
590  {
591  n = n.substr (5);
592  }
593  m_deviceName = n;
594 }
595 
596 std::string
598 {
599  return m_deviceName;
600 }
601 
603 
604 TypeId
606 {
607  static TypeId tid = TypeId ("ns3::DeviceNameTag")
608  .SetParent<Tag> ()
609  .AddConstructor<DeviceNameTag> ();
610  return tid;
611 }
612 TypeId
614 {
615  return GetTypeId ();
616 }
617 uint32_t
619 {
620  uint32_t s = 1 + m_deviceName.size(); // +1 for name length field
621  s = std::min (s, (uint32_t)PacketTagList::TagData::MAX_SIZE);
622  return s;
623 }
624 void
626 {
627  const char *n = m_deviceName.c_str();
628  uint8_t l = (uint8_t) m_deviceName.size ();
629 
630  l = std::min ((uint32_t)l, (uint32_t)PacketTagList::TagData::MAX_SIZE - 1);
631 
632  i.WriteU8 (l);
633  i.Write ( (uint8_t*) n , (uint32_t) l);
634 }
635 void
637 {
638  uint8_t l = i.ReadU8();
639  char buf[256];
640 
641  i.Read ( (uint8_t* ) buf, (uint32_t) l);
642  m_deviceName = std::string (buf, l);
643 }
644 void
645 DeviceNameTag::Print (std::ostream &os) const
646 {
647  os << "DeviceName=" << m_deviceName;
648 }
649 
650 
651 } // namespace ns3
static TypeId GetTypeId(void)
Get the type ID.
uint16_t GetProtocol(void) const
Get the protocol.
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 "...
std::string m_deviceName
Device name.
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
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:841
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:393
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
static bool IsMatchingType(const Address &address)
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
virtual void DoDispose(void)
This method is called by Object::Dispose or by the object's destructor, whichever comes first...
uint32_t GetSize(void) const
Returns the the size in bytes of the packet (including the zero-filled initial payload).
Definition: packet.h:744
void SetAllDevices(void)
Set the address to match all the outgoing NetDevice.
virtual uint32_t GetSerializedSize(void) const
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.
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
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:86
virtual TypeId GetInstanceTypeId(void) const
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:863
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:46
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
Definition: node.cc:134
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:948
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
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:233
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
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.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
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.
Size of serialization buffer data.
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:911
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:203
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
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
PacketType
Packet types are used as they are in Linux.
Definition: net-device.h:274
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)
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
a unique identifier for an interface.
Definition: type-id.h:49
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:610
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.