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.
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.
disallowP25AdjStsBcast: true
disallowExtAdjStsBcast: true
#
# Talkgroup Rules Configuration

@ -87,7 +87,8 @@ FNENetwork::FNENetwork(HostFNE* host, const std::string& address, uint16_t port,
m_updateLookupTime(updateLookupTime * 60U),
m_softConnLimit(0U),
m_callInProgress(false),
m_disallowP25AdjStsBcast(true),
m_disallowAdjStsBcast(false),
m_disallowExtAdjStsBcast(true),
m_reportPeerPing(reportPeerPing),
m_verbose(verbose)
{
@ -118,16 +119,27 @@ FNENetwork::~FNENetwork()
/// <param name="printOptions"></param>
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);
if (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) {
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);
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>()) {
std::string software = peerConfig["software"].get<std::string>();
LogInfoEx(LOG_NET, "PEER %u reports software %s", peerId, software.c_str());

@ -86,6 +86,7 @@ namespace network
m_pingsReceived(0U),
m_lastPing(0U),
m_lastACLUpdate(0U),
m_isExternalPeer(false),
m_config(),
m_pktLastSeq(0U),
m_pktNextSeq(1U)
@ -109,6 +110,7 @@ namespace network
m_pingsReceived(0U),
m_lastPing(0U),
m_lastACLUpdate(0U),
m_isExternalPeer(false),
m_config(),
m_pktLastSeq(0U),
m_pktNextSeq(1U)
@ -152,6 +154,9 @@ namespace network
/// <summary>Last ACL update sent.</summary>
__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>
__PROPERTY_PLAIN(json::object, config);
@ -278,7 +283,8 @@ namespace network
bool m_callInProgress;
bool m_disallowP25AdjStsBcast;
bool m_disallowAdjStsBcast;
bool m_disallowExtAdjStsBcast;
bool m_reportPeerPing;
bool m_verbose;

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

@ -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));
}
// process TSDU from peer
if (!processTSDU(buffer, peerId, duid)) {
return false;
}
// repeat traffic to the connected peers
if (m_network->m_peers.size() > 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);
// 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);
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",
@ -424,12 +429,12 @@ void TagP25Data::routeRewrite(uint8_t* buffer, uint32_t peerId, uint8_t duid, ui
// rewrite destination TGID in the frame
__SET_UINT16(rewriteDstId, buffer, 8U);
UInt8Array data = std::unique_ptr<uint8_t[]>(new uint8_t[frameLength]);
::memset(data.get(), 0x00U, frameLength);
::memcpy(data.get(), buffer + 24U, frameLength);
// are we receiving a TSDU?
if (duid == P25_DUID_TSDU) {
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
@ -503,6 +508,52 @@ bool TagP25Data::peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound)
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>
/// Helper to process TSDUs being passed to an external peer.
/// </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="dstPeerId">Destination Peer ID</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?
if (duid == P25_DUID_TSDU) {
@ -526,15 +577,15 @@ bool TagP25Data::processTSDUExternal(uint8_t* buffer, uint32_t srcPeerId, uint32
switch (tsbk->getLCO()) {
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);
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", tsbk->toString().c_str(),
osp->getAdjSiteSysId(), osp->getAdjSiteRFSSId(), osp->getAdjSiteId(), osp->getAdjSiteChnId(), osp->getAdjSiteChnNo(), osp->getAdjSiteSvcClass());
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(), srcPeerId);
}
}
}

@ -77,8 +77,10 @@ namespace network
/// <summary>Helper to route rewrite destination ID.</summary>
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>
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>
bool isPeerPermitted(uint32_t peerId, p25::lc::LC& control, uint8_t duid, uint32_t streamId);

Loading…
Cancel
Save

Powered by TurnKey Linux.