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 "ns3/ipv6-packet-info-tag.h"
36 #include "udp-socket-impl.h"
37 #include "udp-l4-protocol.h"
38 #include "ipv4-end-point.h"
39 #include "ipv6-end-point.h"
40 #include <limits>
41 
42 NS_LOG_COMPONENT_DEFINE ("UdpSocketImpl");
43 
44 namespace ns3 {
45 
46 NS_OBJECT_ENSURE_REGISTERED (UdpSocketImpl);
47 
48 // The correct maximum UDP message size is 65507, as determined by the following formula:
49 // 0xffff - (sizeof(IP Header) + sizeof(UDP Header)) = 65535-(20+8) = 65507
50 // \todo MAX_IPV4_UDP_DATAGRAM_SIZE is correct only for IPv4
51 static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507;
52 
53 // Add attributes generic to all UdpSockets to base class UdpSocket
54 TypeId
56 {
57  static TypeId tid = TypeId ("ns3::UdpSocketImpl")
58  .SetParent<UdpSocket> ()
59  .AddConstructor<UdpSocketImpl> ()
60  .AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
62  .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
63  CallbackValue (),
64  MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback),
65  MakeCallbackChecker ())
66  .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
67  CallbackValue (),
68  MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback6),
69  MakeCallbackChecker ())
70  ;
71  return tid;
72 }
73 
75  : m_endPoint (0),
76  m_endPoint6 (0),
77  m_node (0),
78  m_udp (0),
79  m_errno (ERROR_NOTERROR),
80  m_shutdownSend (false),
81  m_shutdownRecv (false),
82  m_connected (false),
83  m_rxAvailable (0)
84 {
86  m_allowBroadcast = false;
87 }
88 
90 {
92 
94  m_node = 0;
100  if (m_endPoint != 0)
101  {
102  NS_ASSERT (m_udp != 0);
111  NS_ASSERT (m_endPoint != 0);
112  m_udp->DeAllocate (m_endPoint);
113  NS_ASSERT (m_endPoint == 0);
114  }
115  if (m_endPoint6 != 0)
116  {
117  NS_ASSERT (m_udp != 0);
126  NS_ASSERT (m_endPoint6 != 0);
127  m_udp->DeAllocate (m_endPoint6);
128  NS_ASSERT (m_endPoint6 == 0);
129  }
130  m_udp = 0;
131 }
132 
133 void
135 {
137  m_node = node;
138 
139 }
140 void
142 {
144  m_udp = udp;
145 }
146 
147 
150 {
152  return m_errno;
153 }
154 
157 {
158  return NS3_SOCK_DGRAM;
159 }
160 
161 Ptr<Node>
163 {
165  return m_node;
166 }
167 
168 void
170 {
172  m_endPoint = 0;
173 }
174 
175 void
177 {
179  m_endPoint6 = 0;
180 }
181 
182 /* Deallocate the end point and cancel all the timers */
183 void
185 {
186  if (m_endPoint != 0)
187  {
188  m_endPoint->SetDestroyCallback (MakeNullCallback<void> ());
189  m_udp->DeAllocate (m_endPoint);
190  m_endPoint = 0;
191  }
192  if (m_endPoint6 != 0)
193  {
194  m_endPoint6->SetDestroyCallback (MakeNullCallback<void> ());
195  m_udp->DeAllocate (m_endPoint6);
196  m_endPoint6 = 0;
197  }
198 }
199 
200 
201 int
203 {
205  bool done = false;
206  if (m_endPoint != 0)
207  {
211  done = true;
212  }
213  if (m_endPoint6 != 0)
214  {
218  done = true;
219  }
220  if (done)
221  {
222  return 0;
223  }
224  return -1;
225 }
226 
227 int
229 {
231  m_endPoint = m_udp->Allocate ();
232  return FinishBind ();
233 }
234 
235 int
237 {
239  m_endPoint6 = m_udp->Allocate6 ();
240  return FinishBind ();
241 }
242 
243 int
245 {
246  NS_LOG_FUNCTION (this << address);
247 
248  if (InetSocketAddress::IsMatchingType (address))
249  {
251  Ipv4Address ipv4 = transport.GetIpv4 ();
252  uint16_t port = transport.GetPort ();
253  if (ipv4 == Ipv4Address::GetAny () && port == 0)
254  {
255  m_endPoint = m_udp->Allocate ();
256  }
257  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
258  {
259  m_endPoint = m_udp->Allocate (port);
260  }
261  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
262  {
263  m_endPoint = m_udp->Allocate (ipv4);
264  }
265  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
266  {
267  m_endPoint = m_udp->Allocate (ipv4, port);
268  }
269  if (0 == m_endPoint)
270  {
272  return -1;
273  }
274  }
275  else if (Inet6SocketAddress::IsMatchingType (address))
276  {
278  Ipv6Address ipv6 = transport.GetIpv6 ();
279  uint16_t port = transport.GetPort ();
280  if (ipv6 == Ipv6Address::GetAny () && port == 0)
281  {
282  m_endPoint6 = m_udp->Allocate6 ();
283  }
284  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
285  {
286  m_endPoint6 = m_udp->Allocate6 (port);
287  }
288  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
289  {
290  m_endPoint6 = m_udp->Allocate6 (ipv6);
291  }
292  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
293  {
294  m_endPoint6 = m_udp->Allocate6 (ipv6, port);
295  }
296  if (0 == m_endPoint6)
297  {
299  return -1;
300  }
301  }
302  else
303  {
304  NS_LOG_ERROR ("Not IsMatchingType");
306  return -1;
307  }
308 
309  return FinishBind ();
310 }
311 
312 int
314 {
316  m_shutdownSend = true;
317  return 0;
318 }
319 
320 int
322 {
324  m_shutdownRecv = true;
325  return 0;
326 }
327 
328 int
330 {
332  if (m_shutdownRecv == true && m_shutdownSend == true)
333  {
335  return -1;
336  }
337  m_shutdownRecv = true;
338  m_shutdownSend = true;
340  return 0;
341 }
342 
343 int
345 {
346  NS_LOG_FUNCTION (this << address);
347  if (InetSocketAddress::IsMatchingType(address) == true)
348  {
350  m_defaultAddress = Address(transport.GetIpv4 ());
351  m_defaultPort = transport.GetPort ();
352  m_connected = true;
354  }
355  else if (Inet6SocketAddress::IsMatchingType(address) == true)
356  {
358  m_defaultAddress = Address(transport.GetIpv6 ());
359  m_defaultPort = transport.GetPort ();
360  m_connected = true;
362  }
363  else
364  {
365  return -1;
366  }
367 
368  return 0;
369 }
370 
371 int
373 {
375  return -1;
376 }
377 
378 int
379 UdpSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
380 {
381  NS_LOG_FUNCTION (this << p << flags);
382 
383  if (!m_connected)
384  {
386  return -1;
387  }
388 
389  return DoSend (p);
390 }
391 
392 int
394 {
395  NS_LOG_FUNCTION (this << p);
397  {
398  if (Bind () == -1)
399  {
400  NS_ASSERT (m_endPoint == 0);
401  return -1;
402  }
403  NS_ASSERT (m_endPoint != 0);
404  }
406  {
407  if (Bind6 () == -1)
408  {
409  NS_ASSERT (m_endPoint6 == 0);
410  return -1;
411  }
412  NS_ASSERT (m_endPoint6 != 0);
413  }
414  if (m_shutdownSend)
415  {
417  return -1;
418  }
419 
420  return DoSendTo (p, (const Address)m_defaultAddress);
421 }
422 
423 int
425 {
426  NS_LOG_FUNCTION (this << p << address);
427 
428  if (!m_connected)
429  {
430  NS_LOG_LOGIC ("Not connected");
431  if (InetSocketAddress::IsMatchingType(address) == true)
432  {
434  Ipv4Address ipv4 = transport.GetIpv4 ();
435  uint16_t port = transport.GetPort ();
436  return DoSendTo (p, ipv4, port);
437  }
438  else if (Inet6SocketAddress::IsMatchingType(address) == true)
439  {
441  Ipv6Address ipv6 = transport.GetIpv6 ();
442  uint16_t port = transport.GetPort ();
443  return DoSendTo (p, ipv6, port);
444  }
445  else
446  {
447  return -1;
448  }
449  }
450  else
451  {
452  // connected UDP socket must use default addresses
453  NS_LOG_LOGIC ("Connected");
455  {
457  }
459  {
461  }
462  }
464  return(-1);
465 }
466 
467 int
469 {
470  NS_LOG_FUNCTION (this << p << dest << port);
471  if (m_boundnetdevice)
472  {
473  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
474  }
475  if (m_endPoint == 0)
476  {
477  if (Bind () == -1)
478  {
479  NS_ASSERT (m_endPoint == 0);
480  return -1;
481  }
482  NS_ASSERT (m_endPoint != 0);
483  }
484  if (m_shutdownSend)
485  {
487  return -1;
488  }
489 
490  if (p->GetSize () > GetTxAvailable () )
491  {
493  return -1;
494  }
495 
496  if (IsManualIpTos ())
497  {
498  SocketIpTosTag ipTosTag;
499  ipTosTag.SetTos (GetIpTos ());
500  p->AddPacketTag (ipTosTag);
501  }
502 
503  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
504 
505  // Locally override the IP TTL for this socket
506  // We cannot directly modify the TTL at this stage, so we set a Packet tag
507  // The destination can be either multicast, unicast/anycast, or
508  // either all-hosts broadcast or limited (subnet-directed) broadcast.
509  // For the latter two broadcast types, the TTL will later be set to one
510  // irrespective of what is set in these socket options. So, this tagging
511  // may end up setting the TTL of a limited broadcast packet to be
512  // the same as a unicast, but it will be fixed further down the stack
513  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
514  {
515  SocketIpTtlTag tag;
516  tag.SetTtl (m_ipMulticastTtl);
517  p->AddPacketTag (tag);
518  }
519  else if (IsManualIpTtl () && GetIpTtl () != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
520  {
521  SocketIpTtlTag tag;
522  tag.SetTtl (GetIpTtl ());
523  p->AddPacketTag (tag);
524  }
525  {
527  bool found = p->RemovePacketTag (tag);
528  if (!found)
529  {
530  if (m_mtuDiscover)
531  {
532  tag.Enable ();
533  }
534  else
535  {
536  tag.Disable ();
537  }
538  p->AddPacketTag (tag);
539  }
540  }
541  //
542  // If dest is set to the limited broadcast address (all ones),
543  // convert it to send a copy of the packet out of every
544  // interface as a subnet-directed broadcast.
545  // Exception: if the interface has a /32 address, there is no
546  // valid subnet-directed broadcast, so send it as limited broadcast
547  // Note also that some systems will only send limited broadcast packets
548  // out of the "default" interface; here we send it out all interfaces
549  //
550  if (dest.IsBroadcast ())
551  {
552  if (!m_allowBroadcast)
553  {
555  return -1;
556  }
557  NS_LOG_LOGIC ("Limited broadcast start.");
558  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
559  {
560  // Get the primary address
561  Ipv4InterfaceAddress iaddr = ipv4->GetAddress (i, 0);
562  Ipv4Address addri = iaddr.GetLocal ();
563  if (addri == Ipv4Address ("127.0.0.1"))
564  continue;
565  // Check if interface-bound socket
566  if (m_boundnetdevice)
567  {
568  if (ipv4->GetNetDevice (i) != m_boundnetdevice)
569  continue;
570  }
571  Ipv4Mask maski = iaddr.GetMask ();
572  if (maski == Ipv4Mask::GetOnes ())
573  {
574  // if the network mask is 255.255.255.255, do not convert dest
575  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest
576  << " (mask is " << maski << ")");
577  m_udp->Send (p->Copy (), addri, dest,
579  NotifyDataSent (p->GetSize ());
581  }
582  else
583  {
584  // Convert to subnet-directed broadcast
585  Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
586  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
587  << " (mask is " << maski << ")");
588  m_udp->Send (p->Copy (), addri, bcast,
590  NotifyDataSent (p->GetSize ());
592  }
593  }
594  NS_LOG_LOGIC ("Limited broadcast end.");
595  return p->GetSize ();
596  }
598  {
599  m_udp->Send (p->Copy (), m_endPoint->GetLocalAddress (), dest,
600  m_endPoint->GetLocalPort (), port, 0);
601  NotifyDataSent (p->GetSize ());
603  return p->GetSize ();
604  }
605  else if (ipv4->GetRoutingProtocol () != 0)
606  {
607  Ipv4Header header;
608  header.SetDestination (dest);
610  Socket::SocketErrno errno_;
611  Ptr<Ipv4Route> route;
612  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
613  // TBD-- we could cache the route and just check its validity
614  route = ipv4->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
615  if (route != 0)
616  {
617  NS_LOG_LOGIC ("Route exists");
618  if (!m_allowBroadcast)
619  {
620  uint32_t outputIfIndex = ipv4->GetInterfaceForDevice (route->GetOutputDevice ());
621  uint32_t ifNAddr = ipv4->GetNAddresses (outputIfIndex);
622  for (uint32_t addrI = 0; addrI < ifNAddr; ++addrI)
623  {
624  Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (outputIfIndex, addrI);
625  if (dest == ifAddr.GetBroadcast ())
626  {
628  return -1;
629  }
630  }
631  }
632 
633  header.SetSource (route->GetSource ());
634  m_udp->Send (p->Copy (), header.GetSource (), header.GetDestination (),
635  m_endPoint->GetLocalPort (), port, route);
636  NotifyDataSent (p->GetSize ());
637  return p->GetSize ();
638  }
639  else
640  {
641  NS_LOG_LOGIC ("No route to destination");
642  NS_LOG_ERROR (errno_);
643  m_errno = errno_;
644  return -1;
645  }
646  }
647  else
648  {
649  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
651  return -1;
652  }
653 
654  return 0;
655 }
656 
657 int
659 {
660  NS_LOG_FUNCTION (this << p << dest << port);
661 
662  if (dest.IsIpv4MappedAddress ())
663  {
664  return (DoSendTo(p, dest.GetIpv4MappedAddress (), port));
665  }
666  if (m_boundnetdevice)
667  {
668  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
669  }
670  if (m_endPoint6 == 0)
671  {
672  if (Bind6 () == -1)
673  {
674  NS_ASSERT (m_endPoint6 == 0);
675  return -1;
676  }
677  NS_ASSERT (m_endPoint6 != 0);
678  }
679  if (m_shutdownSend)
680  {
682  return -1;
683  }
684 
685  if (p->GetSize () > GetTxAvailable () )
686  {
688  return -1;
689  }
690 
691  if (IsManualIpv6Tclass ())
692  {
693  SocketIpv6TclassTag ipTclassTag;
694  ipTclassTag.SetTclass (GetIpv6Tclass ());
695  p->AddPacketTag (ipTclassTag);
696  }
697 
698  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
699 
700  // Locally override the IP TTL for this socket
701  // We cannot directly modify the TTL at this stage, so we set a Packet tag
702  // The destination can be either multicast, unicast/anycast, or
703  // either all-hosts broadcast or limited (subnet-directed) broadcast.
704  // For the latter two broadcast types, the TTL will later be set to one
705  // irrespective of what is set in these socket options. So, this tagging
706  // may end up setting the TTL of a limited broadcast packet to be
707  // the same as a unicast, but it will be fixed further down the stack
708  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
709  {
712  p->AddPacketTag (tag);
713  }
714  else if (IsManualIpv6HopLimit () && GetIpv6HopLimit () != 0 && !dest.IsMulticast ())
715  {
717  tag.SetHopLimit (GetIpv6HopLimit ());
718  p->AddPacketTag (tag);
719  }
720  // There is no analgous to an IPv4 broadcast address in IPv6.
721  // Instead, we use a set of link-local, site-local, and global
722  // multicast addresses. The Ipv6 routing layers should all
723  // provide an interface-specific route to these addresses such
724  // that we can treat these multicast addresses as "not broadcast"
725 
727  {
728  m_udp->Send (p->Copy (), m_endPoint6->GetLocalAddress (), dest,
729  m_endPoint6->GetLocalPort (), port, 0);
730  NotifyDataSent (p->GetSize ());
732  return p->GetSize ();
733  }
734  else if (ipv6->GetRoutingProtocol () != 0)
735  {
736  Ipv6Header header;
737  header.SetDestinationAddress (dest);
739  Socket::SocketErrno errno_;
740  Ptr<Ipv6Route> route;
741  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
742  // TBD-- we could cache the route and just check its validity
743  route = ipv6->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
744  if (route != 0)
745  {
746  NS_LOG_LOGIC ("Route exists");
747  header.SetSourceAddress (route->GetSource ());
748  m_udp->Send (p->Copy (), header.GetSourceAddress (), header.GetDestinationAddress (),
749  m_endPoint6->GetLocalPort (), port, route);
750  NotifyDataSent (p->GetSize ());
751  return p->GetSize ();
752  }
753  else
754  {
755  NS_LOG_LOGIC ("No route to destination");
756  NS_LOG_ERROR (errno_);
757  m_errno = errno_;
758  return -1;
759  }
760  }
761  else
762  {
763  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
765  return -1;
766  }
767 
768  return 0;
769 }
770 
771 
772 // maximum message size for UDP broadcast is limited by MTU
773 // size of underlying link; we are not checking that now.
774 // \todo Check MTU size of underlying link
775 uint32_t
777 {
779  // No finite send buffer is modelled, but we must respect
780  // the maximum size of an IP datagram (65535 bytes - headers).
782 }
783 
784 int
786 {
787  NS_LOG_FUNCTION (this << p << flags << address);
788  if (InetSocketAddress::IsMatchingType (address))
789  {
790  if (IsManualIpTos ())
791  {
792  SocketIpTosTag ipTosTag;
793  ipTosTag.SetTos (GetIpTos ());
794  p->AddPacketTag (ipTosTag);
795  }
796 
798  Ipv4Address ipv4 = transport.GetIpv4 ();
799  uint16_t port = transport.GetPort ();
800  return DoSendTo (p, ipv4, port);
801  }
802  else if (Inet6SocketAddress::IsMatchingType (address))
803  {
804  if (IsManualIpv6Tclass ())
805  {
806  SocketIpv6TclassTag ipTclassTag;
807  ipTclassTag.SetTclass (GetIpv6Tclass ());
808  p->AddPacketTag (ipTclassTag);
809  }
810 
812  Ipv6Address ipv6 = transport.GetIpv6 ();
813  uint16_t port = transport.GetPort ();
814  return DoSendTo (p, ipv6, port);
815  }
816  return -1;
817 }
818 
819 uint32_t
821 {
823  // We separately maintain this state to avoid walking the queue
824  // every time this might be called
825  return m_rxAvailable;
826 }
827 
829 UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
830 {
831  NS_LOG_FUNCTION (this << maxSize << flags);
832  if (m_deliveryQueue.empty () )
833  {
835  return 0;
836  }
837  Ptr<Packet> p = m_deliveryQueue.front ();
838  if (p->GetSize () <= maxSize)
839  {
840  m_deliveryQueue.pop ();
841  m_rxAvailable -= p->GetSize ();
842  }
843  else
844  {
845  p = 0;
846  }
847  return p;
848 }
849 
851 UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
852  Address &fromAddress)
853 {
854  NS_LOG_FUNCTION (this << maxSize << flags);
855  Ptr<Packet> packet = Recv (maxSize, flags);
856  if (packet != 0)
857  {
858  SocketAddressTag tag;
859  bool found;
860  found = packet->PeekPacketTag (tag);
861  NS_ASSERT (found);
862  fromAddress = tag.GetAddress ();
863  }
864  return packet;
865 }
866 
867 int
869 {
871  if (m_endPoint != 0)
872  {
874  }
875  else if (m_endPoint6 != 0)
876  {
878  }
879  else
880  { // It is possible to call this method on a socket without a name
881  // in which case, behavior is unspecified
882  // Should this return an InetSocketAddress or an Inet6SocketAddress?
883  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
884  }
885  return 0;
886 }
887 
888 int
889 UdpSocketImpl::MulticastJoinGroup (uint32_t interface, const Address &groupAddress)
890 {
891  NS_LOG_FUNCTION (interface << groupAddress);
892  /*
893  1) sanity check interface
894  2) sanity check that it has not been called yet on this interface/group
895  3) determine address family of groupAddress
896  4) locally store a list of (interface, groupAddress)
897  5) call ipv4->MulticastJoinGroup () or Ipv6->MulticastJoinGroup ()
898  */
899  return 0;
900 }
901 
902 int
903 UdpSocketImpl::MulticastLeaveGroup (uint32_t interface, const Address &groupAddress)
904 {
905  NS_LOG_FUNCTION (interface << groupAddress);
906  /*
907  1) sanity check interface
908  2) determine address family of groupAddress
909  3) delete from local list of (interface, groupAddress); raise a LOG_WARN
910  if not already present (but return 0)
911  5) call ipv4->MulticastLeaveGroup () or Ipv6->MulticastLeaveGroup ()
912  */
913  return 0;
914 }
915 
916 void
918 {
919  NS_LOG_FUNCTION (netdevice);
920  Socket::BindToNetDevice (netdevice); // Includes sanity check
921  if (m_endPoint == 0)
922  {
923  if (Bind () == -1)
924  {
925  NS_ASSERT (m_endPoint == 0);
926  return;
927  }
928  NS_ASSERT (m_endPoint != 0);
929  }
930  m_endPoint->BindToNetDevice (netdevice);
931  return;
932 }
933 
934 void
936  Ptr<Ipv4Interface> incomingInterface)
937 {
938  NS_LOG_FUNCTION (this << packet << header << port);
939 
940  if (m_shutdownRecv)
941  {
942  return;
943  }
944 
945  // Should check via getsockopt ()..
946  if (IsRecvPktInfo ())
947  {
948  Ipv4PacketInfoTag tag;
949  packet->RemovePacketTag (tag);
950  tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ());
951  packet->AddPacketTag (tag);
952  }
953 
954  //Check only version 4 options
955  if (IsIpRecvTos ())
956  {
957  SocketIpTosTag ipTosTag;
958  ipTosTag.SetTos (header.GetTos ());
959  packet->AddPacketTag (ipTosTag);
960  }
961 
962  if (IsIpRecvTtl ())
963  {
964  SocketIpTtlTag ipTtlTag;
965  ipTtlTag.SetTtl (header.GetTtl ());
966  packet->AddPacketTag (ipTtlTag);
967  }
968 
969  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
970  {
972  SocketAddressTag tag;
973  tag.SetAddress (address);
974  packet->AddPacketTag (tag);
975  m_deliveryQueue.push (packet);
976  m_rxAvailable += packet->GetSize ();
977  NotifyDataRecv ();
978  }
979  else
980  {
981  // In general, this case should not occur unless the
982  // receiving application reads data from this socket slowly
983  // in comparison to the arrival rate
984  //
985  // drop and trace packet
986  NS_LOG_WARN ("No receive buffer space available. Drop.");
987  m_dropTrace (packet);
988  }
989 }
990 
991 void
992 UdpSocketImpl::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, Ptr<Ipv6Interface> incomingInterface)
993 {
994  NS_LOG_FUNCTION (this << packet << header.GetSourceAddress () << port);
995 
996  if (m_shutdownRecv)
997  {
998  return;
999  }
1000 
1001  // Should check via getsockopt ()..
1002  if (IsRecvPktInfo ())
1003  {
1004  Ipv6PacketInfoTag tag;
1005  packet->RemovePacketTag (tag);
1006  tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ());
1007  packet->AddPacketTag (tag);
1008  }
1009 
1010  //Check only version 6 options
1011  if (IsIpv6RecvTclass ())
1012  {
1013  SocketIpv6TclassTag ipTclassTag;
1014  ipTclassTag.SetTclass (header.GetTrafficClass ());
1015  packet->AddPacketTag (ipTclassTag);
1016  }
1017 
1018  if (IsIpv6RecvHopLimit ())
1019  {
1020  SocketIpv6HopLimitTag ipHopLimitTag;
1021  ipHopLimitTag.SetHopLimit (header.GetHopLimit ());
1022  packet->AddPacketTag (ipHopLimitTag);
1023  }
1024 
1025  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
1026  {
1028  SocketAddressTag tag;
1029  tag.SetAddress (address);
1030  packet->AddPacketTag (tag);
1031  m_deliveryQueue.push (packet);
1032  m_rxAvailable += packet->GetSize ();
1033  NotifyDataRecv ();
1034  }
1035  else
1036  {
1037  // In general, this case should not occur unless the
1038  // receiving application reads data from this socket slowly
1039  // in comparison to the arrival rate
1040  //
1041  // drop and trace packet
1042  NS_LOG_WARN ("No receive buffer space available. Drop.");
1043  m_dropTrace (packet);
1044  }
1045 }
1046 
1047 void
1048 UdpSocketImpl::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
1049  uint8_t icmpType, uint8_t icmpCode,
1050  uint32_t icmpInfo)
1051 {
1052  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
1053  (uint32_t)icmpCode << icmpInfo);
1054  if (!m_icmpCallback.IsNull ())
1055  {
1056  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1057  }
1058 }
1059 
1060 void
1061 UdpSocketImpl::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
1062  uint8_t icmpType, uint8_t icmpCode,
1063  uint32_t icmpInfo)
1064 {
1065  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
1066  (uint32_t)icmpCode << icmpInfo);
1067  if (!m_icmpCallback6.IsNull ())
1068  {
1069  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1070  }
1071 }
1072 
1073 void
1075 {
1076  m_rcvBufSize = size;
1077 }
1078 
1079 uint32_t
1081 {
1082  return m_rcvBufSize;
1083 }
1084 
1085 void
1087 {
1088  m_ipMulticastTtl = ipTtl;
1089 }
1090 
1091 uint8_t
1093 {
1094  return m_ipMulticastTtl;
1095 }
1096 
1097 void
1099 {
1100  m_ipMulticastIf = ipIf;
1101 }
1102 
1103 int32_t
1105 {
1106  return m_ipMulticastIf;
1107 }
1108 
1109 void
1111 {
1112  m_ipMulticastLoop = loop;
1113 }
1114 
1115 bool
1117 {
1118  return m_ipMulticastLoop;
1119 }
1120 
1121 void
1123 {
1124  m_mtuDiscover = discover;
1125 }
1126 bool
1128 {
1129  return m_mtuDiscover;
1130 }
1131 
1132 bool
1134 {
1135  m_allowBroadcast = allowBroadcast;
1136  return true;
1137 }
1138 
1139 bool
1141 {
1142  return m_allowBroadcast;
1143 }
1144 
1145 
1146 } // namespace ns3
static bool IsMatchingType(const Address &address)
If the Address matches the type.
void SetSource(Ipv4Address source)
Definition: ipv4-header.cc:285
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
bool m_shutdownSend
Send no longer allowed.
void SetTclass(uint8_t tclass)
Set the tag's Tclass.
Definition: socket.cc:816
static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE
Maximum 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
Checks if the socket has a specific IPv4 TTL set.
Definition: socket.cc:382
Doxygen introspection did not find any typical Config paths.
Definition: ipv6-header.h:33
an Inet address class
Ipv4Address GetIpv4(void) const
void SetDestination(Ipv4Address destination)
Definition: ipv4-header.cc:298
static Ipv4Address GetAny(void)
#define NS_LOG_FUNCTION(parameters)
If log level LOG_FUNCTION is enabled, this macro will output all input parameters separated by "...
void Destroy(void)
Kill this socket by zeroing its attributes (IPv4)
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
the associated UDP L4 protocol
virtual bool GetIpMulticastLoop(void) const
Get the IP multicast loop capability.
Ipv4Mask GetMask(void) const
Get the network mask.
virtual uint8_t GetIpTtl(void) const
Query the value of IP Time to Live field of this socket.
Definition: socket.cc:470
Ipv4EndPoint * m_endPoint
the IPv4 endpoint
uint8_t GetIpTos(void) const
Query the value of IP Type of Service of this socket.
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:1044
#define NS_OBJECT_ENSURE_REGISTERED(type)
Register the class in the ns-3 factory.
Definition: object-base.h:38
enum SocketErrno m_errno
Socket error code.
virtual void SetIpMulticastIf(int32_t ipIf)
Set the IP multicast interface.
Ipv4Address GetLocal(void) const
Get the local address.
Access to the IPv6 forwarding table, interfaces, and configuration.
Definition: ipv6.h:80
bool m_allowBroadcast
Allow send broadcast packets.
void NotifyDataRecv(void)
Notify through the callback (if set) that some data have been received.
Definition: socket.cc:304
a class to represent an Ipv4 address mask
Definition: ipv4-address.h:222
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv4Header, uint16_t, Ptr< Ipv4Interface > > callback)
Set the reception callback.
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:174
void SetDestroyCallback(Callback< void > callback)
Set the default destroy callback.
std::queue< Ptr< Packet > > m_deliveryQueue
Queue for incoming packets.
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
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
virtual int Close(void)
Close a socket.
#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 Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
virtual uint8_t GetIpMulticastTtl(void) const
Get the IP multicast TTL.
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:170
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 SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:76
bool IsManualIpTos(void) const
Checks if the socket has a specific IPv4 ToS set.
Definition: socket.cc:370
uint32_t m_rxAvailable
Number of available bytes to be received.
bool IsMulticast(void) const
void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
virtual uint8_t GetIpv6HopLimit(void) const
Query the value of IP Hop Limit field of this socket.
Definition: socket.cc:495
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetTos(uint8_t tos)
Set the tag's 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:996
SocketErrno
Enumeration of the possible errors returned by a socket.
Definition: socket.h:82
virtual void SetRcvBufSize(uint32_t size)
Set the receiving buffer size.
bool IsRecvPktInfo() const
Get status indicating whether enable/disable packet information to socket.
Definition: socket.cc:363
bool m_connected
Connection established.
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)
Called by the L3 protocol when it received an ICMPv6 packet to pass on to TCP.
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.
AttributeValue form of a Callback.
Definition: callback.h:1662
void ForwardUp(Ptr< Packet > packet, Ipv4Header header, uint16_t port, Ptr< Ipv4Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
virtual enum SocketErrno GetErrno(void) const
Get last error number.
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
Get socket address.
bool PeekPacketTag(Tag &tag) const
Search a matching tag and call Tag::Deserialize if it is found.
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)
Send a packet to a specific destination.
void ForwardIcmp(Ipv4Address icmpSource, uint8_t icmpTtl, uint8_t icmpType, uint8_t icmpCode, uint32_t icmpInfo)
Called by the L3 protocol when it received an ICMP packet to pass on to TCP.
Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback6
ICMPv6 callback.
void SetTtl(uint8_t ttl)
Set the tag's TTL.
Definition: socket.cc:582
int DoSend(Ptr< Packet > p)
Send a packet.
uint16_t GetLocalPort()
Get the local port.
void SetNode(Ptr< Node > node)
Set the associated node.
virtual uint32_t GetRcvBufSize(void) const
Get the receiving buffer size.
virtual uint32_t GetRxAvailable(void) const
Return number of bytes which can be returned from one or multiple calls to Recv.
virtual int Bind6(void)
Allocate a local IPv6 endpoint for this socket.
UdpSocketImpl()
Create an unbound udp 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.
Ipv4Address GetLocalAddress(void)
Get the local address.
bool IsBroadcast(void) const
uint8_t m_ipMulticastTtl
Multicast TTL.
Address m_defaultAddress
Default address.
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:948
virtual void SetMtuDiscover(bool discover)
Set the MTU discover capability.
Callback< R > MakeCallback(R(T::*memPtr)(void), OBJ objPtr)
Definition: callback.h:1242
virtual int32_t GetIpMulticastIf(void) const
Get the IP multicast interface.
bool IsManualIpv6Tclass(void) const
Checks if the socket has a specific IPv6 Tclass set.
Definition: socket.cc:376
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:284
virtual Ptr< NetDevice > GetDevice() const
Get the NetDevice.
Ipv4Address GetSource(void) const
Definition: ipv4-route.cc:56
void Destroy6(void)
Kill this socket by zeroing its attributes (IPv6)
static bool IsMatchingType(const Address &address)
#define NS_LOG_LOGIC(msg)
Use NS_LOG to output a message of level LOG_LOGIC.
Definition: log.h:233
int FinishBind(void)
Finish the binding process.
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition: socket.cc:642
static TypeId GetTypeId(void)
Get the type ID.
void NotifyConnectionSucceeded(void)
Notify through the callback (if set) that the connection has been established.
Definition: socket.cc:216
Access to the Ipv4 forwarding table, interfaces, and configuration.
Definition: ipv4.h:76
Ptr< Packet > Copy(void) const
performs a COW copy of the packet.
Definition: packet.cc:122
bool IsManualIpv6HopLimit(void) const
Checks if the socket has a specific IPv6 Hop Limit set.
Definition: socket.cc:388
virtual void SetIpMulticastLoop(bool loop)
Set the IP multicast loop capability.
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.
bool m_shutdownRecv
Receive no longer allowed.
static InetSocketAddress ConvertFrom(const Address &address)
Returns an InetSocketAddress which corresponds to the input Address.
Ptr< const TraceSourceAccessor > MakeTraceSourceAccessor(T a)
Ptr< Node > m_node
the associated node
void SetIcmpCallback(Callback< void, Ipv6Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
indicates whether the socket has IPV6_TCLASS set.
Definition: socket.h:1189
uint8_t GetIpv6Tclass(void) const
Query the value of IPv6 Traffic Class field of this socket.
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
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
void Disable(void)
Disables the DF (Don't Fragment) flag.
Definition: socket.cc:702
Describes an IPv6 address.
Definition: ipv6-address.h:46
void ForwardUp6(Ptr< Packet > packet, Ipv6Header header, uint16_t port, Ptr< Ipv6Interface > incomingInterface)
Called by the L3 protocol when it received a packet to pass on to TCP.
Ipv4 addresses are stored in host order in this class.
Definition: ipv4-address.h:38
virtual uint32_t GetTxAvailable(void) const
Returns the number of bytes which can be sent in a single call to Send.
Ipv4Address GetBroadcast(void) const
Get the broadcast address.
Ptr< NetDevice > m_boundnetdevice
the device this socket is bound to (might be null).
Definition: socket.h:911
virtual bool SetAllowBroadcast(bool allowBroadcast)
Configure whether broadcast datagram transmissions are allowed.
a class to store IPv4 address information on an interface
uint32_t m_rcvBufSize
Receive buffer size.
uint16_t GetLocalPort(void)
Get the local port.
#define NS_LOG_WARN(msg)
Use NS_LOG to output a message of level LOG_WARN.
Definition: log.h:203
Ptr< NetDevice > GetDevice(void) const
Address GetAddress(void) const
Get the tag's address.
Definition: socket.cc:529
void SetUdp(Ptr< UdpL4Protocol > udp)
Set the associated UDP L4 protocol.
bool m_ipMulticastLoop
Allow multicast loop.
virtual int Listen(void)
Listen for incoming connections.
bool RemovePacketTag(Tag &tag)
Remove a packet tag.
Definition: packet.cc:848
Ipv6Address GetSourceAddress(void) const
Get the "Source address" field.
Definition: ipv6-header.cc:101
indicates whether packets should be sent out with the DF (Don't Fragment) flag set.
Definition: socket.h:1092
static Inet6SocketAddress ConvertFrom(const Address &addr)
Convert the address to a InetSocketAddress.
uint16_t m_defaultPort
Default port.
virtual int SendTo(Ptr< Packet > p, uint32_t flags, const Address &address)
Send data to a specified peer.
Ipv6EndPoint * m_endPoint6
the IPv6 endpoint
void SetRxCallback(Callback< void, Ptr< Packet >, Ipv6Header, uint16_t, Ptr< Ipv6Interface > > callback)
Set the reception callback.
static bool IsMatchingType(const Address &addr)
If the address match.
void Enable(void)
Enables the DF (Don't Fragment) flag.
Definition: socket.cc:696
uint16_t GetPort(void) const
Get the port.
void DeallocateEndPoint(void)
Deallocate m_endPoint and m_endPoint6.
Ipv4Address GetIpv4MappedAddress() const
Return the Ipv4 address.
int32_t m_ipMulticastIf
Multicast Interface.
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_LOG_ERROR(msg)
Use NS_LOG to output a message of level LOG_ERROR.
Definition: log.h:193
uint16_t GetPort(void) const
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
uint8_t GetTos(void) const
Definition: ipv4-header.cc:194
This class implements a tag that carries socket ancillary data to the socket interface.
static Ipv4Address ConvertFrom(const Address &address)
tuple address
Definition: first.py:37
TracedCallback< Ptr< const Packet > > m_dropTrace
Trace for dropped packets.
indicates whether the socket has IP_TOS set.
Definition: socket.h:1142
Ptr< T > GetObject(void) const
Definition: object.h:362
void SetIcmpCallback(Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > callback)
Set the ICMP callback.
SocketType
Enumeration of the possible socket types.
Definition: socket.h:104
bool IsIpv4MappedAddress() const
If the address is an IPv4-mapped address.
a unique identifier for an interface.
Definition: type-id.h:49
static const uint8_t PROT_NUMBER
protocol number (0x11)
bool m_mtuDiscover
Allow MTU discovery.
void SetDestinationAddress(Ipv6Address dst)
Set the "Destination address" field.
Definition: ipv6-header.cc:106
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
void SetRecvIf(uint32_t ifindex)
Set the tag's receiving interface.
static bool IsMatchingType(const Address &address)
Callback< void, Ipv4Address, uint8_t, uint8_t, uint8_t, uint32_t > m_icmpCallback
ICMP callback.
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
Get the MTU discover capability.
virtual void SetIpMulticastTtl(uint8_t ipTtl)
Set the IP multicast TTL.
virtual Ptr< Node > GetNode(void) const
Return the node this socket is associated with.
void SetRecvIf(uint32_t ifindex)
Set the tag's receiving interface.