A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
udp-socket-impl.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2007 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  * Author: Mathieu Lacage <mathieu.lacage@sophia.inria.fr>
19  */
20 
21 #include "ns3/log.h"
22 #include "ns3/node.h"
23 #include "ns3/inet-socket-address.h"
24 #include "ns3/inet6-socket-address.h"
25 #include "ns3/ipv4-route.h"
26 #include "ns3/ipv6-route.h"
27 #include "ns3/ipv4.h"
28 #include "ns3/ipv6.h"
29 #include "ns3/ipv4-header.h"
30 #include "ns3/ipv4-routing-protocol.h"
31 #include "ns3/ipv6-routing-protocol.h"
32 #include "ns3/udp-socket-factory.h"
33 #include "ns3/trace-source-accessor.h"
34 #include "ns3/ipv4-packet-info-tag.h"
35 #include "udp-socket-impl.h"
36 #include "udp-l4-protocol.h"
37 #include "ipv4-end-point.h"
38 #include "ipv6-end-point.h"
39 #include <limits>
40 
41 NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl");
42 
43 namespace ns3 {
44 
45 NS_OBJECT_ENSURE_REGISTERED (UdpSocketImpl);
46 
47 static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507;
48 
49 // Add attributes generic to all UdpSockets to base class UdpSocket
50 TypeId
52 {
53  static TypeId tid = TypeId ("ns3::UdpSocketImpl")
54  .SetParent<UdpSocket> ()
55  .AddConstructor<UdpSocketImpl> ()
56  .AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
58  .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
59  CallbackValue (),
60  MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback),
61  MakeCallbackChecker ())
62  .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
63  CallbackValue (),
64  MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback6),
65  MakeCallbackChecker ())
66  ;
67  return tid;
68 }
69 
71  : m_endPoint (0),
72  m_endPoint6 (0),
73  m_node (0),
74  m_udp (0),
75  m_errno (ERROR_NOTERROR),
76  m_shutdownSend (false),
77  m_shutdownRecv (false),
78  m_connected (false),
79  m_rxAvailable (0)
80 {
82  m_allowBroadcast = false;
83 }
84 
86 {
88 
90  m_node = 0;
96  if (m_endPoint != 0)
97  {
98  NS_ASSERT (m_udp != 0);
107  NS_ASSERT (m_endPoint != 0);
108  m_udp->DeAllocate (m_endPoint);
109  NS_ASSERT (m_endPoint == 0);
110  }
111  if (m_endPoint6 != 0)
112  {
113  NS_ASSERT (m_udp != 0);
122  NS_ASSERT (m_endPoint6 != 0);
123  m_udp->DeAllocate (m_endPoint6);
124  NS_ASSERT (m_endPoint6 == 0);
125  }
126  m_udp = 0;
127 }
128 
129 void
131 {
133  m_node = node;
134 
135 }
136 void
138 {
140  m_udp = udp;
141 }
142 
143 
146 {
148  return m_errno;
149 }
150 
153 {
154  return NS3_SOCK_DGRAM;
155 }
156 
157 Ptr<Node>
159 {
161  return m_node;
162 }
163 
164 void
166 {
168  m_endPoint = 0;
169 }
170 
171 void
173 {
175  m_endPoint6 = 0;
176 }
177 
178 int
180 {
182  bool done = false;
183  if (m_endPoint != 0)
184  {
188  done = true;
189  }
190  if (m_endPoint6 != 0)
191  {
195  done = true;
196  }
197  if (done)
198  {
199  return 0;
200  }
201  return -1;
202 }
203 
204 int
206 {
208  m_endPoint = m_udp->Allocate ();
209  return FinishBind ();
210 }
211 
212 int
214 {
216  m_endPoint6 = m_udp->Allocate6 ();
217  return FinishBind ();
218 }
219 
220 int
222 {
223  NS_LOG_FUNCTION (this << address);
224 
225  if (InetSocketAddress::IsMatchingType (address))
226  {
228  Ipv4Address ipv4 = transport.GetIpv4 ();
229  uint16_t port = transport.GetPort ();
230  if (ipv4 == Ipv4Address::GetAny () && port == 0)
231  {
232  m_endPoint = m_udp->Allocate ();
233  }
234  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
235  {
236  m_endPoint = m_udp->Allocate (port);
237  }
238  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
239  {
240  m_endPoint = m_udp->Allocate (ipv4);
241  }
242  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
243  {
244  m_endPoint = m_udp->Allocate (ipv4, port);
245  }
246  }
247  else if (Inet6SocketAddress::IsMatchingType (address))
248  {
250  Ipv6Address ipv6 = transport.GetIpv6 ();
251  uint16_t port = transport.GetPort ();
252  if (ipv6 == Ipv6Address::GetAny () && port == 0)
253  {
254  m_endPoint6 = m_udp->Allocate6 ();
255  }
256  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
257  {
258  m_endPoint6 = m_udp->Allocate6 (port);
259  }
260  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
261  {
262  m_endPoint6 = m_udp->Allocate6 (ipv6);
263  }
264  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
265  {
266  m_endPoint6 = m_udp->Allocate6 (ipv6, port);
267  }
268  }
269  else
270  {
271  NS_LOG_ERROR ("Not IsMatchingType");
273  return -1;
274  }
275 
276  return FinishBind ();
277 }
278 
279 int
281 {
283  m_shutdownSend = true;
284  return 0;
285 }
286 
287 int
289 {
291  m_shutdownRecv = true;
292  return 0;
293 }
294 
295 int
297 {
299  if (m_shutdownRecv == true && m_shutdownSend == true)
300  {
302  return -1;
303  }
304  m_shutdownRecv = true;
305  m_shutdownSend = true;
306  return 0;
307 }
308 
309 int
311 {
312  NS_LOG_FUNCTION (this << address);
313  if (InetSocketAddress::IsMatchingType(address) == true)
314  {
316  m_defaultAddress = Address(transport.GetIpv4 ());
317  m_defaultPort = transport.GetPort ();
318  m_connected = true;
320  }
321  else if (Inet6SocketAddress::IsMatchingType(address) == true)
322  {
324  m_defaultAddress = Address(transport.GetIpv6 ());
325  m_defaultPort = transport.GetPort ();
326  m_connected = true;
328  }
329  else
330  {
331  return -1;
332  }
333 
334  return 0;
335 }
336 
337 int
339 {
341  return -1;
342 }
343 
344 int
345 UdpSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
346 {
347  NS_LOG_FUNCTION (this << p << flags);
348 
349  if (!m_connected)
350  {
352  return -1;
353  }
354 
355  return DoSend (p);
356 }
357 
358 int
360 {
361  NS_LOG_FUNCTION (this << p);
363  {
364  if (Bind () == -1)
365  {
366  NS_ASSERT (m_endPoint == 0);
367  return -1;
368  }
369  NS_ASSERT (m_endPoint != 0);
370  }
372  {
373  if (Bind6 () == -1)
374  {
375  NS_ASSERT (m_endPoint6 == 0);
376  return -1;
377  }
378  NS_ASSERT (m_endPoint6 != 0);
379  }
380  if (m_shutdownSend)
381  {
383  return -1;
384  }
385 
386  return DoSendTo (p, (const Address)m_defaultAddress);
387 }
388 
389 int
391 {
392  NS_LOG_FUNCTION (this << p << address);
393 
394  if (!m_connected)
395  {
396  NS_LOG_LOGIC ("Not connected");
397  if (InetSocketAddress::IsMatchingType(address) == true)
398  {
400  Ipv4Address ipv4 = transport.GetIpv4 ();
401  uint16_t port = transport.GetPort ();
402  return DoSendTo (p, ipv4, port);
403  }
404  else if (Inet6SocketAddress::IsMatchingType(address) == true)
405  {
407  Ipv6Address ipv6 = transport.GetIpv6 ();
408  uint16_t port = transport.GetPort ();
409  return DoSendTo (p, ipv6, port);
410  }
411  else
412  {
413  return -1;
414  }
415  }
416  else
417  {
418  // connected UDP socket must use default addresses
419  NS_LOG_LOGIC ("Connected");
421  {
423  }
425  {
427  }
428  }
430  return(-1);
431 }
432 
433 int
435 {
436  NS_LOG_FUNCTION (this << p << dest << port);
437  if (m_boundnetdevice)
438  {
439  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
440  }
441  if (m_endPoint == 0)
442  {
443  if (Bind () == -1)
444  {
445  NS_ASSERT (m_endPoint == 0);
446  return -1;
447  }
448  NS_ASSERT (m_endPoint != 0);
449  }
450  if (m_shutdownSend)
451  {
453  return -1;
454  }
455 
456  if (p->GetSize () > GetTxAvailable () )
457  {
459  return -1;
460  }
461 
462  if (IsManualIpTos ())
463  {
464  SocketIpTosTag ipTosTag;
465  ipTosTag.SetTos (GetIpTos ());
466  p->AddPacketTag (ipTosTag);
467  }
468 
469  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
470 
471  // Locally override the IP TTL for this socket
472  // We cannot directly modify the TTL at this stage, so we set a Packet tag
473  // The destination can be either multicast, unicast/anycast, or
474  // either all-hosts broadcast or limited (subnet-directed) broadcast.
475  // For the latter two broadcast types, the TTL will later be set to one
476  // irrespective of what is set in these socket options. So, this tagging
477  // may end up setting the TTL of a limited broadcast packet to be
478  // the same as a unicast, but it will be fixed further down the stack
479  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
480  {
481  SocketIpTtlTag tag;
482  tag.SetTtl (m_ipMulticastTtl);
483  p->AddPacketTag (tag);
484  }
485  else if (IsManualIpTtl () && GetIpTtl () != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
486  {
487  SocketIpTtlTag tag;
488  tag.SetTtl (GetIpTtl ());
489  p->AddPacketTag (tag);
490  }
491  {
493  bool found = p->RemovePacketTag (tag);
494  if (!found)
495  {
496  if (m_mtuDiscover)
497  {
498  tag.Enable ();
499  }
500  else
501  {
502  tag.Disable ();
503  }
504  p->AddPacketTag (tag);
505  }
506  }
507  //
508  // If dest is set to the limited broadcast address (all ones),
509  // convert it to send a copy of the packet out of every
510  // interface as a subnet-directed broadcast.
511  // Exception: if the interface has a /32 address, there is no
512  // valid subnet-directed broadcast, so send it as limited broadcast
513  // Note also that some systems will only send limited broadcast packets
514  // out of the "default" interface; here we send it out all interfaces
515  //
516  if (dest.IsBroadcast ())
517  {
518  if (!m_allowBroadcast)
519  {
521  return -1;
522  }
523  NS_LOG_LOGIC ("Limited broadcast start.");
524  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
525  {
526  // Get the primary address
527  Ipv4InterfaceAddress iaddr = ipv4->GetAddress (i, 0);
528  Ipv4Address addri = iaddr.GetLocal ();
529  if (addri == Ipv4Address ("127.0.0.1"))
530  continue;
531  // Check if interface-bound socket
532  if (m_boundnetdevice)
533  {
534  if (ipv4->GetNetDevice (i) != m_boundnetdevice)
535  continue;
536  }
537  Ipv4Mask maski = iaddr.GetMask ();
538  if (maski == Ipv4Mask::GetOnes ())
539  {
540  // if the network mask is 255.255.255.255, do not convert dest
541  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest
542  << " (mask is " << maski << ")");
543  m_udp->Send (p->Copy (), addri, dest,
545  NotifyDataSent (p->GetSize ());
547  }
548  else
549  {
550  // Convert to subnet-directed broadcast
551  Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
552  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
553  << " (mask is " << maski << ")");
554  m_udp->Send (p->Copy (), addri, bcast,
556  NotifyDataSent (p->GetSize ());
558  }
559  }
560  NS_LOG_LOGIC ("Limited broadcast end.");
561  return p->GetSize ();
562  }
564  {
565  m_udp->Send (p->Copy (), m_endPoint->GetLocalAddress (), dest,
566  m_endPoint->GetLocalPort (), port, 0);
567  NotifyDataSent (p->GetSize ());
569  return p->GetSize ();
570  }
571  else if (ipv4->GetRoutingProtocol () != 0)
572  {
573  Ipv4Header header;
574  header.SetDestination (dest);
576  Socket::SocketErrno errno_;
577  Ptr<Ipv4Route> route;
578  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
579  // TBD-- we could cache the route and just check its validity
580  route = ipv4->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
581  if (route != 0)
582  {
583  NS_LOG_LOGIC ("Route exists");
584  if (!m_allowBroadcast)
585  {
586  uint32_t outputIfIndex = ipv4->GetInterfaceForDevice (route->GetOutputDevice ());
587  uint32_t ifNAddr = ipv4->GetNAddresses (outputIfIndex);
588  for (uint32_t addrI = 0; addrI < ifNAddr; ++addrI)
589  {
590  Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (outputIfIndex, addrI);
591  if (dest == ifAddr.GetBroadcast ())
592  {
594  return -1;
595  }
596  }
597  }
598 
599  header.SetSource (route->GetSource ());
600  m_udp->Send (p->Copy (), header.GetSource (), header.GetDestination (),
601  m_endPoint->GetLocalPort (), port, route);
602  NotifyDataSent (p->GetSize ());
603  return p->GetSize ();
604  }
605  else
606  {
607  NS_LOG_LOGIC ("No route to destination");
608  NS_LOG_ERROR (errno_);
609  m_errno = errno_;
610  return -1;
611  }
612  }
613  else
614  {
615  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
617  return -1;
618  }
619 
620  return 0;
621 }
622 
623 int
625 {
626  NS_LOG_FUNCTION (this << p << dest << port);
627 
628  if (dest.IsIpv4MappedAddress ())
629  {
630  return (DoSendTo(p, dest.GetIpv4MappedAddress (), port));
631  }
632  if (m_boundnetdevice)
633  {
634  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
635  }
636  if (m_endPoint6 == 0)
637  {
638  if (Bind6 () == -1)
639  {
640  NS_ASSERT (m_endPoint6 == 0);
641  return -1;
642  }
643  NS_ASSERT (m_endPoint6 != 0);
644  }
645  if (m_shutdownSend)
646  {
648  return -1;
649  }
650 
651  if (p->GetSize () > GetTxAvailable () )
652  {
654  return -1;
655  }
656 
657  if (IsManualIpv6Tclass ())
658  {
659  SocketIpv6TclassTag ipTclassTag;
660  ipTclassTag.SetTclass (GetIpv6Tclass ());
661  p->AddPacketTag (ipTclassTag);
662  }
663 
664  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
665 
666  // Locally override the IP TTL for this socket
667  // We cannot directly modify the TTL at this stage, so we set a Packet tag
668  // The destination can be either multicast, unicast/anycast, or
669  // either all-hosts broadcast or limited (subnet-directed) broadcast.
670  // For the latter two broadcast types, the TTL will later be set to one
671  // irrespective of what is set in these socket options. So, this tagging
672  // may end up setting the TTL of a limited broadcast packet to be
673  // the same as a unicast, but it will be fixed further down the stack
674  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
675  {
678  p->AddPacketTag (tag);
679  }
680  else if (IsManualIpv6HopLimit () && GetIpv6HopLimit () != 0 && !dest.IsMulticast ())
681  {
683  tag.SetHopLimit (GetIpv6HopLimit ());
684  p->AddPacketTag (tag);
685  }
686  // There is no analgous to an IPv4 broadcast address in IPv6.
687  // Instead, we use a set of link-local, site-local, and global
688  // multicast addresses. The Ipv6 routing layers should all
689  // provide an interface-specific route to these addresses such
690  // that we can treat these multicast addresses as "not broadcast"
691 
693  {
694  m_udp->Send (p->Copy (), m_endPoint6->GetLocalAddress (), dest,
695  m_endPoint6->GetLocalPort (), port, 0);
696  NotifyDataSent (p->GetSize ());
698  return p->GetSize ();
699  }
700  else if (ipv6->GetRoutingProtocol () != 0)
701  {
702  Ipv6Header header;
703  header.SetDestinationAddress (dest);
705  Socket::SocketErrno errno_;
706  Ptr<Ipv6Route> route;
707  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
708  // TBD-- we could cache the route and just check its validity
709  route = ipv6->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
710  if (route != 0)
711  {
712  NS_LOG_LOGIC ("Route exists");
713  header.SetSourceAddress (route->GetSource ());
714  m_udp->Send (p->Copy (), header.GetSourceAddress (), header.GetDestinationAddress (),
715  m_endPoint6->GetLocalPort (), port, route);
716  NotifyDataSent (p->GetSize ());
717  return p->GetSize ();
718  }
719  else
720  {
721  NS_LOG_LOGIC ("No route to destination");
722  NS_LOG_ERROR (errno_);
723  m_errno = errno_;
724  return -1;
725  }
726  }
727  else
728  {
729  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
731  return -1;
732  }
733 
734  return 0;
735 }
736 
737 
738 // maximum message size for UDP broadcast is limited by MTU
739 // size of underlying link; we are not checking that now.
741 uint32_t
743 {
745  // No finite send buffer is modelled, but we must respect
746  // the maximum size of an IP datagram (65535 bytes - headers).
748 }
749 
750 int
752 {
753  NS_LOG_FUNCTION (this << p << flags << address);
754  if (InetSocketAddress::IsMatchingType (address))
755  {
756  if (IsManualIpTos ())
757  {
758  SocketIpTosTag ipTosTag;
759  ipTosTag.SetTos (GetIpTos ());
760  p->AddPacketTag (ipTosTag);
761  }
762 
764  Ipv4Address ipv4 = transport.GetIpv4 ();
765  uint16_t port = transport.GetPort ();
766  return DoSendTo (p, ipv4, port);
767  }
768  else if (Inet6SocketAddress::IsMatchingType (address))
769  {
770  if (IsManualIpv6Tclass ())
771  {
772  SocketIpv6TclassTag ipTclassTag;
773  ipTclassTag.SetTclass (GetIpv6Tclass ());
774  p->AddPacketTag (ipTclassTag);
775  }
776 
778  Ipv6Address ipv6 = transport.GetIpv6 ();
779  uint16_t port = transport.GetPort ();
780  return DoSendTo (p, ipv6, port);
781  }
782  return -1;
783 }
784 
785 uint32_t
787 {
789  // We separately maintain this state to avoid walking the queue
790  // every time this might be called
791  return m_rxAvailable;
792 }
793 
795 UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
796 {
797  NS_LOG_FUNCTION (this << maxSize << flags);
798  if (m_deliveryQueue.empty () )
799  {
801  return 0;
802  }
803  Ptr<Packet> p = m_deliveryQueue.front ();
804  if (p->GetSize () <= maxSize)
805  {
806  m_deliveryQueue.pop ();
807  m_rxAvailable -= p->GetSize ();
808  }
809  else
810  {
811  p = 0;
812  }
813  return p;
814 }
815 
817 UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
818  Address &fromAddress)
819 {
820  NS_LOG_FUNCTION (this << maxSize << flags);
821  Ptr<Packet> packet = Recv (maxSize, flags);
822  if (packet != 0)
823  {
824  SocketAddressTag tag;
825  bool found;
826  found = packet->PeekPacketTag (tag);
827  NS_ASSERT (found);
828  fromAddress = tag.GetAddress ();
829  }
830  return packet;
831 }
832 
833 int
835 {
837  if (m_endPoint != 0)
838  {
840  }
841  else
842  {
843  // It is possible to call this method on a socket without a name
844  // in which case, behavior is unspecified
845  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
846  }
847  return 0;
848 }
849 
850 int
851 UdpSocketImpl::MulticastJoinGroup (uint32_t interface, const Address &groupAddress)
852 {
853  NS_LOG_FUNCTION (interface << groupAddress);
854  /*
855  1) sanity check interface
856  2) sanity check that it has not been called yet on this interface/group
857  3) determine address family of groupAddress
858  4) locally store a list of (interface, groupAddress)
859  5) call ipv4->MulticastJoinGroup () or Ipv6->MulticastJoinGroup ()
860  */
861  return 0;
862 }
863 
864 int
865 UdpSocketImpl::MulticastLeaveGroup (uint32_t interface, const Address &groupAddress)
866 {
867  NS_LOG_FUNCTION (interface << groupAddress);
868  /*
869  1) sanity check interface
870  2) determine address family of groupAddress
871  3) delete from local list of (interface, groupAddress); raise a LOG_WARN
872  if not already present (but return 0)
873  5) call ipv4->MulticastLeaveGroup () or Ipv6->MulticastLeaveGroup ()
874  */
875  return 0;
876 }
877 
878 void
880 {
881  NS_LOG_FUNCTION (netdevice);
882  Socket::BindToNetDevice (netdevice); // Includes sanity check
883  if (m_endPoint == 0)
884  {
885  if (Bind () == -1)
886  {
887  NS_ASSERT (m_endPoint == 0);
888  return;
889  }
890  NS_ASSERT (m_endPoint != 0);
891  }
892  m_endPoint->BindToNetDevice (netdevice);
893  return;
894 }
895 
896 void
898  Ptr<Ipv4Interface> incomingInterface)
899 {
900  NS_LOG_FUNCTION (this << packet << header << port);
901 
902  if (m_shutdownRecv)
903  {
904  return;
905  }
906 
907  // Should check via getsockopt ()..
908  if (IsRecvPktInfo ())
909  {
910  Ipv4PacketInfoTag tag;
911  packet->RemovePacketTag (tag);
912  tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ());
913  packet->AddPacketTag (tag);
914  }
915 
916  //Check only version 4 options
917  if (IsIpRecvTos ())
918  {
919  SocketIpTosTag ipTosTag;
920  ipTosTag.SetTos (header.GetTos ());
921  packet->AddPacketTag (ipTosTag);
922  }
923 
924  if (IsIpRecvTtl ())
925  {
926  SocketIpTtlTag ipTtlTag;
927  ipTtlTag.SetTtl (header.GetTtl ());
928  packet->AddPacketTag (ipTtlTag);
929  }
930 
931  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
932  {
934  SocketAddressTag tag;
935  tag.SetAddress (address);
936  packet->AddPacketTag (tag);
937  m_deliveryQueue.push (packet);
938  m_rxAvailable += packet->GetSize ();
939  NotifyDataRecv ();
940  }
941  else
942  {
943  // In general, this case should not occur unless the
944  // receiving application reads data from this socket slowly
945  // in comparison to the arrival rate
946  //
947  // drop and trace packet
948  NS_LOG_WARN ("No receive buffer space available. Drop.");
949  m_dropTrace (packet);
950  }
951 }
952 
953 void
955 {
956  NS_LOG_FUNCTION (this << packet << header.GetSourceAddress () << port);
957 
958  if (m_shutdownRecv)
959  {
960  return;
961  }
962 
963 
964  //Check only version 6 options
965  if (IsIpv6RecvTclass ())
966  {
967  SocketIpv6TclassTag ipTclassTag;
968  ipTclassTag.SetTclass (header.GetTrafficClass ());
969  packet->AddPacketTag (ipTclassTag);
970  }
971 
972  if (IsIpv6RecvHopLimit ())
973  {
974  SocketIpv6HopLimitTag ipHopLimitTag;
975  ipHopLimitTag.SetHopLimit (header.GetHopLimit ());
976  packet->AddPacketTag (ipHopLimitTag);
977  }
978 
979  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
980  {
982  SocketAddressTag tag;
983  tag.SetAddress (address);
984  packet->AddPacketTag (tag);
985  m_deliveryQueue.push (packet);
986  m_rxAvailable += packet->GetSize ();
987  NotifyDataRecv ();
988  }
989  else
990  {
991  // In general, this case should not occur unless the
992  // receiving application reads data from this socket slowly
993  // in comparison to the arrival rate
994  //
995  // drop and trace packet
996  NS_LOG_WARN ("No receive buffer space available. Drop.");
997  m_dropTrace (packet);
998  }
999 }
1000 
1001 void
1002 UdpSocketImpl::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
1003  uint8_t icmpType, uint8_t icmpCode,
1004  uint32_t icmpInfo)
1005 {
1006  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
1007  (uint32_t)icmpCode << icmpInfo);
1008  if (!m_icmpCallback.IsNull ())
1009  {
1010  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1011  }
1012 }
1013 
1014 void
1015 UdpSocketImpl::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
1016  uint8_t icmpType, uint8_t icmpCode,
1017  uint32_t icmpInfo)
1018 {
1019  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
1020  (uint32_t)icmpCode << icmpInfo);
1021  if (!m_icmpCallback6.IsNull ())
1022  {
1023  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1024  }
1025 }
1026 
1027 void
1029 {
1030  m_rcvBufSize = size;
1031 }
1032 
1033 uint32_t
1035 {
1036  return m_rcvBufSize;
1037 }
1038 
1039 void
1041 {
1042  m_ipMulticastTtl = ipTtl;
1043 }
1044 
1045 uint8_t
1047 {
1048  return m_ipMulticastTtl;
1049 }
1050 
1051 void
1053 {
1054  m_ipMulticastIf = ipIf;
1055 }
1056 
1057 int32_t
1059 {
1060  return m_ipMulticastIf;
1061 }
1062 
1063 void
1065 {
1066  m_ipMulticastLoop = loop;
1067 }
1068 
1069 bool
1071 {
1072  return m_ipMulticastLoop;
1073 }
1074 
1075 void
1077 {
1078  m_mtuDiscover = discover;
1079 }
1080 bool
1082 {
1083  return m_mtuDiscover;
1084 }
1085 
1086 bool
1088 {
1089  m_allowBroadcast = allowBroadcast;
1090  return true;
1091 }
1092 
1093 bool
1095 {
1096  return m_allowBroadcast;
1097 }
1098 
1099 
1100 } // namespace ns3
static bool IsMatchingType(const Address &address)
If the Address matches the type.
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:284
Ipv6Address GetLocalAddress()
Get the local address.
(abstract) base class of all UdpSockets
Definition: udp-socket.h:46
uint8_t GetTrafficClass(void) const
Get the "Traffic class" field.
Definition: ipv6-header.cc:51
void SetTclass(uint8_t tclass)
Definition: socket.cc:816
static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE
static Ipv4Mask GetOnes(void)
Ipv6Address GetIpv6(void) const
Get the IPv6 address.
virtual bool GetAllowBroadcast() const
Query whether broadcast datagram transmissions are allowed.
bool IsManualIpTtl(void) const
Definition: socket.cc:382
Packet header for IPv6.
Definition: ipv6-header.h:33
an Inet address class
Ipv4Address GetIpv4(void) const
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:297
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
Definition: log.h:311
bool IsIpv6RecvHopLimit(void) const
Ask if the socket is currently passing information about IPv6 Hop Limit up the stack.
Definition: socket.cc:507
Ptr< UdpL4Protocol > m_udp
virtual bool GetIpMulticastLoop(void) const
virtual uint8_t GetIpTtl(void) const
Definition: socket.cc:470
Ipv4EndPoint * m_endPoint
uint8_t GetIpTos(void) const
Definition: socket.cc:403
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Definition: socket.h:891
enum SocketErrno m_errno
virtual void SetIpMulticastIf(int32_t ipIf)
Ipv4Address GetLocal(void) const
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:79
void NotifyDataRecv(void)
Definition: socket.cc:304
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:210
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:174
void SetDestroyCallback(Callback< void > callback)
std::queue< Ptr< Packet > > m_deliveryQueue
void AddPacketTag(const Tag &tag) const
Definition: packet.cc:841
void SetAddress(Address addr)
Definition: socket.cc:522
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:303
virtual int Close(void)
Close a socket.
#define NS_ASSERT(condition)
Definition: assert.h:64
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
virtual uint8_t GetIpMulticastTtl(void) const
uint32_t GetSize(void) const
Definition: packet.h:650
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:76
bool IsManualIpTos(void) const
Definition: socket.cc:370
bool IsMulticast(void) const
void BindToNetDevice(Ptr< NetDevice > netdevice)
virtual uint8_t GetIpv6HopLimit(void) const
Definition: socket.cc:495
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:290
#define NS_LOG_FUNCTION_NOARGS()
Definition: log.h:275
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:277
void SetTos(uint8_t tos)
Definition: socket.cc:760
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
This class implements a tag that carries the socket-specific TTL of a packet to the IP layer...
Definition: socket.h:869
virtual void SetRcvBufSize(uint32_t size)
bool IsRecvPktInfo() const
Get status indicating whether enable/disable packet information to socket.
Definition: socket.cc:363
Ipv4Address GetSubnetDirectedBroadcast(Ipv4Mask const &mask) const
Generate subnet-directed broadcast address corresponding to mask.
void ForwardIcmp6(Ipv6Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
uint16_t port
Definition: dsdv-manet.cc:44
a polymophic address class
Definition: address.h:86
virtual int Bind(void)
Allocate a local IPv4 endpoint for this socket.
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
virtual enum SocketErrno GetErrno(void) const
Ptr< NetDevice > GetOutputDevice(void) const
Definition: ipv4-route.cc:84
bool IsIpRecvTos(void) const
Ask if the socket is currently passing information about IP Type of Service up the stack...
Definition: socket.cc:415
Packet header for IPv4.
Definition: ipv4-header.h:31
virtual int ShutdownRecv(void)
virtual int GetSockName(Address &address) const
bool PeekPacketTag(Tag &tag) const
Definition: packet.cc:863
virtual int MulticastLeaveGroup(uint32_t interfaceIndex, const Address &groupAddress)
Corresponds to socket option MCAST_LEAVE_GROUP.
int DoSendTo(Ptr< Packet > p, const Address &daddr)
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback6
void SetTtl(uint8_t ttl)
Definition: socket.cc:582
int DoSend(Ptr< Packet > p)
uint16_t GetLocalPort()
Get the local port.
void SetNode(Ptr< Node > node)
virtual uint32_t GetRcvBufSize(void) const
virtual uint32_t GetRxAvailable(void) const
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
virtual int Connect(const Address &address)
Initiate a connection to a remote host.
virtual int MulticastJoinGroup(uint32_t interfaceIndex, const Address &groupAddress)
Corresponds to socket option MCAST_JOIN_GROUP.
NS_OBJECT_ENSURE_REGISTERED(AntennaModel)
Ipv4Address GetLocalAddress(void)
bool IsBroadcast(void) const
virtual enum SocketType GetSocketType(void) const
An Inet6 address class.
This class implements a tag that carries an address of a packet across the socket interface...
Definition: socket.h:847
virtual void SetMtuDiscover(bool discover)
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1238
virtual int32_t GetIpMulticastIf(void) const
bool IsManualIpv6Tclass(void) const
Definition: socket.cc:376
void NotifyDataSent(uint32_t size)
Definition: socket.cc:284
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
static bool IsMatchingType(const Address &address)
#define NS_LOG_LOGIC(msg)
Definition: log.h:334
void SetHopLimit(uint8_t hopLimit)
Definition: socket.cc:642
static TypeId GetTypeId(void)
void NotifyConnectionSucceeded(void)
Definition: socket.cc:216
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:75
Ptr< Packet > Copy(void) const
Definition: packet.cc:122
bool IsManualIpv6HopLimit(void) const
Definition: socket.cc:388
virtual void SetIpMulticastLoop(bool loop)
uint8_t GetHopLimit(void) const
Get the "Hop limit" field (TTL).
Definition: ipv6-header.cc:91
virtual int Send(Ptr< Packet > p, uint32_t flags)
Send data (or dummy data) to the remote host.
static InetSocketAddress ConvertFrom(const Address &address)
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
void SetIcmpCallback(Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
uint8_t GetIpv6Tclass(void) const
Definition: socket.cc:445
bool IsMulticast() const
If the IPv6 address is multicast (ff00::/8).
static Ipv4Address GetZero(void)
bool IsIpv6RecvTclass(void) const
Ask if the socket is currently passing information about IPv6 Traffic Class up the stack...
Definition: socket.cc:457
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv6Header, uint16_t > callback)
Set the reception callback.
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:329
This class implements Linux struct pktinfo in order to deliver ancillary information to the socket in...
virtual int ShutdownSend(void)
void SetSourceAddress(Ipv6Address src)
Set the "Source address" field.
Definition: ipv6-header.cc:96
bool IsIpRecvTtl(void) const
Ask if the socket is currently passing information about IP_TTL up the stack.
Definition: socket.cc:482
Describes an IPv6 address.
Definition: ipv6-address.h:46
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
virtual uint32_t GetTxAvailable(void) const
Ipv4Address GetBroadcast(void) const
Ptr< NetDevice > m_boundnetdevice
Definition: socket.h:810
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
a class to store IPv4 address information on an interface
uint16_t GetLocalPort(void)
#define NS_LOG_WARN(msg)
Definition: log.h:246
Ptr< NetDevice > GetDevice(void) const
Address GetAddress(void) const
Definition: socket.cc:529
void SetUdp(Ptr< UdpL4Protocol > udp)
virtual int Listen(void)
Listen for incoming connections.
bool RemovePacketTag(Tag &tag)
Definition: packet.cc:848
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
indicated whether packets should be sent out with the DF flag set.
Definition: socket.h:913
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &address)
Send data to a specified peer.
Ipv6EndPoint * m_endPoint6
static bool IsMatchingType(const Address &addr)
If the address match.
uint16_t GetPort(void) const
Get the port.
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
virtual Ptr< Packet > RecvFrom(uint32_t maxSize, uint32_t flags, Address &fromAddress)
Read a single packet from the socket and retrieve the sender address.
void ForwardUp6(Ptr< Packet > p, Ipv6Header header, uint16_t port)
void ForwardUp(Ptr< Packet > p, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
#define NS_LOG_ERROR(msg)
Definition: log.h:237
uint16_t GetPort(void) const
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:264
uint8_t GetTos(void) const
Definition: ipv4-header.cc:194
static Ipv4Address ConvertFrom(const Address &address)
tuple address
Definition: first.py:37
TracedCallback< Ptr< const Packet > > m_dropTrace
Ptr< T > GetObject(void) const
Definition: object.h:360
void SetIcmpCallback(Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
a unique identifier for an interface.
Definition: type-id.h:49
static const uint8_t PROT_NUMBER
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
bool IsIpv4MappedAddress()
If the address is an IPv4-mapped address.
void NotifySend(uint32_t spaceAvailable)
Definition: socket.cc:294
TypeId SetParent(TypeId tid)
Definition: type-id.cc:610
static bool IsMatchingType(const Address &address)
NS_LOG_COMPONENT_DEFINE("UdpSocketImpl")
Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback
Ipv6Address GetDestinationAddress(void) const
Get the "Destination address" field.
Definition: ipv6-header.cc:111
static Ipv6Address ConvertFrom(const Address &address)
Convert the Address object into an Ipv6Address ones.
virtual bool GetMtuDiscover(void) const
virtual void SetIpMulticastTtl(uint8_t ipTtl)
virtual Ptr< Node > GetNode(void) const
void SetRecvIf(uint32_t ifindex)