• ns3_AODV 源码阅读1:RouteOutput和RouteInput是什么


    运行脚本aodv.cc 可以得到以下log输出

    RouteOutput:

    主动发包时调用的(它在找到路由的时候返回路由地址)

    而这里没有找到路由,所以返回了loopback,也就是本机地址,于是数据包又发回了本机。

    RouteInput:

    收到包转发时调用的,在这里调用loopback发给自己后

    node0就从发包着变成了收包者,然后再进行转发

    以及调用DeferredRouteOutput(它又调用SendRequest)发送RREQ

    这样复用了RouteInput,从而简化了RouteOutput的操作,只进行路由查询,查询不到的情况下和转发函数合并为RouteInput,不需要在主动发起时考虑如何发出去了(广播啥的)

    将发包和收包时的路由请求过程合并

    
    
    Ptr<Ipv4Route>
    RoutingProtocol::RouteOutput (Ptr<Packet> p, const Ipv4Header &header,
                                  Ptr<NetDevice> oif, Socket::SocketErrno &sockerr)
    {
      NS_LOG_FUNCTION (this << header << (oif ? oif->GetIfIndex () : 0));
      if (!p)
        {
          NS_LOG_DEBUG("Packet is == 0");
          return LoopbackRoute (header, oif); // later
        }
      if (m_socketAddresses.empty ())
        {
          sockerr = Socket::ERROR_NOROUTETOHOST;
          NS_LOG_LOGIC ("No aodv interfaces");
          Ptr<Ipv4Route> route;
          return route;
        }
      sockerr = Socket::ERROR_NOTERROR;
      Ptr<Ipv4Route> route;
      Ipv4Address dst = header.GetDestination ();
      RoutingTableEntry rt;
      if (m_routingTable.LookupValidRoute (dst, rt))
        {//找到路由则返回路由
          route = rt.GetRoute ();
          NS_ASSERT (route != 0);
          NS_LOG_DEBUG ("Exist route to " << route->GetDestination () << " from interface " << route->GetSource ());
          if (oif != 0 && route->GetOutputDevice () != oif)
            {
              NS_LOG_DEBUG ("Output device doesn't match. Dropped.");
              sockerr = Socket::ERROR_NOROUTETOHOST;
              return Ptr<Ipv4Route> ();
            }
          UpdateRouteLifeTime (dst, m_activeRouteTimeout);
          UpdateRouteLifeTime (route->GetGateway (), m_activeRouteTimeout);
          return route;
        }
    
      // 没有找到有效的路由,在这种情况下我们返回loopback。Valid route not found, in this case we return loopback. 
      //实际路径请求将被推迟,直到包将完全形成, Actual route request will be deferred until packet will be fully formed, 
      // 路由到loopback,从loopback接收并传递到RouteInput(见下文)routed to loopback, received from loopback and passed to RouteInput (see below)
      uint32_t iif = (oif ? m_ipv4->GetInterfaceForDevice (oif) : -1);
      DeferredRouteOutputTag tag (iif);
      NS_LOG_DEBUG ("Valid Route not found");
      if (!p->PeekPacketTag (tag))
        {
          p->AddPacketTag (tag);
        }
      return LoopbackRoute (header, oif);
    }
    
    
    bool
    RoutingProtocol::RouteInput (Ptr<const Packet> p, const Ipv4Header &header,
                                 Ptr<const NetDevice> idev, UnicastForwardCallback ucb,
                                 MulticastForwardCallback mcb, LocalDeliverCallback lcb, ErrorCallback ecb)
    {//CALLBACK,回调函数就是一个通过函数指针调用的函数。
        //(虽然这里是类)
        //如果你把函数的指针(地址)作为参数传递给另一个函数,
        //当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
        //回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
      NS_LOG_FUNCTION (this << p->GetUid () << header.GetDestination () << idev->GetAddress ());
      if (m_socketAddresses.empty ())
        {
          NS_LOG_LOGIC ("No aodv interfaces");//没有aodv接口
          return false;
        }
      NS_ASSERT (m_ipv4 != 0);
      NS_ASSERT (p != 0);
      // 检查输入设备是否支持IP Check if input device supports IP
      NS_ASSERT (m_ipv4->GetInterfaceForDevice (idev) >= 0);
      int32_t iif = m_ipv4->GetInterfaceForDevice (idev);
    
      Ipv4Address dst = header.GetDestination ();
      Ipv4Address origin = header.GetSource ();
    
      // 延迟的路由请求Deferred route request
      if (idev == m_lo)
        {
          DeferredRouteOutputTag tag;
          if (p->PeekPacketTag (tag))
            {
              DeferredRouteOutput (p, header, ucb, ecb);
              //当一个节点无法找到一个可用的到某个节点的路由时,它就会广播一条 RREQ 消息。
              return true;
            }
        }
    
      // 重复自己的数据包 Duplicate of own packet
      if (IsMyOwnAddress (origin))
        return true;
    
      // AODV不是多播路由协议 AODV is not a multicast routing protocol
      if (dst.IsMulticast ())
        {
          return false; 
        }
    
      // 广播本地交付/转发 Broadcast local delivery/forwarding
      for (std::map<Ptr<Socket>, Ipv4InterfaceAddress>::const_iterator j =
             m_socketAddresses.begin (); j != m_socketAddresses.end (); ++j)
        {
          Ipv4InterfaceAddress iface = j->second;
          if (m_ipv4->GetInterfaceForAddress (iface.GetLocal ()) == iif)
            if (dst == iface.GetBroadcast () || dst.IsBroadcast ())
              {
                if (m_dpd.IsDuplicate (p, header))
                  {//重复数据包p from Source,Drop
                    NS_LOG_DEBUG ("Duplicated packet " << p->GetUid () << " from " << origin << ". Drop.");
                    return true;
                  }
                UpdateRouteLifeTime (origin, m_activeRouteTimeout);
                Ptr<Packet> packet = p->Copy ();
                if (lcb.IsNull () == false)
                  {//广播本地交付to  iface.GetLocal 
                    NS_LOG_LOGIC ("Broadcast local delivery to " << iface.GetLocal ());
                    lcb (p, header, iif);
                    // 通过追加处理 Fall through to additional processing
                  }
                else
                  {//由于null callback ,无法在本地传递数据包 
                    NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
                    ecb (p, header, Socket::ERROR_NOROUTETOHOST);
                  }
                if (!m_enableBroadcast)
                  {
                    return true;
                  }
                if (header.GetProtocol () == UdpL4Protocol::PROT_NUMBER)
                  {
                    UdpHeader udpHeader;
                    p->PeekHeader (udpHeader);
                    if (udpHeader.GetDestinationPort () == AODV_PORT)
                      {
                        // 广播发送的AODV数据包已经被管理 AODV packets sent in broadcast are already managed
                        return true;
                      }
                  }
                if (header.GetTtl () > 1)
                  {//转发广播。 TTL=header.GetTtl ()
                    NS_LOG_LOGIC ("Forward broadcast. TTL " << (uint16_t) header.GetTtl ());
                    RoutingTableEntry toBroadcast;
                    if (m_routingTable.LookupRoute (dst, toBroadcast))
                      {
                        Ptr<Ipv4Route> route = toBroadcast.GetRoute ();
                        ucb (route, packet, header);
                      }
                    else
                      {//没有路由转发广播。 丢弃数据包
                        NS_LOG_DEBUG ("No route to forward broadcast. Drop packet " << p->GetUid ());
                      }
                  }
                else
                  {//TTL超出。 丢弃数据包
                    NS_LOG_DEBUG ("TTL exceeded. Drop packet " << p->GetUid ());
                  }
                return true;
              }
        }
    
      // 单播本地交付Unicast local delivery
      if (m_ipv4->IsDestinationAddress (dst, iif))
        {
          UpdateRouteLifeTime (origin, m_activeRouteTimeout);
          RoutingTableEntry toOrigin;
          if (m_routingTable.LookupValidRoute (origin, toOrigin))
            {
              UpdateRouteLifeTime (toOrigin.GetNextHop (), m_activeRouteTimeout);
              m_nb.Update (toOrigin.GetNextHop (), m_activeRouteTimeout);
            }
          if (lcb.IsNull () == false)
            {//单播本地交付到dst
              NS_LOG_LOGIC ("Unicast local delivery to " << dst);
              lcb (p, header, iif);
            }
          else
            {//由于null回调,无法在本地交付数据包
              NS_LOG_ERROR ("Unable to deliver packet locally due to null callback " << p->GetUid () << " from " << origin);
              ecb (p, header, Socket::ERROR_NOROUTETOHOST);
            }
          return true;
        }
    
      // 检查输入设备是否支持IP转发Check if input device supports IP forwarding
      if (m_ipv4->IsForwarding (iif) == false)
        {
          NS_LOG_LOGIC ("Forwarding disabled for this interface");
          ecb (p, header, Socket::ERROR_NOROUTETOHOST);
          return true;
        }
    
      // 转发Forwarding
      return Forwarding (p, header, ucb, ecb);
    }
    
    
  • 相关阅读:
    Prince and princess「DP优化」
    Wooden Stricks——两个递增条件的线性DP
    死磕 java线程系列之线程池深入解析——构造方法
    死磕 java线程系列之线程池深入解析——体系结构
    死磕 java线程系列之自己动手写一个线程池(续)
    死磕 java线程系列之自己动手写一个线程池
    死磕 java线程系列之创建线程的8种方式
    死磕 java线程系列之线程模型
    死磕 java同步系列之终结篇
    死磕 java同步系列之redis分布式锁进化史
  • 原文地址:https://www.cnblogs.com/cyf1995/p/6593078.html
Copyright © 2020-2023  润新知