Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::Lookup()

in simulation/src/internet/model/ipv6-end-point-demux.cc [172:289]


Ipv6EndPointDemux::EndPoints Ipv6EndPointDemux::Lookup (Ipv6Address daddr, uint16_t dport,
                                                        Ipv6Address saddr, uint16_t sport,
                                                        Ptr<Ipv6Interface> incomingInterface)
{
  NS_LOG_FUNCTION (this << daddr << dport << saddr << sport << incomingInterface);

  EndPoints retval1; /* Matches exact on local port, wildcards on others */
  EndPoints retval2; /* Matches exact on local port/adder, wildcards on others */
  EndPoints retval3; /* Matches all but local address */
  EndPoints retval4; /* Exact match on all 4 */

  NS_LOG_DEBUG ("Looking up endpoint for destination address " << daddr);
  for (EndPointsI i = m_endPoints.begin (); i != m_endPoints.end (); i++)
    {
      Ipv6EndPoint* endP = *i;

      NS_LOG_DEBUG ("Looking at endpoint dport=" << endP->GetLocalPort ()
                                                 << " daddr=" << endP->GetLocalAddress ()
                                                 << " sport=" << endP->GetPeerPort ()
                                                 << " saddr=" << endP->GetPeerAddress ());

      if (!endP->IsRxEnabled ())
        {
          NS_LOG_LOGIC ("Skipping endpoint " << &endP
                        << " because endpoint can not receive packets");
          continue;
        }

      if (endP->GetLocalPort () != dport)
        {
          NS_LOG_LOGIC ("Skipping endpoint " << &endP
                                             << " because endpoint dport "
                                             << endP->GetLocalPort ()
                                             << " does not match packet dport " << dport);
          continue;
        }

      if (endP->GetBoundNetDevice ())
        {
          if (!incomingInterface)
            {
              continue;
            }
          if (endP->GetBoundNetDevice () != incomingInterface->GetDevice ())
            {
              NS_LOG_LOGIC ("Skipping endpoint " << &endP
                                                 << " because endpoint is bound to specific device and"
                                                 << endP->GetBoundNetDevice ()
                                                 << " does not match packet device " << incomingInterface->GetDevice ());
              continue;
            }
        }

      /*    Ipv6Address incomingInterfaceAddr = incomingInterface->GetAddress (); */
      NS_LOG_DEBUG ("dest addr " << daddr);

      bool localAddressMatchesWildCard = endP->GetLocalAddress () == Ipv6Address::GetAny ();
      bool localAddressMatchesExact = endP->GetLocalAddress () == daddr;
      bool localAddressMatchesAllRouters = endP->GetLocalAddress () == Ipv6Address::GetAllRoutersMulticast ();

      /* if no match here, keep looking */
      if (!(localAddressMatchesExact || localAddressMatchesWildCard))
        {
          continue;
        }
      bool remotePeerMatchesExact = endP->GetPeerPort () == sport;
      bool remotePeerMatchesWildCard = endP->GetPeerPort () == 0;
      bool remoteAddressMatchesExact = endP->GetPeerAddress () == saddr;
      bool remoteAddressMatchesWildCard = endP->GetPeerAddress () == Ipv6Address::GetAny ();

      /* If remote does not match either with exact or wildcard,i
         skip this one */
      if (!(remotePeerMatchesExact || remotePeerMatchesWildCard))
        {
          continue;
        }
      if (!(remoteAddressMatchesExact || remoteAddressMatchesWildCard))
        {
          continue;
        }

      /* Now figure out which return list to add this one to */
      if (localAddressMatchesWildCard
          && remotePeerMatchesWildCard
          && remoteAddressMatchesWildCard)
        { /* Only local port matches exactly */
          retval1.push_back (endP);
        }
      if ((localAddressMatchesExact || (localAddressMatchesAllRouters))
          && remotePeerMatchesWildCard
          && remoteAddressMatchesWildCard)
        { /* Only local port and local address matches exactly */
          retval2.push_back (endP);
        }
      if (localAddressMatchesWildCard
          && remotePeerMatchesExact
          && remoteAddressMatchesExact)
        { /* All but local address */
          retval3.push_back (endP);
        }
      if (localAddressMatchesExact
          && remotePeerMatchesExact
          && remoteAddressMatchesExact)
        { /* All 4 match */
          retval4.push_back (endP);
        }
    }

  // Here we find the most exact match
  EndPoints retval;
  if (!retval4.empty ()) retval = retval4;
  else if (!retval3.empty ()) retval = retval3;
  else if (!retval2.empty ()) retval = retval2;
  else retval = retval1;

  NS_ABORT_MSG_IF (retval.size () > 1, "Too many endpoints - perhaps you created too many sockets without binding them to different NetDevices.");
  return retval;  // might be empty if no matches
}