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 
49 // The correct maximum UDP message size is 65507, as determined by the following formula:
50 // 0xffff - (sizeof(IP Header) + sizeof(UDP Header)) = 65535-(20+8) = 65507
51 // \todo MAX_IPV4_UDP_DATAGRAM_SIZE is correct only for IPv4
52 static const uint32_t MAX_IPV4_UDP_DATAGRAM_SIZE = 65507;
53 
54 // Add attributes generic to all UdpSockets to base class UdpSocket
55 TypeId
57 {
58  static TypeId tid = TypeId ("ns3::UdpSocketImpl")
59  .SetParent<UdpSocket> ()
60  .AddConstructor<UdpSocketImpl> ()
61  .AddTraceSource ("Drop", "Drop UDP packet due to receive buffer overflow",
63  .AddAttribute ("IcmpCallback", "Callback invoked whenever an icmp error is received on this socket.",
64  CallbackValue (),
65  MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback),
66  MakeCallbackChecker ())
67  .AddAttribute ("IcmpCallback6", "Callback invoked whenever an icmpv6 error is received on this socket.",
68  CallbackValue (),
69  MakeCallbackAccessor (&UdpSocketImpl::m_icmpCallback6),
70  MakeCallbackChecker ())
71  ;
72  return tid;
73 }
74 
76  : m_endPoint (0),
77  m_endPoint6 (0),
78  m_node (0),
79  m_udp (0),
80  m_errno (ERROR_NOTERROR),
81  m_shutdownSend (false),
82  m_shutdownRecv (false),
83  m_connected (false),
84  m_rxAvailable (0)
85 {
87  m_allowBroadcast = false;
88 }
89 
91 {
93 
95  m_node = 0;
101  if (m_endPoint != 0)
102  {
103  NS_ASSERT (m_udp != 0);
112  NS_ASSERT (m_endPoint != 0);
113  m_udp->DeAllocate (m_endPoint);
114  NS_ASSERT (m_endPoint == 0);
115  }
116  if (m_endPoint6 != 0)
117  {
118  NS_ASSERT (m_udp != 0);
127  NS_ASSERT (m_endPoint6 != 0);
128  m_udp->DeAllocate (m_endPoint6);
129  NS_ASSERT (m_endPoint6 == 0);
130  }
131  m_udp = 0;
132 }
133 
134 void
136 {
138  m_node = node;
139 
140 }
141 void
143 {
145  m_udp = udp;
146 }
147 
148 
151 {
153  return m_errno;
154 }
155 
158 {
159  return NS3_SOCK_DGRAM;
160 }
161 
162 Ptr<Node>
164 {
166  return m_node;
167 }
168 
169 void
171 {
173  m_endPoint = 0;
174 }
175 
176 void
178 {
180  m_endPoint6 = 0;
181 }
182 
183 int
185 {
187  bool done = false;
188  if (m_endPoint != 0)
189  {
193  done = true;
194  }
195  if (m_endPoint6 != 0)
196  {
200  done = true;
201  }
202  if (done)
203  {
204  return 0;
205  }
206  return -1;
207 }
208 
209 int
211 {
213  m_endPoint = m_udp->Allocate ();
214  return FinishBind ();
215 }
216 
217 int
219 {
221  m_endPoint6 = m_udp->Allocate6 ();
222  return FinishBind ();
223 }
224 
225 int
227 {
228  NS_LOG_FUNCTION (this << address);
229 
230  if (InetSocketAddress::IsMatchingType (address))
231  {
233  Ipv4Address ipv4 = transport.GetIpv4 ();
234  uint16_t port = transport.GetPort ();
235  if (ipv4 == Ipv4Address::GetAny () && port == 0)
236  {
237  m_endPoint = m_udp->Allocate ();
238  }
239  else if (ipv4 == Ipv4Address::GetAny () && port != 0)
240  {
241  m_endPoint = m_udp->Allocate (port);
242  }
243  else if (ipv4 != Ipv4Address::GetAny () && port == 0)
244  {
245  m_endPoint = m_udp->Allocate (ipv4);
246  }
247  else if (ipv4 != Ipv4Address::GetAny () && port != 0)
248  {
249  m_endPoint = m_udp->Allocate (ipv4, port);
250  }
251  if (0 == m_endPoint)
252  {
254  return -1;
255  }
256  }
257  else if (Inet6SocketAddress::IsMatchingType (address))
258  {
260  Ipv6Address ipv6 = transport.GetIpv6 ();
261  uint16_t port = transport.GetPort ();
262  if (ipv6 == Ipv6Address::GetAny () && port == 0)
263  {
264  m_endPoint6 = m_udp->Allocate6 ();
265  }
266  else if (ipv6 == Ipv6Address::GetAny () && port != 0)
267  {
268  m_endPoint6 = m_udp->Allocate6 (port);
269  }
270  else if (ipv6 != Ipv6Address::GetAny () && port == 0)
271  {
272  m_endPoint6 = m_udp->Allocate6 (ipv6);
273  }
274  else if (ipv6 != Ipv6Address::GetAny () && port != 0)
275  {
276  m_endPoint6 = m_udp->Allocate6 (ipv6, port);
277  }
278  if (0 == m_endPoint6)
279  {
281  return -1;
282  }
283  }
284  else
285  {
286  NS_LOG_ERROR ("Not IsMatchingType");
288  return -1;
289  }
290 
291  return FinishBind ();
292 }
293 
294 int
296 {
298  m_shutdownSend = true;
299  return 0;
300 }
301 
302 int
304 {
306  m_shutdownRecv = true;
307  return 0;
308 }
309 
310 int
312 {
314  if (m_shutdownRecv == true && m_shutdownSend == true)
315  {
317  return -1;
318  }
319  m_shutdownRecv = true;
320  m_shutdownSend = true;
321  return 0;
322 }
323 
324 int
326 {
327  NS_LOG_FUNCTION (this << address);
328  if (InetSocketAddress::IsMatchingType(address) == true)
329  {
331  m_defaultAddress = Address(transport.GetIpv4 ());
332  m_defaultPort = transport.GetPort ();
333  m_connected = true;
335  }
336  else if (Inet6SocketAddress::IsMatchingType(address) == true)
337  {
339  m_defaultAddress = Address(transport.GetIpv6 ());
340  m_defaultPort = transport.GetPort ();
341  m_connected = true;
343  }
344  else
345  {
346  return -1;
347  }
348 
349  return 0;
350 }
351 
352 int
354 {
356  return -1;
357 }
358 
359 int
360 UdpSocketImpl::Send (Ptr<Packet> p, uint32_t flags)
361 {
362  NS_LOG_FUNCTION (this << p << flags);
363 
364  if (!m_connected)
365  {
367  return -1;
368  }
369 
370  return DoSend (p);
371 }
372 
373 int
375 {
376  NS_LOG_FUNCTION (this << p);
378  {
379  if (Bind () == -1)
380  {
381  NS_ASSERT (m_endPoint == 0);
382  return -1;
383  }
384  NS_ASSERT (m_endPoint != 0);
385  }
387  {
388  if (Bind6 () == -1)
389  {
390  NS_ASSERT (m_endPoint6 == 0);
391  return -1;
392  }
393  NS_ASSERT (m_endPoint6 != 0);
394  }
395  if (m_shutdownSend)
396  {
398  return -1;
399  }
400 
401  return DoSendTo (p, (const Address)m_defaultAddress);
402 }
403 
404 int
406 {
407  NS_LOG_FUNCTION (this << p << address);
408 
409  if (!m_connected)
410  {
411  NS_LOG_LOGIC ("Not connected");
412  if (InetSocketAddress::IsMatchingType(address) == true)
413  {
415  Ipv4Address ipv4 = transport.GetIpv4 ();
416  uint16_t port = transport.GetPort ();
417  return DoSendTo (p, ipv4, port);
418  }
419  else if (Inet6SocketAddress::IsMatchingType(address) == true)
420  {
422  Ipv6Address ipv6 = transport.GetIpv6 ();
423  uint16_t port = transport.GetPort ();
424  return DoSendTo (p, ipv6, port);
425  }
426  else
427  {
428  return -1;
429  }
430  }
431  else
432  {
433  // connected UDP socket must use default addresses
434  NS_LOG_LOGIC ("Connected");
436  {
438  }
440  {
442  }
443  }
445  return(-1);
446 }
447 
448 int
450 {
451  NS_LOG_FUNCTION (this << p << dest << port);
452  if (m_boundnetdevice)
453  {
454  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
455  }
456  if (m_endPoint == 0)
457  {
458  if (Bind () == -1)
459  {
460  NS_ASSERT (m_endPoint == 0);
461  return -1;
462  }
463  NS_ASSERT (m_endPoint != 0);
464  }
465  if (m_shutdownSend)
466  {
468  return -1;
469  }
470 
471  if (p->GetSize () > GetTxAvailable () )
472  {
474  return -1;
475  }
476 
477  if (IsManualIpTos ())
478  {
479  SocketIpTosTag ipTosTag;
480  ipTosTag.SetTos (GetIpTos ());
481  p->AddPacketTag (ipTosTag);
482  }
483 
484  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
485 
486  // Locally override the IP TTL for this socket
487  // We cannot directly modify the TTL at this stage, so we set a Packet tag
488  // The destination can be either multicast, unicast/anycast, or
489  // either all-hosts broadcast or limited (subnet-directed) broadcast.
490  // For the latter two broadcast types, the TTL will later be set to one
491  // irrespective of what is set in these socket options. So, this tagging
492  // may end up setting the TTL of a limited broadcast packet to be
493  // the same as a unicast, but it will be fixed further down the stack
494  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
495  {
496  SocketIpTtlTag tag;
497  tag.SetTtl (m_ipMulticastTtl);
498  p->AddPacketTag (tag);
499  }
500  else if (IsManualIpTtl () && GetIpTtl () != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
501  {
502  SocketIpTtlTag tag;
503  tag.SetTtl (GetIpTtl ());
504  p->AddPacketTag (tag);
505  }
506  {
508  bool found = p->RemovePacketTag (tag);
509  if (!found)
510  {
511  if (m_mtuDiscover)
512  {
513  tag.Enable ();
514  }
515  else
516  {
517  tag.Disable ();
518  }
519  p->AddPacketTag (tag);
520  }
521  }
522  //
523  // If dest is set to the limited broadcast address (all ones),
524  // convert it to send a copy of the packet out of every
525  // interface as a subnet-directed broadcast.
526  // Exception: if the interface has a /32 address, there is no
527  // valid subnet-directed broadcast, so send it as limited broadcast
528  // Note also that some systems will only send limited broadcast packets
529  // out of the "default" interface; here we send it out all interfaces
530  //
531  if (dest.IsBroadcast ())
532  {
533  if (!m_allowBroadcast)
534  {
536  return -1;
537  }
538  NS_LOG_LOGIC ("Limited broadcast start.");
539  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
540  {
541  // Get the primary address
542  Ipv4InterfaceAddress iaddr = ipv4->GetAddress (i, 0);
543  Ipv4Address addri = iaddr.GetLocal ();
544  if (addri == Ipv4Address ("127.0.0.1"))
545  continue;
546  // Check if interface-bound socket
547  if (m_boundnetdevice)
548  {
549  if (ipv4->GetNetDevice (i) != m_boundnetdevice)
550  continue;
551  }
552  Ipv4Mask maski = iaddr.GetMask ();
553  if (maski == Ipv4Mask::GetOnes ())
554  {
555  // if the network mask is 255.255.255.255, do not convert dest
556  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest
557  << " (mask is " << maski << ")");
558  m_udp->Send (p->Copy (), addri, dest,
560  NotifyDataSent (p->GetSize ());
562  }
563  else
564  {
565  // Convert to subnet-directed broadcast
566  Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
567  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
568  << " (mask is " << maski << ")");
569  m_udp->Send (p->Copy (), addri, bcast,
571  NotifyDataSent (p->GetSize ());
573  }
574  }
575  NS_LOG_LOGIC ("Limited broadcast end.");
576  return p->GetSize ();
577  }
579  {
580  m_udp->Send (p->Copy (), m_endPoint->GetLocalAddress (), dest,
581  m_endPoint->GetLocalPort (), port, 0);
582  NotifyDataSent (p->GetSize ());
584  return p->GetSize ();
585  }
586  else if (ipv4->GetRoutingProtocol () != 0)
587  {
588  Ipv4Header header;
589  header.SetDestination (dest);
591  Socket::SocketErrno errno_;
592  Ptr<Ipv4Route> route;
593  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
594  // TBD-- we could cache the route and just check its validity
595  route = ipv4->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
596  if (route != 0)
597  {
598  NS_LOG_LOGIC ("Route exists");
599  if (!m_allowBroadcast)
600  {
601  uint32_t outputIfIndex = ipv4->GetInterfaceForDevice (route->GetOutputDevice ());
602  uint32_t ifNAddr = ipv4->GetNAddresses (outputIfIndex);
603  for (uint32_t addrI = 0; addrI < ifNAddr; ++addrI)
604  {
605  Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (outputIfIndex, addrI);
606  if (dest == ifAddr.GetBroadcast ())
607  {
609  return -1;
610  }
611  }
612  }
613 
614  header.SetSource (route->GetSource ());
615  m_udp->Send (p->Copy (), header.GetSource (), header.GetDestination (),
616  m_endPoint->GetLocalPort (), port, route);
617  NotifyDataSent (p->GetSize ());
618  return p->GetSize ();
619  }
620  else
621  {
622  NS_LOG_LOGIC ("No route to destination");
623  NS_LOG_ERROR (errno_);
624  m_errno = errno_;
625  return -1;
626  }
627  }
628  else
629  {
630  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
632  return -1;
633  }
634 
635  return 0;
636 }
637 
638 int
640 {
641  NS_LOG_FUNCTION (this << p << dest << port);
642 
643  if (dest.IsIpv4MappedAddress ())
644  {
645  return (DoSendTo(p, dest.GetIpv4MappedAddress (), port));
646  }
647  if (m_boundnetdevice)
648  {
649  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
650  }
651  if (m_endPoint6 == 0)
652  {
653  if (Bind6 () == -1)
654  {
655  NS_ASSERT (m_endPoint6 == 0);
656  return -1;
657  }
658  NS_ASSERT (m_endPoint6 != 0);
659  }
660  if (m_shutdownSend)
661  {
663  return -1;
664  }
665 
666  if (p->GetSize () > GetTxAvailable () )
667  {
669  return -1;
670  }
671 
672  if (IsManualIpv6Tclass ())
673  {
674  SocketIpv6TclassTag ipTclassTag;
675  ipTclassTag.SetTclass (GetIpv6Tclass ());
676  p->AddPacketTag (ipTclassTag);
677  }
678 
679  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
680 
681  // Locally override the IP TTL for this socket
682  // We cannot directly modify the TTL at this stage, so we set a Packet tag
683  // The destination can be either multicast, unicast/anycast, or
684  // either all-hosts broadcast or limited (subnet-directed) broadcast.
685  // For the latter two broadcast types, the TTL will later be set to one
686  // irrespective of what is set in these socket options. So, this tagging
687  // may end up setting the TTL of a limited broadcast packet to be
688  // the same as a unicast, but it will be fixed further down the stack
689  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
690  {
693  p->AddPacketTag (tag);
694  }
695  else if (IsManualIpv6HopLimit () && GetIpv6HopLimit () != 0 && !dest.IsMulticast ())
696  {
698  tag.SetHopLimit (GetIpv6HopLimit ());
699  p->AddPacketTag (tag);
700  }
701  // There is no analgous to an IPv4 broadcast address in IPv6.
702  // Instead, we use a set of link-local, site-local, and global
703  // multicast addresses. The Ipv6 routing layers should all
704  // provide an interface-specific route to these addresses such
705  // that we can treat these multicast addresses as "not broadcast"
706 
708  {
709  m_udp->Send (p->Copy (), m_endPoint6->GetLocalAddress (), dest,
710  m_endPoint6->GetLocalPort (), port, 0);
711  NotifyDataSent (p->GetSize ());
713  return p->GetSize ();
714  }
715  else if (ipv6->GetRoutingProtocol () != 0)
716  {
717  Ipv6Header header;
718  header.SetDestinationAddress (dest);
720  Socket::SocketErrno errno_;
721  Ptr<Ipv6Route> route;
722  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
723  // TBD-- we could cache the route and just check its validity
724  route = ipv6->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
725  if (route != 0)
726  {
727  NS_LOG_LOGIC ("Route exists");
728  header.SetSourceAddress (route->GetSource ());
729  m_udp->Send (p->Copy (), header.GetSourceAddress (), header.GetDestinationAddress (),
730  m_endPoint6->GetLocalPort (), port, route);
731  NotifyDataSent (p->GetSize ());
732  return p->GetSize ();
733  }
734  else
735  {
736  NS_LOG_LOGIC ("No route to destination");
737  NS_LOG_ERROR (errno_);
738  m_errno = errno_;
739  return -1;
740  }
741  }
742  else
743  {
744  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
746  return -1;
747  }
748 
749  return 0;
750 }
751 
752 
753 // maximum message size for UDP broadcast is limited by MTU
754 // size of underlying link; we are not checking that now.
755 // \todo Check MTU size of underlying link
756 uint32_t
758 {
760  // No finite send buffer is modelled, but we must respect
761  // the maximum size of an IP datagram (65535 bytes - headers).
763 }
764 
765 int
767 {
768  NS_LOG_FUNCTION (this << p << flags << address);
769  if (InetSocketAddress::IsMatchingType (address))
770  {
771  if (IsManualIpTos ())
772  {
773  SocketIpTosTag ipTosTag;
774  ipTosTag.SetTos (GetIpTos ());
775  p->AddPacketTag (ipTosTag);
776  }
777 
779  Ipv4Address ipv4 = transport.GetIpv4 ();
780  uint16_t port = transport.GetPort ();
781  return DoSendTo (p, ipv4, port);
782  }
783  else if (Inet6SocketAddress::IsMatchingType (address))
784  {
785  if (IsManualIpv6Tclass ())
786  {
787  SocketIpv6TclassTag ipTclassTag;
788  ipTclassTag.SetTclass (GetIpv6Tclass ());
789  p->AddPacketTag (ipTclassTag);
790  }
791 
793  Ipv6Address ipv6 = transport.GetIpv6 ();
794  uint16_t port = transport.GetPort ();
795  return DoSendTo (p, ipv6, port);
796  }
797  return -1;
798 }
799 
800 uint32_t
802 {
804  // We separately maintain this state to avoid walking the queue
805  // every time this might be called
806  return m_rxAvailable;
807 }
808 
810 UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
811 {
812  NS_LOG_FUNCTION (this << maxSize << flags);
813  if (m_deliveryQueue.empty () )
814  {
816  return 0;
817  }
818  Ptr<Packet> p = m_deliveryQueue.front ();
819  if (p->GetSize () <= maxSize)
820  {
821  m_deliveryQueue.pop ();
822  m_rxAvailable -= p->GetSize ();
823  }
824  else
825  {
826  p = 0;
827  }
828  return p;
829 }
830 
832 UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
833  Address &fromAddress)
834 {
835  NS_LOG_FUNCTION (this << maxSize << flags);
836  Ptr<Packet> packet = Recv (maxSize, flags);
837  if (packet != 0)
838  {
839  SocketAddressTag tag;
840  bool found;
841  found = packet->PeekPacketTag (tag);
842  NS_ASSERT (found);
843  fromAddress = tag.GetAddress ();
844  }
845  return packet;
846 }
847 
848 int
850 {
852  if (m_endPoint != 0)
853  {
855  }
856  else
857  {
858  // It is possible to call this method on a socket without a name
859  // in which case, behavior is unspecified
860  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
861  }
862  return 0;
863 }
864 
865 int
866 UdpSocketImpl::MulticastJoinGroup (uint32_t interface, const Address &groupAddress)
867 {
868  NS_LOG_FUNCTION (interface << groupAddress);
869  /*
870  1) sanity check interface
871  2) sanity check that it has not been called yet on this interface/group
872  3) determine address family of groupAddress
873  4) locally store a list of (interface, groupAddress)
874  5) call ipv4->MulticastJoinGroup () or Ipv6->MulticastJoinGroup ()
875  */
876  return 0;
877 }
878 
879 int
880 UdpSocketImpl::MulticastLeaveGroup (uint32_t interface, const Address &groupAddress)
881 {
882  NS_LOG_FUNCTION (interface << groupAddress);
883  /*
884  1) sanity check interface
885  2) determine address family of groupAddress
886  3) delete from local list of (interface, groupAddress); raise a LOG_WARN
887  if not already present (but return 0)
888  5) call ipv4->MulticastLeaveGroup () or Ipv6->MulticastLeaveGroup ()
889  */
890  return 0;
891 }
892 
893 void
895 {
896  NS_LOG_FUNCTION (netdevice);
897  Socket::BindToNetDevice (netdevice); // Includes sanity check
898  if (m_endPoint == 0)
899  {
900  if (Bind () == -1)
901  {
902  NS_ASSERT (m_endPoint == 0);
903  return;
904  }
905  NS_ASSERT (m_endPoint != 0);
906  }
907  m_endPoint->BindToNetDevice (netdevice);
908  return;
909 }
910 
911 void
913  Ptr<Ipv4Interface> incomingInterface)
914 {
915  NS_LOG_FUNCTION (this << packet << header << port);
916 
917  if (m_shutdownRecv)
918  {
919  return;
920  }
921 
922  // Should check via getsockopt ()..
923  if (IsRecvPktInfo ())
924  {
925  Ipv4PacketInfoTag tag;
926  packet->RemovePacketTag (tag);
927  tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ());
928  packet->AddPacketTag (tag);
929  }
930 
931  //Check only version 4 options
932  if (IsIpRecvTos ())
933  {
934  SocketIpTosTag ipTosTag;
935  ipTosTag.SetTos (header.GetTos ());
936  packet->AddPacketTag (ipTosTag);
937  }
938 
939  if (IsIpRecvTtl ())
940  {
941  SocketIpTtlTag ipTtlTag;
942  ipTtlTag.SetTtl (header.GetTtl ());
943  packet->AddPacketTag (ipTtlTag);
944  }
945 
946  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
947  {
949  SocketAddressTag tag;
950  tag.SetAddress (address);
951  packet->AddPacketTag (tag);
952  m_deliveryQueue.push (packet);
953  m_rxAvailable += packet->GetSize ();
954  NotifyDataRecv ();
955  }
956  else
957  {
958  // In general, this case should not occur unless the
959  // receiving application reads data from this socket slowly
960  // in comparison to the arrival rate
961  //
962  // drop and trace packet
963  NS_LOG_WARN ("No receive buffer space available. Drop.");
964  m_dropTrace (packet);
965  }
966 }
967 
968 void
969 UdpSocketImpl::ForwardUp6 (Ptr<Packet> packet, Ipv6Header header, uint16_t port, Ptr<Ipv6Interface> incomingInterface)
970 {
971  NS_LOG_FUNCTION (this << packet << header.GetSourceAddress () << port);
972 
973  if (m_shutdownRecv)
974  {
975  return;
976  }
977 
978  // Should check via getsockopt ()..
979  if (IsRecvPktInfo ())
980  {
981  Ipv6PacketInfoTag tag;
982  packet->RemovePacketTag (tag);
983  tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ());
984  packet->AddPacketTag (tag);
985  }
986 
987  //Check only version 6 options
988  if (IsIpv6RecvTclass ())
989  {
990  SocketIpv6TclassTag ipTclassTag;
991  ipTclassTag.SetTclass (header.GetTrafficClass ());
992  packet->AddPacketTag (ipTclassTag);
993  }
994 
995  if (IsIpv6RecvHopLimit ())
996  {
997  SocketIpv6HopLimitTag ipHopLimitTag;
998  ipHopLimitTag.SetHopLimit (header.GetHopLimit ());
999  packet->AddPacketTag (ipHopLimitTag);
1000  }
1001 
1002  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
1003  {
1005  SocketAddressTag tag;
1006  tag.SetAddress (address);
1007  packet->AddPacketTag (tag);
1008  m_deliveryQueue.push (packet);
1009  m_rxAvailable += packet->GetSize ();
1010  NotifyDataRecv ();
1011  }
1012  else
1013  {
1014  // In general, this case should not occur unless the
1015  // receiving application reads data from this socket slowly
1016  // in comparison to the arrival rate
1017  //
1018  // drop and trace packet
1019  NS_LOG_WARN ("No receive buffer space available. Drop.");
1020  m_dropTrace (packet);
1021  }
1022 }
1023 
1024 void
1025 UdpSocketImpl::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
1026  uint8_t icmpType, uint8_t icmpCode,
1027  uint32_t icmpInfo)
1028 {
1029  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
1030  (uint32_t)icmpCode << icmpInfo);
1031  if (!m_icmpCallback.IsNull ())
1032  {
1033  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1034  }
1035 }
1036 
1037 void
1038 UdpSocketImpl::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
1039  uint8_t icmpType, uint8_t icmpCode,
1040  uint32_t icmpInfo)
1041 {
1042  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
1043  (uint32_t)icmpCode << icmpInfo);
1044  if (!m_icmpCallback6.IsNull ())
1045  {
1046  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
1047  }
1048 }
1049 
1050 void
1052 {
1053  m_rcvBufSize = size;
1054 }
1055 
1056 uint32_t
1058 {
1059  return m_rcvBufSize;
1060 }
1061 
1062 void
1064 {
1065  m_ipMulticastTtl = ipTtl;
1066 }
1067 
1068 uint8_t
1070 {
1071  return m_ipMulticastTtl;
1072 }
1073 
1074 void
1076 {
1077  m_ipMulticastIf = ipIf;
1078 }
1079 
1080 int32_t
1082 {
1083  return m_ipMulticastIf;
1084 }
1085 
1086 void
1088 {
1089  m_ipMulticastLoop = loop;
1090 }
1091 
1092 bool
1094 {
1095  return m_ipMulticastLoop;
1096 }
1097 
1098 void
1100 {
1101  m_mtuDiscover = discover;
1102 }
1103 bool
1105 {
1106  return m_mtuDiscover;
1107 }
1108 
1109 bool
1111 {
1112  m_allowBroadcast = allowBroadcast;
1113  return true;
1114 }
1115 
1116 bool
1118 {
1119  return m_allowBroadcast;
1120 }
1121 
1122 
1123 } // 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:52
bool m_shutdownSend
Send no longer allowed.
void SetTclass(uint8_t tclass)
Set the tag's Tclass.
Definition: socket.cc:821
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:383
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)
Definition: log.h:345
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:508
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:471
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:404
This class implements a tag that carries the socket-specific HOPLIMIT of a packet to the IPv6 layer...
Definition: socket.h:1044
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:79
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:305
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)
Set the reception callback.
Ptr< Packet > Recv(void)
Read a single packet from the socket.
Definition: socket.cc:175
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:523
Ipv4Address GetDestination(void) const
Definition: ipv4-header.cc:304
virtual int Close(void)
Close a socket.
#define NS_ASSERT(condition)
Definition: assert.h:64
static Ipv6Address GetAny()
Get the "any" (::) Ipv6Address.
NS_OBJECT_ENSURE_REGISTERED(NullMessageSimulatorImpl)
virtual uint8_t GetIpMulticastTtl(void) const
Get the IP multicast TTL.
uint32_t GetSize(void) const
Definition: packet.h:650
void SetNextHeader(uint8_t next)
Set the "Next header" field.
Definition: ipv6-header.cc:77
bool IsManualIpTos(void) const
Checks if the socket has a specific IPv4 ToS set.
Definition: socket.cc:371
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:496
Ipv4Address GetSource(void) const
Definition: ipv4-header.cc:291
#define NS_LOG_FUNCTION_NOARGS()
Output the name of the function.
Definition: log.h:309
void SetProtocol(uint8_t num)
Definition: ipv4-header.cc:278
void SetTos(uint8_t tos)
Set the tag's TOS.
Definition: socket.cc:765
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:364
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:1658
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:416
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:584
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:1238
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:377
void NotifyDataSent(uint32_t size)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:285
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)
Definition: log.h:368
int FinishBind(void)
Finish the binding process.
void SetHopLimit(uint8_t hopLimit)
Set the tag's Hop Limit.
Definition: socket.cc:645
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:217
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
Checks if the socket has a specific IPv6 Hop Limit set.
Definition: socket.cc:389
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:92
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)
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:446
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:458
virtual void BindToNetDevice(Ptr< NetDevice > netdevice)
Bind a socket to specific device.
Definition: socket.cc:330
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:97
bool IsIpRecvTtl(void) const
Ask if the socket is currently passing information about IP_TTL up the stack.
Definition: socket.cc:483
void Disable(void)
Disables the DF (Don't Fragment) flag.
Definition: socket.cc:706
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)
Definition: log.h:280
Ptr< NetDevice > GetDevice(void) const
Address GetAddress(void) const
Get the tag's address.
Definition: socket.cc:530
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:102
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:700
uint16_t GetPort(void) const
Get the port.
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)
Definition: log.h:271
uint16_t GetPort(void) const
uint8_t GetTtl(void) const
Definition: ipv4-header.cc:265
uint8_t GetTos(void) const
Definition: ipv4-header.cc:195
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:361
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:107
void NotifySend(uint32_t spaceAvailable)
Notify through the callback (if set) that some data have been sent.
Definition: socket.cc:295
TypeId SetParent(TypeId tid)
Definition: type-id.cc:611
void SetRecvIf(uint32_t ifindex)
Set the tag's receiving interface.
static bool IsMatchingType(const Address &address)
NS_LOG_COMPONENT_DEFINE("UdpSocketImpl")
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:112
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.