コード例 #1
0
ファイル: Beacon.cpp プロジェクト: JakeMont/OpenBFDD
  bool Beacon::StartActiveSession(const IpAddr &remoteAddr, const IpAddr &localAddr)
  {
    Session *session = NULL;

    LogAssert(m_scheduler->IsMainThread());

    session = findInSourceMap(remoteAddr, localAddr);
    if (session)
    {
      if (session->IsActiveSession())
        return true;
      if (!session->UpgradeToActiveSession())
      {
        LogOptional(Log::Session, "Failed to upgrade Session id=%u for %s to %s is to an active session.",
                    session->GetId(),
                    localAddr.ToString(),
                    remoteAddr.ToString()
                    );
        return false;
      }


      LogOptional(Log::Session, "Session id=%u for %s to %s is now an active session.",
                  session->GetId(),
                  localAddr.ToString(),
                  remoteAddr.ToString()
                  );
      return true;
    }
    else
    {
      session = addSession(remoteAddr, localAddr);
      if (!session)
        return false;

      LogOptional(Log::Session, "Manually added new session for %s to %s id=%u.",
                  localAddr.ToString(),
                  remoteAddr.ToString(),
                  session->GetId());


      if (!session->StartActiveSession(remoteAddr, localAddr))
      {
        LogOptional(Log::Session, "Failed to start active session id=%u for %s to %s.",
                    session->GetId(),
                    localAddr.ToString(),
                    remoteAddr.ToString()
                    );
        return false;
      }

      LogOptional(Log::Session, "Session id=%u for %s to %s is started as an active session.",
                  session->GetId(),
                  localAddr.ToString(),
                  remoteAddr.ToString()
                  );
      return true;
    }
  }
コード例 #2
0
ファイル: SchedulerBase.cpp プロジェクト: Lennie/OpenBFDD
    void Stop()
    {

      LogAssert(m_scheduler->IsMainThread());

      if (m_stopped)
        LogOptional(Log::TimerDetail, "Stopping ignored on stopped timer %s", m_name);
      else
      {
        // Remove us from active timers list. (Must remove before changing timer.)
        SchedulerBase::timer_set_it found = m_activeTimers->find(this);
        if (found != m_activeTimers->end())
          m_activeTimers->erase(found);

        m_stopped = true;
        LogOptional(Log::TimerDetail, "Stopping timer %s. (%zu timers)", m_name, m_activeTimers->size());
      }
    }
コード例 #3
0
ファイル: SchedulerBase.cpp プロジェクト: Lennie/OpenBFDD
    /**
     * Called by the Scheduler to mark the timer as stopped and run its action. Will
     * Remove the timer from the active list. 
     * 
     */
    void ExpireTimer()
    {
      LogAssert(!m_stopped);

      Stop();

      LogOptional(Log::TimerDetail, "Expired timer %s calling callback", m_name);
      m_callback(this, m_userdata); 
    }
コード例 #4
0
ファイル: Beacon.cpp プロジェクト: JakeMont/OpenBFDD
  void Beacon::KillSession(Session *session)
  {

    if (!LogVerify(session))
      return;

    LogAssert(m_scheduler->IsMainThread());

    LogVerify(1 == m_discMap.erase(session->GetLocalDiscriminator()));
    LogVerify(1 == m_IdMap.erase(session->GetId()));
    LogVerify(1 == m_sourceMap.erase(SourceMapKey(session->GetRemoteAddress(), session->GetLocalAddress())));

    LogOptional(Log::Session, "Removed session %s to %s id=%d.",
                session->GetLocalAddress().ToString(),
                session->GetRemoteAddress().ToString(),
                session->GetId());

    delete session;
  }
コード例 #5
0
ファイル: SchedulerBase.cpp プロジェクト: Lennie/OpenBFDD
    /**
     * Changes the start and expire time for the timer. 
     * 
     * @param startTime - The time of the last timer start. May be m_startTime. 
     * @param micro - Time to expire from startTime in microseconds. 
     *  
     * @return bool - false on failure.  
     */
    bool setExpireTime(const struct timespec &startTime,  uint64_t micro)
    {
      bool expireChange, startChange;
      TimeSpec expireTime(startTime);

      expireTime += TimeSpec(TimeSpec::Microsec, micro);

      startChange = (m_startTime != startTime);
      expireChange = (m_stopped || m_expireTime != expireTime);

      //LogOptional(Log::Temp, "Timer %s before change %zu items",m_name, m_activeTimers->size());

      if (!expireChange && !startChange)
      {
        LogOptional(Log::TimerDetail, "Timer %s no change.  %" PRIu64 "  microseconds. Expires:%jd:%09ld", m_name, micro, (intmax_t)expireTime.tv_sec, expireTime.tv_nsec );
        return true;
      }

      LogOptional(Log::TimerDetail, "%s timer %s for %" PRIu64 " microseconds from %jd:%09ld. Expires:%jd:%09ld", 
                  m_stopped ? "Starting": startChange ? "Resetting":"Advancing", 
                  m_name, 
                  micro, 
                  (intmax_t)startTime.tv_sec, 
                  startTime.tv_nsec,
                  (intmax_t)expireTime.tv_sec, 
                  expireTime.tv_nsec 
                 );

      // Start time does not effect sorting in active timer list, so we can set it now.
      // Stopped also should not matter. 
      if (startChange)
        m_startTime = startTime;
      m_stopped = false;

      if (expireChange)
      {
        SchedulerBase::timer_set_it found = m_activeTimers->find(this);
        if (found != m_activeTimers->end())
        {
          if (!willTimerBeSorted(found, expireTime))
          {
            m_activeTimers->erase(found);
            found = m_activeTimers->end();  // cause it to be added back
          }
        }

        // Actually set the time
        m_expireTime = expireTime;

        if (found == m_activeTimers->end())
        {
          try
          {
            m_activeTimers->insert(this);
          }
          catch (std::exception &e)
          {
            m_stopped = true;
            gLog.Message(Log::Error, "Failed to add timer: %s.", e.what());
            return false;
          }
        }
      }

      //LogOptional(Log::Temp, "Timer %s after change %zu items",m_name, m_activeTimers->size()); 
      return true;
    }
