add support to disable *ALL* passing of P25 ADJ_STS_BCAST from a CFNE instance; properly implement processing of TSDU messages from any peer; implement login flag from CFNEs to identify themselves as external when they are peering;

pull/51/head
Bryan Biedenkapp 2 years ago
parent ecdce85e8a
commit 17d69cb950

@ -71,8 +71,10 @@ master:
# Flag indicating whether or not a parrot TG call will generate a grant demand. # Flag indicating whether or not a parrot TG call will generate a grant demand.
parrotGrantDemand: true parrotGrantDemand: true
# Flag indicating whether or not a P25 ADJ_STS_BCAST will pass to any peers.
disallowAdjStsBcast: false
# Flag indicating whether or not a P25 ADJ_STS_BCAST will pass to connected external peers. # Flag indicating whether or not a P25 ADJ_STS_BCAST will pass to connected external peers.
disallowP25AdjStsBcast: true disallowExtAdjStsBcast: true
# #
# Talkgroup Rules Configuration # Talkgroup Rules Configuration

@ -87,7 +87,8 @@ FNENetwork::FNENetwork(HostFNE* host, const std::string& address, uint16_t port,
m_updateLookupTime(updateLookupTime * 60U), m_updateLookupTime(updateLookupTime * 60U),
m_softConnLimit(0U), m_softConnLimit(0U),
m_callInProgress(false), m_callInProgress(false),
m_disallowP25AdjStsBcast(true), m_disallowAdjStsBcast(false),
m_disallowExtAdjStsBcast(true),
m_reportPeerPing(reportPeerPing), m_reportPeerPing(reportPeerPing),
m_verbose(verbose) m_verbose(verbose)
{ {
@ -118,16 +119,27 @@ FNENetwork::~FNENetwork()
/// <param name="printOptions"></param> /// <param name="printOptions"></param>
void FNENetwork::setOptions(yaml::Node& conf, bool printOptions) void FNENetwork::setOptions(yaml::Node& conf, bool printOptions)
{ {
m_disallowP25AdjStsBcast = conf["disallowP25AdjStsBcast"].as<bool>(true); m_disallowAdjStsBcast = conf["disallowAdjStsBcast"].as<bool>(false);
m_disallowExtAdjStsBcast = conf["disallowExtAdjStsBcast"].as<bool>(true);
m_softConnLimit = conf["connectionLimit"].as<uint32_t>(MAX_HARD_CONN_CAP); m_softConnLimit = conf["connectionLimit"].as<uint32_t>(MAX_HARD_CONN_CAP);
if (m_softConnLimit > MAX_HARD_CONN_CAP) { if (m_softConnLimit > MAX_HARD_CONN_CAP) {
m_softConnLimit = MAX_HARD_CONN_CAP; m_softConnLimit = MAX_HARD_CONN_CAP;
} }
// always force disable ADJ_STS_BCAST to external peers if the all option
// is enabled
if (m_disallowAdjStsBcast) {
m_disallowExtAdjStsBcast = true;
}
if (printOptions) { if (printOptions) {
LogInfo(" Maximum Permitted Connections: %u", m_softConnLimit); LogInfo(" Maximum Permitted Connections: %u", m_softConnLimit);
LogInfo(" Disable P25 ADJ_STS_BCAST to external peers: %s", m_disallowP25AdjStsBcast ? "yes" : "no"); LogInfo(" Disable P25 ADJ_STS_BCAST to any peers: %s", m_disallowAdjStsBcast ? "yes" : "no");
if (m_disallowAdjStsBcast) {
LogWarning(LOG_NET, "NOTICE: All P25 ADJ_STS_BCAST messages will be blocked and dropped!");
}
LogInfo(" Disable P25 ADJ_STS_BCAST to external peers: %s", m_disallowExtAdjStsBcast ? "yes" : "no");
} }
} }
@ -632,6 +644,11 @@ void* FNENetwork::threadedNetworkRx(void* arg)
LogInfoEx(LOG_NET, "PEER %u RPTC ACK, completed the configuration exchange", peerId); LogInfoEx(LOG_NET, "PEER %u RPTC ACK, completed the configuration exchange", peerId);
json::object peerConfig = connection->config(); json::object peerConfig = connection->config();
if (peerConfig["externalPeer"].is<bool>()) {
bool external = peerConfig["externalPeer"].get<bool>();
connection->isExternalPeer(external);
}
if (peerConfig["software"].is<std::string>()) { if (peerConfig["software"].is<std::string>()) {
std::string software = peerConfig["software"].get<std::string>(); std::string software = peerConfig["software"].get<std::string>();
LogInfoEx(LOG_NET, "PEER %u reports software %s", peerId, software.c_str()); LogInfoEx(LOG_NET, "PEER %u reports software %s", peerId, software.c_str());

@ -86,6 +86,7 @@ namespace network
m_pingsReceived(0U), m_pingsReceived(0U),
m_lastPing(0U), m_lastPing(0U),
m_lastACLUpdate(0U), m_lastACLUpdate(0U),
m_isExternalPeer(false),
m_config(), m_config(),
m_pktLastSeq(0U), m_pktLastSeq(0U),
m_pktNextSeq(1U) m_pktNextSeq(1U)
@ -109,6 +110,7 @@ namespace network
m_pingsReceived(0U), m_pingsReceived(0U),
m_lastPing(0U), m_lastPing(0U),
m_lastACLUpdate(0U), m_lastACLUpdate(0U),
m_isExternalPeer(false),
m_config(), m_config(),
m_pktLastSeq(0U), m_pktLastSeq(0U),
m_pktNextSeq(1U) m_pktNextSeq(1U)
@ -152,6 +154,9 @@ namespace network
/// <summary>Last ACL update sent.</summary> /// <summary>Last ACL update sent.</summary>
__PROPERTY_PLAIN(uint64_t, lastACLUpdate); __PROPERTY_PLAIN(uint64_t, lastACLUpdate);
/// <summary>Flag indicating this connection is from an external peer.</summary>
__PROPERTY_PLAIN(bool, isExternalPeer);
/// <summary>JSON objecting containing peer configuration information.</summary> /// <summary>JSON objecting containing peer configuration information.</summary>
__PROPERTY_PLAIN(json::object, config); __PROPERTY_PLAIN(json::object, config);
@ -278,7 +283,8 @@ namespace network
bool m_callInProgress; bool m_callInProgress;
bool m_disallowP25AdjStsBcast; bool m_disallowAdjStsBcast;
bool m_disallowExtAdjStsBcast;
bool m_reportPeerPing; bool m_reportPeerPing;
bool m_verbose; bool m_verbose;

@ -117,6 +117,8 @@ bool PeerNetwork::writeConfig()
rcon["port"].set<uint16_t>(m_restApiPort); // REST API Port rcon["port"].set<uint16_t>(m_restApiPort); // REST API Port
config["rcon"].set<json::object>(rcon); config["rcon"].set<json::object>(rcon);
bool external = true;
config["externalPeer"].set<bool>(external); // External Peer Marker
config["software"].set<std::string>(std::string(software)); // Software ID config["software"].set<std::string>(std::string(software)); // Software ID
json::value v = json::value(config); json::value v = json::value(config);

@ -244,6 +244,11 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
m_parrotFrames.push_back(std::make_tuple(copy, len, pktSeq, streamId, srcId, dstId)); m_parrotFrames.push_back(std::make_tuple(copy, len, pktSeq, streamId, srcId, dstId));
} }
// process TSDU from peer
if (!processTSDU(buffer, peerId, duid)) {
return false;
}
// repeat traffic to the connected peers // repeat traffic to the connected peers
if (m_network->m_peers.size() > 0U) { if (m_network->m_peers.size() > 0U) {
uint32_t i = 0U; uint32_t i = 0U;
@ -306,7 +311,7 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId
routeRewrite(outboundPeerBuffer, dstPeerId, duid, dstId); routeRewrite(outboundPeerBuffer, dstPeerId, duid, dstId);
// process TSDUs going to external peers // process TSDUs going to external peers
if (processTSDUExternal(outboundPeerBuffer, peerId, dstPeerId, duid)) { if (processTSDUToExternal(outboundPeerBuffer, peerId, dstPeerId, duid)) {
peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, outboundPeerBuffer, len, pktSeq, streamId); peer.second->writeMaster({ NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, outboundPeerBuffer, len, pktSeq, streamId);
if (m_network->m_debug) { if (m_network->m_debug) {
LogDebug(LOG_NET, "P25, srcPeer = %u, dstPeer = %u, duid = $%02X, lco = $%02X, MFId = $%02X, srcId = %u, dstId = %u, len = %u, pktSeq = %u, streamId = %u, external = %u", LogDebug(LOG_NET, "P25, srcPeer = %u, dstPeer = %u, duid = $%02X, lco = $%02X, MFId = $%02X, srcId = %u, dstId = %u, len = %u, pktSeq = %u, streamId = %u, external = %u",
@ -424,12 +429,12 @@ void TagP25Data::routeRewrite(uint8_t* buffer, uint32_t peerId, uint8_t duid, ui
// rewrite destination TGID in the frame // rewrite destination TGID in the frame
__SET_UINT16(rewriteDstId, buffer, 8U); __SET_UINT16(rewriteDstId, buffer, 8U);
// are we receiving a TSDU?
if (duid == P25_DUID_TSDU) {
UInt8Array data = std::unique_ptr<uint8_t[]>(new uint8_t[frameLength]); UInt8Array data = std::unique_ptr<uint8_t[]>(new uint8_t[frameLength]);
::memset(data.get(), 0x00U, frameLength); ::memset(data.get(), 0x00U, frameLength);
::memcpy(data.get(), buffer + 24U, frameLength); ::memcpy(data.get(), buffer + 24U, frameLength);
// are we receiving a TSDU?
if (duid == P25_DUID_TSDU) {
std::unique_ptr<lc::TSBK> tsbk = lc::tsbk::TSBKFactory::createTSBK(data.get()); std::unique_ptr<lc::TSBK> tsbk = lc::tsbk::TSBKFactory::createTSBK(data.get());
if (tsbk != nullptr) { if (tsbk != nullptr) {
// handle standard P25 reference opcodes // handle standard P25 reference opcodes
@ -503,6 +508,52 @@ bool TagP25Data::peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound)
return false; return false;
} }
/// <summary>
/// Helper to process TSDUs being passed from a peer.
/// </summary>
/// <param name="buffer"></param>
/// <param name="peerId">Peer ID</param>
/// <param name="duid"></param>
bool TagP25Data::processTSDU(uint8_t* buffer, uint32_t peerId, uint8_t duid)
{
// are we receiving a TSDU?
if (duid == P25_DUID_TSDU) {
uint32_t frameLength = buffer[23U];
UInt8Array data = std::unique_ptr<uint8_t[]>(new uint8_t[frameLength]);
::memset(data.get(), 0x00U, frameLength);
::memcpy(data.get(), buffer + 24U, frameLength);
std::unique_ptr<lc::TSBK> tsbk = lc::tsbk::TSBKFactory::createTSBK(data.get());
if (tsbk != nullptr) {
// handle standard P25 reference opcodes
switch (tsbk->getLCO()) {
case TSBK_OSP_ADJ_STS_BCAST:
{
if (m_network->m_disallowAdjStsBcast) {
// LogWarning(LOG_NET, "PEER %u, passing ADJ_STS_BCAST to internal peers is prohibited, dropping", peerId);
return false;
} else {
lc::tsbk::OSP_ADJ_STS_BCAST* osp = static_cast<lc::tsbk::OSP_ADJ_STS_BCAST*>(tsbk.get());
if (m_network->m_verbose) {
LogMessage(LOG_NET, P25_TSDU_STR ", %s, sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X, peerId = %u", tsbk->toString().c_str(),
osp->getAdjSiteSysId(), osp->getAdjSiteRFSSId(), osp->getAdjSiteId(), osp->getAdjSiteChnId(), osp->getAdjSiteChnNo(), osp->getAdjSiteSvcClass(), peerId);
}
}
}
break;
default:
break;
}
} else {
LogWarning(LOG_NET, "PEER %u, passing TSBK that failed to decode? tsbk == nullptr", peerId);
}
}
return true;
}
/// <summary> /// <summary>
/// Helper to process TSDUs being passed to an external peer. /// Helper to process TSDUs being passed to an external peer.
/// </summary> /// </summary>
@ -510,7 +561,7 @@ bool TagP25Data::peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound)
/// <param name="srcPeerId">Source Peer ID</param> /// <param name="srcPeerId">Source Peer ID</param>
/// <param name="dstPeerId">Destination Peer ID</param> /// <param name="dstPeerId">Destination Peer ID</param>
/// <param name="duid"></param> /// <param name="duid"></param>
bool TagP25Data::processTSDUExternal(uint8_t* buffer, uint32_t srcPeerId, uint32_t dstPeerId, uint8_t duid) bool TagP25Data::processTSDUToExternal(uint8_t* buffer, uint32_t srcPeerId, uint32_t dstPeerId, uint8_t duid)
{ {
// are we receiving a TSDU? // are we receiving a TSDU?
if (duid == P25_DUID_TSDU) { if (duid == P25_DUID_TSDU) {
@ -526,15 +577,15 @@ bool TagP25Data::processTSDUExternal(uint8_t* buffer, uint32_t srcPeerId, uint32
switch (tsbk->getLCO()) { switch (tsbk->getLCO()) {
case TSBK_OSP_ADJ_STS_BCAST: case TSBK_OSP_ADJ_STS_BCAST:
{ {
if (m_network->m_disallowP25AdjStsBcast) { if (m_network->m_disallowExtAdjStsBcast) {
// LogWarning(LOG_NET, "PEER %u, passing ADJ_STS_BCAST to external peers is prohibited, dropping", dstPeerId); // LogWarning(LOG_NET, "PEER %u, passing ADJ_STS_BCAST to external peers is prohibited, dropping", dstPeerId);
return false; return false;
} else { } else {
lc::tsbk::OSP_ADJ_STS_BCAST* osp = static_cast<lc::tsbk::OSP_ADJ_STS_BCAST*>(tsbk.get()); lc::tsbk::OSP_ADJ_STS_BCAST* osp = static_cast<lc::tsbk::OSP_ADJ_STS_BCAST*>(tsbk.get());
if (m_network->m_verbose) { if (m_network->m_verbose) {
LogMessage(LOG_NET, P25_TSDU_STR ", %s, sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X", tsbk->toString().c_str(), LogMessage(LOG_NET, P25_TSDU_STR ", %s, sysId = $%03X, rfss = $%02X, site = $%02X, chId = %u, chNo = %u, svcClass = $%02X, peerId = %u", tsbk->toString().c_str(),
osp->getAdjSiteSysId(), osp->getAdjSiteRFSSId(), osp->getAdjSiteId(), osp->getAdjSiteChnId(), osp->getAdjSiteChnNo(), osp->getAdjSiteSvcClass()); osp->getAdjSiteSysId(), osp->getAdjSiteRFSSId(), osp->getAdjSiteId(), osp->getAdjSiteChnId(), osp->getAdjSiteChnNo(), osp->getAdjSiteSvcClass(), srcPeerId);
} }
} }
} }

@ -77,8 +77,10 @@ namespace network
/// <summary>Helper to route rewrite destination ID.</summary> /// <summary>Helper to route rewrite destination ID.</summary>
bool peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound = true); bool peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound = true);
/// <summary>Helper to process TSDUs being passed from a peer.</summary>
bool processTSDU(uint8_t* buffer, uint32_t peerId, uint8_t duid);
/// <summary>Helper to process TSDUs being passed to an external peer.</summary> /// <summary>Helper to process TSDUs being passed to an external peer.</summary>
bool processTSDUExternal(uint8_t* buffer, uint32_t srcPeerId, uint32_t dstPeerId, uint8_t duid); bool processTSDUToExternal(uint8_t* buffer, uint32_t srcPeerId, uint32_t dstPeerId, uint8_t duid);
/// <summary>Helper to determine if the peer is permitted for traffic.</summary> /// <summary>Helper to determine if the peer is permitted for traffic.</summary>
bool isPeerPermitted(uint32_t peerId, p25::lc::LC& control, uint8_t duid, uint32_t streamId); bool isPeerPermitted(uint32_t peerId, p25::lc::LC& control, uint8_t duid, uint32_t streamId);

Loading…
Cancel
Save

Powered by TurnKey Linux.