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 
89  // XXX todo: leave any multicast groups that have been joined
90  m_node = 0;
96  if (m_endPoint != 0)
97  {
98  NS_ASSERT (m_udp != 0);
107  NS_ASSERT (m_endPoint != 0);
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);
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 {
217  return FinishBind ();
218 }
219 
220 int
221 UdpSocketImpl::Bind (const Address &address)
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  {
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  return DoSend (p);
355 }
356 
357 int
359 {
360  NS_LOG_FUNCTION (this << p);
362  {
363  if (Bind () == -1)
364  {
365  NS_ASSERT (m_endPoint == 0);
366  return -1;
367  }
368  NS_ASSERT (m_endPoint != 0);
369  }
371  {
372  if (Bind6 () == -1)
373  {
374  NS_ASSERT (m_endPoint6 == 0);
375  return -1;
376  }
377  NS_ASSERT (m_endPoint6 != 0);
378  }
379  if (m_shutdownSend)
380  {
382  return -1;
383  }
384 
385  return DoSendTo (p, (const Address)m_defaultAddress);
386 }
387 
388 int
390 {
391  NS_LOG_FUNCTION (this << p << address);
392 
393  if (!m_connected)
394  {
395  NS_LOG_LOGIC ("Not connected");
396  if (InetSocketAddress::IsMatchingType(address) == true)
397  {
399  Ipv4Address ipv4 = transport.GetIpv4 ();
400  uint16_t port = transport.GetPort ();
401  return DoSendTo (p, ipv4, port);
402  }
403  else if (Inet6SocketAddress::IsMatchingType(address) == true)
404  {
406  Ipv6Address ipv6 = transport.GetIpv6 ();
407  uint16_t port = transport.GetPort ();
408  return DoSendTo (p, ipv6, port);
409  }
410  else
411  {
412  return -1;
413  }
414  }
415  else
416  {
417  // connected UDP socket must use default addresses
418  NS_LOG_LOGIC ("Connected");
420  {
422  }
424  {
426  }
427  }
429  return(-1);
430 }
431 
432 int
434 {
435  NS_LOG_FUNCTION (this << p << dest << port);
436  if (m_boundnetdevice)
437  {
438  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
439  }
440  if (m_endPoint == 0)
441  {
442  if (Bind () == -1)
443  {
444  NS_ASSERT (m_endPoint == 0);
445  return -1;
446  }
447  NS_ASSERT (m_endPoint != 0);
448  }
449  if (m_shutdownSend)
450  {
452  return -1;
453  }
454 
455  if (p->GetSize () > GetTxAvailable () )
456  {
458  return -1;
459  }
460 
461  Ptr<Ipv4> ipv4 = m_node->GetObject<Ipv4> ();
462 
463  // Locally override the IP TTL for this socket
464  // We cannot directly modify the TTL at this stage, so we set a Packet tag
465  // The destination can be either multicast, unicast/anycast, or
466  // either all-hosts broadcast or limited (subnet-directed) broadcast.
467  // For the latter two broadcast types, the TTL will later be set to one
468  // irrespective of what is set in these socket options. So, this tagging
469  // may end up setting the TTL of a limited broadcast packet to be
470  // the same as a unicast, but it will be fixed further down the stack
471  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
472  {
473  SocketIpTtlTag tag;
474  tag.SetTtl (m_ipMulticastTtl);
475  p->AddPacketTag (tag);
476  }
477  else if (m_ipTtl != 0 && !dest.IsMulticast () && !dest.IsBroadcast ())
478  {
479  SocketIpTtlTag tag;
480  tag.SetTtl (m_ipTtl);
481  p->AddPacketTag (tag);
482  }
483  {
485  bool found = p->RemovePacketTag (tag);
486  if (!found)
487  {
488  if (m_mtuDiscover)
489  {
490  tag.Enable ();
491  }
492  else
493  {
494  tag.Disable ();
495  }
496  p->AddPacketTag (tag);
497  }
498  }
499  //
500  // If dest is set to the limited broadcast address (all ones),
501  // convert it to send a copy of the packet out of every
502  // interface as a subnet-directed broadcast.
503  // Exception: if the interface has a /32 address, there is no
504  // valid subnet-directed broadcast, so send it as limited broadcast
505  // Note also that some systems will only send limited broadcast packets
506  // out of the "default" interface; here we send it out all interfaces
507  //
508  if (dest.IsBroadcast ())
509  {
510  if (!m_allowBroadcast)
511  {
513  return -1;
514  }
515  NS_LOG_LOGIC ("Limited broadcast start.");
516  for (uint32_t i = 0; i < ipv4->GetNInterfaces (); i++ )
517  {
518  // Get the primary address
519  Ipv4InterfaceAddress iaddr = ipv4->GetAddress (i, 0);
520  Ipv4Address addri = iaddr.GetLocal ();
521  if (addri == Ipv4Address ("127.0.0.1"))
522  continue;
523  // Check if interface-bound socket
524  if (m_boundnetdevice)
525  {
526  if (ipv4->GetNetDevice (i) != m_boundnetdevice)
527  continue;
528  }
529  Ipv4Mask maski = iaddr.GetMask ();
530  if (maski == Ipv4Mask::GetOnes ())
531  {
532  // if the network mask is 255.255.255.255, do not convert dest
533  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << dest
534  << " (mask is " << maski << ")");
535  m_udp->Send (p->Copy (), addri, dest,
537  NotifyDataSent (p->GetSize ());
539  }
540  else
541  {
542  // Convert to subnet-directed broadcast
543  Ipv4Address bcast = addri.GetSubnetDirectedBroadcast (maski);
544  NS_LOG_LOGIC ("Sending one copy from " << addri << " to " << bcast
545  << " (mask is " << maski << ")");
546  m_udp->Send (p->Copy (), addri, bcast,
548  NotifyDataSent (p->GetSize ());
550  }
551  }
552  NS_LOG_LOGIC ("Limited broadcast end.");
553  return p->GetSize ();
554  }
556  {
557  m_udp->Send (p->Copy (), m_endPoint->GetLocalAddress (), dest,
558  m_endPoint->GetLocalPort (), port, 0);
559  NotifyDataSent (p->GetSize ());
561  return p->GetSize ();
562  }
563  else if (ipv4->GetRoutingProtocol () != 0)
564  {
565  Ipv4Header header;
566  header.SetDestination (dest);
568  Socket::SocketErrno errno_;
569  Ptr<Ipv4Route> route;
570  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
571  // TBD-- we could cache the route and just check its validity
572  route = ipv4->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
573  if (route != 0)
574  {
575  NS_LOG_LOGIC ("Route exists");
576  if (!m_allowBroadcast)
577  {
578  uint32_t outputIfIndex = ipv4->GetInterfaceForDevice (route->GetOutputDevice ());
579  uint32_t ifNAddr = ipv4->GetNAddresses (outputIfIndex);
580  for (uint32_t addrI = 0; addrI < ifNAddr; ++addrI)
581  {
582  Ipv4InterfaceAddress ifAddr = ipv4->GetAddress (outputIfIndex, addrI);
583  if (dest == ifAddr.GetBroadcast ())
584  {
586  return -1;
587  }
588  }
589  }
590 
591  header.SetSource (route->GetSource ());
592  m_udp->Send (p->Copy (), header.GetSource (), header.GetDestination (),
593  m_endPoint->GetLocalPort (), port, route);
594  NotifyDataSent (p->GetSize ());
595  return p->GetSize ();
596  }
597  else
598  {
599  NS_LOG_LOGIC ("No route to destination");
600  NS_LOG_ERROR (errno_);
601  m_errno = errno_;
602  return -1;
603  }
604  }
605  else
606  {
607  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
609  return -1;
610  }
611 
612  return 0;
613 }
614 
615 int
617 {
618  NS_LOG_FUNCTION (this << p << dest << port);
619 
620  if (dest.IsIpv4MappedAddress ())
621  {
622  return (DoSendTo(p, dest.GetIpv4MappedAddress (), port));
623  }
624  if (m_boundnetdevice)
625  {
626  NS_LOG_LOGIC ("Bound interface number " << m_boundnetdevice->GetIfIndex ());
627  }
628  if (m_endPoint6 == 0)
629  {
630  if (Bind6 () == -1)
631  {
632  NS_ASSERT (m_endPoint6 == 0);
633  return -1;
634  }
635  NS_ASSERT (m_endPoint6 != 0);
636  }
637  if (m_shutdownSend)
638  {
640  return -1;
641  }
642 
643  if (p->GetSize () > GetTxAvailable () )
644  {
646  return -1;
647  }
648 
649  Ptr<Ipv6> ipv6 = m_node->GetObject<Ipv6> ();
650 
651  // Locally override the IP TTL for this socket
652  // We cannot directly modify the TTL at this stage, so we set a Packet tag
653  // The destination can be either multicast, unicast/anycast, or
654  // either all-hosts broadcast or limited (subnet-directed) broadcast.
655  // For the latter two broadcast types, the TTL will later be set to one
656  // irrespective of what is set in these socket options. So, this tagging
657  // may end up setting the TTL of a limited broadcast packet to be
658  // the same as a unicast, but it will be fixed further down the stack
659  if (m_ipMulticastTtl != 0 && dest.IsMulticast ())
660  {
661  SocketIpTtlTag tag;
662  tag.SetTtl (m_ipMulticastTtl);
663  p->AddPacketTag (tag);
664  }
665  else if (m_ipTtl != 0 && !dest.IsMulticast ())
666  {
667  SocketIpTtlTag tag;
668  tag.SetTtl (m_ipTtl);
669  p->AddPacketTag (tag);
670  }
671  // There is no analgous to an IPv4 broadcast address in IPv6.
672  // Instead, we use a set of link-local, site-local, and global
673  // multicast addresses. The Ipv6 routing layers should all
674  // provide an interface-specific route to these addresses such
675  // that we can treat these multicast addresses as "not broadcast"
676 
678  {
679  m_udp->Send (p->Copy (), m_endPoint6->GetLocalAddress (), dest,
680  m_endPoint6->GetLocalPort (), port, 0);
681  NotifyDataSent (p->GetSize ());
683  return p->GetSize ();
684  }
685  else if (ipv6->GetRoutingProtocol () != 0)
686  {
687  Ipv6Header header;
688  header.SetDestinationAddress (dest);
690  Socket::SocketErrno errno_;
691  Ptr<Ipv6Route> route;
692  Ptr<NetDevice> oif = m_boundnetdevice; //specify non-zero if bound to a specific device
693  // TBD-- we could cache the route and just check its validity
694  route = ipv6->GetRoutingProtocol ()->RouteOutput (p, header, oif, errno_);
695  if (route != 0)
696  {
697  NS_LOG_LOGIC ("Route exists");
698  header.SetSourceAddress (route->GetSource ());
699  m_udp->Send (p->Copy (), header.GetSourceAddress (), header.GetDestinationAddress (),
700  m_endPoint6->GetLocalPort (), port, route);
701  NotifyDataSent (p->GetSize ());
702  return p->GetSize ();
703  }
704  else
705  {
706  NS_LOG_LOGIC ("No route to destination");
707  NS_LOG_ERROR (errno_);
708  m_errno = errno_;
709  return -1;
710  }
711  }
712  else
713  {
714  NS_LOG_ERROR ("ERROR_NOROUTETOHOST");
716  return -1;
717  }
718 
719  return 0;
720 }
721 
722 // XXX maximum message size for UDP broadcast is limited by MTU
723 // size of underlying link; we are not checking that now.
724 uint32_t
726 {
728  // No finite send buffer is modelled, but we must respect
729  // the maximum size of an IP datagram (65535 bytes - headers).
731 }
732 
733 int
734 UdpSocketImpl::SendTo (Ptr<Packet> p, uint32_t flags, const Address &address)
735 {
736  NS_LOG_FUNCTION (this << p << flags << address);
737  if (InetSocketAddress::IsMatchingType (address))
738  {
740  Ipv4Address ipv4 = transport.GetIpv4 ();
741  uint16_t port = transport.GetPort ();
742  return DoSendTo (p, ipv4, port);
743  }
744  else if (Inet6SocketAddress::IsMatchingType (address))
745  {
747  Ipv6Address ipv6 = transport.GetIpv6 ();
748  uint16_t port = transport.GetPort ();
749  return DoSendTo (p, ipv6, port);
750  }
751  return -1;
752 }
753 
754 uint32_t
756 {
758  // We separately maintain this state to avoid walking the queue
759  // every time this might be called
760  return m_rxAvailable;
761 }
762 
764 UdpSocketImpl::Recv (uint32_t maxSize, uint32_t flags)
765 {
766  NS_LOG_FUNCTION (this << maxSize << flags);
767  if (m_deliveryQueue.empty () )
768  {
770  return 0;
771  }
772  Ptr<Packet> p = m_deliveryQueue.front ();
773  if (p->GetSize () <= maxSize)
774  {
775  m_deliveryQueue.pop ();
776  m_rxAvailable -= p->GetSize ();
777  }
778  else
779  {
780  p = 0;
781  }
782  return p;
783 }
784 
786 UdpSocketImpl::RecvFrom (uint32_t maxSize, uint32_t flags,
787  Address &fromAddress)
788 {
789  NS_LOG_FUNCTION (this << maxSize << flags);
790  Ptr<Packet> packet = Recv (maxSize, flags);
791  if (packet != 0)
792  {
793  SocketAddressTag tag;
794  bool found;
795  found = packet->PeekPacketTag (tag);
796  NS_ASSERT (found);
797  fromAddress = tag.GetAddress ();
798  }
799  return packet;
800 }
801 
802 int
804 {
806  if (m_endPoint != 0)
807  {
809  }
810  else
811  {
812  // It is possible to call this method on a socket without a name
813  // in which case, behavior is unspecified
814  address = InetSocketAddress (Ipv4Address::GetZero (), 0);
815  }
816  return 0;
817 }
818 
819 int
820 UdpSocketImpl::MulticastJoinGroup (uint32_t interface, const Address &groupAddress)
821 {
822  NS_LOG_FUNCTION (interface << groupAddress);
823  /*
824  1) sanity check interface
825  2) sanity check that it has not been called yet on this interface/group
826  3) determine address family of groupAddress
827  4) locally store a list of (interface, groupAddress)
828  5) call ipv4->MulticastJoinGroup () or Ipv6->MulticastJoinGroup ()
829  */
830  return 0;
831 }
832 
833 int
834 UdpSocketImpl::MulticastLeaveGroup (uint32_t interface, const Address &groupAddress)
835 {
836  NS_LOG_FUNCTION (interface << groupAddress);
837  /*
838  1) sanity check interface
839  2) determine address family of groupAddress
840  3) delete from local list of (interface, groupAddress); raise a LOG_WARN
841  if not already present (but return 0)
842  5) call ipv4->MulticastLeaveGroup () or Ipv6->MulticastLeaveGroup ()
843  */
844  return 0;
845 }
846 
847 void
849 {
850  NS_LOG_FUNCTION (netdevice);
851  Socket::BindToNetDevice (netdevice); // Includes sanity check
852  if (m_endPoint == 0)
853  {
854  if (Bind () == -1)
855  {
856  NS_ASSERT (m_endPoint == 0);
857  return;
858  }
859  NS_ASSERT (m_endPoint != 0);
860  }
861  m_endPoint->BindToNetDevice (netdevice);
862  return;
863 }
864 
865 void
867  Ptr<Ipv4Interface> incomingInterface)
868 {
869  NS_LOG_FUNCTION (this << packet << header << port);
870 
871  if (m_shutdownRecv)
872  {
873  return;
874  }
875 
876  // Should check via getsockopt ()..
877  if (IsRecvPktInfo ())
878  {
879  Ipv4PacketInfoTag tag;
880  packet->RemovePacketTag (tag);
881  tag.SetRecvIf (incomingInterface->GetDevice ()->GetIfIndex ());
882  packet->AddPacketTag (tag);
883  }
884 
885  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
886  {
887  Address address = InetSocketAddress (header.GetSource (), port);
888  SocketAddressTag tag;
889  tag.SetAddress (address);
890  packet->AddPacketTag (tag);
891  m_deliveryQueue.push (packet);
892  m_rxAvailable += packet->GetSize ();
893  NotifyDataRecv ();
894  }
895  else
896  {
897  // In general, this case should not occur unless the
898  // receiving application reads data from this socket slowly
899  // in comparison to the arrival rate
900  //
901  // drop and trace packet
902  NS_LOG_WARN ("No receive buffer space available. Drop.");
903  m_dropTrace (packet);
904  }
905 }
906 
907 void
909 {
910  NS_LOG_FUNCTION (this << packet << saddr << port);
911 
912  if (m_shutdownRecv)
913  {
914  return;
915  }
916 
917  if ((m_rxAvailable + packet->GetSize ()) <= m_rcvBufSize)
918  {
919  Address address = Inet6SocketAddress (saddr, port);
920  SocketAddressTag tag;
921  tag.SetAddress (address);
922  packet->AddPacketTag (tag);
923  m_deliveryQueue.push (packet);
924  m_rxAvailable += packet->GetSize ();
925  NotifyDataRecv ();
926  }
927  else
928  {
929  // In general, this case should not occur unless the
930  // receiving application reads data from this socket slowly
931  // in comparison to the arrival rate
932  //
933  // drop and trace packet
934  NS_LOG_WARN ("No receive buffer space available. Drop.");
935  m_dropTrace (packet);
936  }
937 }
938 
939 void
940 UdpSocketImpl::ForwardIcmp (Ipv4Address icmpSource, uint8_t icmpTtl,
941  uint8_t icmpType, uint8_t icmpCode,
942  uint32_t icmpInfo)
943 {
944  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
945  (uint32_t)icmpCode << icmpInfo);
946  if (!m_icmpCallback.IsNull ())
947  {
948  m_icmpCallback (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
949  }
950 }
951 
952 void
953 UdpSocketImpl::ForwardIcmp6 (Ipv6Address icmpSource, uint8_t icmpTtl,
954  uint8_t icmpType, uint8_t icmpCode,
955  uint32_t icmpInfo)
956 {
957  NS_LOG_FUNCTION (this << icmpSource << (uint32_t)icmpTtl << (uint32_t)icmpType <<
958  (uint32_t)icmpCode << icmpInfo);
959  if (!m_icmpCallback6.IsNull ())
960  {
961  m_icmpCallback6 (icmpSource, icmpTtl, icmpType, icmpCode, icmpInfo);
962  }
963 }
964 
965 
966 void
968 {
969  m_rcvBufSize = size;
970 }
971 
972 uint32_t
974 {
975  return m_rcvBufSize;
976 }
977 
978 void
979 UdpSocketImpl::SetIpTtl (uint8_t ipTtl)
980 {
981  m_ipTtl = ipTtl;
982 }
983 
984 uint8_t
986 {
987  return m_ipTtl;
988 }
989 
990 void
992 {
993  m_ipMulticastTtl = ipTtl;
994 }
995 
996 uint8_t
998 {
999  return m_ipMulticastTtl;
1000 }
1001 
1002 void
1004 {
1005  m_ipMulticastIf = ipIf;
1006 }
1007 
1008 int32_t
1010 {
1011  return m_ipMulticastIf;
1012 }
1013 
1014 void
1016 {
1017  m_ipMulticastLoop = loop;
1018 }
1019 
1020 bool
1022 {
1023  return m_ipMulticastLoop;
1024 }
1025 
1026 void
1028 {
1029  m_mtuDiscover = discover;
1030 }
1031 bool
1033 {
1034  return m_mtuDiscover;
1035 }
1036 
1037 bool
1039 {
1040  m_allowBroadcast = allowBroadcast;
1041  return true;
1042 }
1043 
1044 bool
1046 {
1047  return m_allowBroadcast;
1048 }
1049 
1050 
1051 } // namespace ns3