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; } }
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()); }