コード例 #6
0
ファイル: Beacon.cpp プロジェクト: JakeMont/OpenBFDD
  void Beacon::handleListenSocket(Socket &socket)
  {
    SockAddr sourceAddr;
    IpAddr destIpAddr, sourceIpAddr;
    uint8_t ttl;
    BfdPacket packet;
    bool found;
    Session *session = NULL;

    if (!m_packet.DoRecvMsg(socket))
    {
      gLog.ErrnoError(m_packet.GetLastError(), "Error receiving on BFD listen socket");
      return;
    }

    sourceAddr = m_packet.GetSrcAddress();
    if (!LogVerify(sourceAddr.IsValid()))
      return;
    sourceIpAddr = IpAddr(sourceAddr);

    destIpAddr = m_packet.GetDestAddress();
    if (!destIpAddr.IsValid())
    {
      gLog.LogError("Could not get destination address for packet from %s.", sourceAddr.ToString());
      return;
    }

    ttl = m_packet.GetTTLorHops(&found);
    if (!found)
    {
      gLog.LogError("Could not get ttl for packet from %s.", sourceAddr.ToString());
      return;
    }

    LogOptional(Log::Packet, "Received bfd packet %zu bytes from %s to %s", m_packet.GetDataSize(), sourceAddr.ToString(), destIpAddr.ToString());

    //
    // Check ip specific stuff. See draft-ietf-bfd-v4v6-1hop-11.txt
    //

    // Port
    if (m_strictPorts)
    {
      if (sourceAddr.Port() < bfd::MinSourcePort) // max port is max value, so no need to check
      {
        LogOptional(Log::Discard, "Discard packet: bad source port %s to %s", sourceAddr.ToString(), destIpAddr.ToString());
        return;
      }
    }

    // TTL assumes that all control packets are from neighbors.
    if (ttl != 255)
    {
      gLog.Optional(Log::Discard, "Discard packet: bad ttl/hops %hhu", ttl);
      return;
    }

    if (!Session::InitialProcessControlPacket(m_packet.GetData(), m_packet.GetDataSize(), packet))
    {
      gLog.Optional(Log::Discard, "Discard packet");
      return;
    }

    // We have a (partially) valid packet ... now find the correct session.
    if (packet.header.yourDisc != 0)
    {
      DiscMapIt found = m_discMap.find(packet.header.yourDisc);
      if (found == m_discMap.end())
      {
        if (gLog.LogTypeEnabled(Log::DiscardDetail))
          Session::LogPacketContents(packet, false, true, sourceAddr, destIpAddr);

        gLog.Optional(Log::Discard, "Discard packet: no session found for yourDisc <%u>.", packet.header.yourDisc);
        return;
      }
      session = found->second;
      if (session->GetRemoteAddress() != sourceIpAddr)
      {
        if (gLog.LogTypeEnabled(Log::DiscardDetail))
          Session::LogPacketContents(packet, false, true, sourceAddr, destIpAddr);

        LogOptional(Log::Discard, "Discard packet: mismatched yourDisc <%u> and ip <from %s to %s>.", packet.header.yourDisc, sourceAddr.ToString(), destIpAddr.ToString());
        return;
      }
    }
    else
    {
      // No discriminator
      session = findInSourceMap(sourceIpAddr, destIpAddr);
      if (NULL == session)
      {
        // No session yet .. create one !?
        if (!m_allowAnyPassiveIP && m_allowedPassiveIP.find(sourceIpAddr) == m_allowedPassiveIP.end())
        {
          if (gLog.LogTypeEnabled(Log::DiscardDetail))
            Session::LogPacketContents(packet, false, true, sourceAddr, destIpAddr);

          LogOptional(Log::Discard, "Ignoring unauthorized bfd packets from %s",  sourceAddr.ToString());
          return;
        }

        session = addSession(sourceIpAddr, destIpAddr);
        if (!session)
          return;
        if (!session->StartPassiveSession(sourceAddr, destIpAddr))
        {
          gLog.LogError("Failed to add new session for local %s to remote  %s id=%d.", destIpAddr.ToString(), sourceAddr.ToString(), session->GetId());
          KillSession(session);
        }
        LogOptional(Log::Session, "Added new session for local %s to remote  %s id=%d.", destIpAddr.ToString(), sourceAddr.ToString(), session->GetId());
      }
    }

    //
    //  We have a session that can handle the rest.
    //
    session->ProcessControlPacket(packet, sourceAddr.Port());
  }