add support to properly filter traffic headers and terminators; add support to selectivly block U2U (private) calls from peers;

pull/55/head
Bryan Biedenkapp 2 years ago
parent 70600d3fd7
commit 6425ec5cd7

@ -83,6 +83,14 @@ master:
# Flag indicating whether or not a conventional site can override affiliation rules.
allowConvSiteAffOverride: true
# Flag indicating that traffic headers will be filtered by destination ID (i.e. valid RID or valid TGID).
filterHeaders: true
# Flag indicating that terminators will be filtered by destination ID (i.e. valid RID or valid TGID).
filterTerminators: true
# List of peers that unit to unit calls are dropped for.
dropUnitToUnit: []
# Flag indicating whether or not InfluxDB logging and metrics recording is enabled.
enableInflux: false
# Hostname/IP address of the InfluxDB instance to connect to.

@ -633,6 +633,7 @@ bool HostFNE::createPeerNetworks()
/*
** Block Traffic To Peers
*/
yaml::Node& blockTrafficTo = peerConf["blockTrafficTo"];
if (blockTrafficTo.size() > 0U) {
for (size_t i = 0; i < blockTrafficTo.size(); i++) {

@ -98,6 +98,9 @@ FNENetwork::FNENetwork(HostFNE* host, const std::string& address, uint16_t port,
m_disallowExtAdjStsBcast(true),
m_allowConvSiteAffOverride(false),
m_restrictGrantToAffOnly(false),
m_filterHeaders(true),
m_filterTerminators(true),
m_dropU2UPeerTable(),
m_enableInfluxDB(false),
m_influxServerAddress("127.0.0.1"),
m_influxServerPort(8086U),
@ -163,6 +166,22 @@ void FNENetwork::setOptions(yaml::Node& conf, bool printOptions)
m_parrotOnlyOriginating = conf["parrotOnlyToOrginiatingPeer"].as<bool>(false);
m_restrictGrantToAffOnly = conf["restrictGrantToAffiliatedOnly"].as<bool>(false);
m_filterHeaders = conf["filterHeaders"].as<bool>(true);
m_filterTerminators = conf["filterTerminators"].as<bool>(true);
/*
** Drop Unit to Unit Peers
*/
yaml::Node& dropUnitToUnit = conf["dropUnitToUnit"];
if (dropUnitToUnit.size() > 0U) {
for (size_t i = 0; i < dropUnitToUnit.size(); i++) {
uint32_t peerId = (uint32_t)::strtoul(dropUnitToUnit[i].as<std::string>("0").c_str(), NULL, 10);
if (peerId != 0U) {
m_dropU2UPeerTable.push_back(peerId);
}
}
}
if (printOptions) {
LogInfo(" Maximum Permitted Connections: %u", m_softConnLimit);
@ -173,6 +192,8 @@ void FNENetwork::setOptions(yaml::Node& conf, bool printOptions)
LogInfo(" Disable P25 ADJ_STS_BCAST to external peers: %s", m_disallowExtAdjStsBcast ? "yes" : "no");
LogInfo(" Allow conventional sites to override affiliation and receive all traffic: %s", m_allowConvSiteAffOverride ? "yes" : "no");
LogInfo(" Restrict grant response by affiliation: %s", m_restrictGrantToAffOnly ? "yes" : "no");
LogInfo(" Traffic Headers Filtered by Destination ID: %s", m_filterHeaders ? "yes" : "no");
LogInfo(" Traffic Terminators Filtered by Destination ID: %s", m_filterTerminators ? "yes" : "no");
LogInfo(" InfluxDB Reporting Enabled: %s", m_enableInfluxDB ? "yes" : "no");
if (m_enableInfluxDB) {
LogInfo(" InfluxDB Address: %s", m_influxServerAddress.c_str());
@ -1103,6 +1124,22 @@ void* FNENetwork::threadedNetworkRx(void* arg)
return nullptr;
}
/// <summary>
/// Checks if the passed peer ID is blocked from unit-to-unit traffic.
/// </summary>
/// <param name="peerId"></param>
bool FNENetwork::checkU2UDroppedPeer(uint32_t peerId)
{
if (m_dropU2UPeerTable.empty())
return false;
if (std::find(m_dropU2UPeerTable.begin(), m_dropU2UPeerTable.end(), peerId) != m_dropU2UPeerTable.end()) {
return true;
}
return false;
}
/// <summary>
/// Helper to create a peer on the peers affiliations list.
/// </summary>

@ -307,6 +307,11 @@ namespace network
bool m_allowConvSiteAffOverride;
bool m_restrictGrantToAffOnly;
bool m_filterHeaders;
bool m_filterTerminators;
std::vector<uint32_t> m_dropU2UPeerTable;
bool m_enableInfluxDB;
std::string m_influxServerAddress;
uint16_t m_influxServerPort;
@ -322,6 +327,9 @@ namespace network
/// <summary>Entry point to process a given network packet.</summary>
static void* threadedNetworkRx(void* arg);
/// <summary>Checks if the passed peer ID is blocked from unit-to-unit traffic.</summary>
bool checkU2UDroppedPeer(uint32_t peerId);
/// <summary>Helper to create a peer on the peers affiliations list.</summary>
void createPeerAffiliations(uint32_t peerId, std::string peerName);
/// <summary>Helper to erase the peer from the peers affiliations list.</summary>

@ -612,9 +612,10 @@ bool TagDMRData::processCSBK(uint8_t* buffer, uint32_t peerId, dmr::data::Data&
/// <returns></returns>
bool TagDMRData::isPeerPermitted(uint32_t peerId, data::Data& data, uint32_t streamId, bool external)
{
// private calls are always permitted
if (data.getDataType() == FLCO_PRIVATE) {
return true;
if (!m_network->checkU2UDroppedPeer(peerId))
return true;
return false;
}
// is this a group call?

@ -421,9 +421,10 @@ bool TagNXDNData::peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound)
/// <returns></returns>
bool TagNXDNData::isPeerPermitted(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, uint32_t streamId, bool external)
{
// private calls are always permitted
if (!lc.getGroup()) {
return true;
if (!m_network->checkU2UDroppedPeer(peerId))
return true;
return false;
}
// is this a group call?

@ -684,6 +684,13 @@ bool TagP25Data::processTSDUFrom(uint8_t* buffer, uint32_t peerId, uint8_t duid)
// handle standard P25 reference opcodes
switch (tsbk->getLCO()) {
case TSBK_IOSP_UU_VCH:
case TSBK_IOSP_UU_ANS:
{
if (m_network->checkU2UDroppedPeer(peerId))
return false;
}
break;
case TSBK_OSP_ADJ_STS_BCAST:
{
if (m_network->m_disallowAdjStsBcast) {
@ -841,18 +848,76 @@ bool TagP25Data::processTSDUToExternal(uint8_t* buffer, uint32_t srcPeerId, uint
/// <returns></returns>
bool TagP25Data::isPeerPermitted(uint32_t peerId, lc::LC& control, uint8_t duid, uint32_t streamId, bool external)
{
// private calls are always permitted
if (control.getLCO() == LC_PRIVATE) {
return true;
if (!m_network->checkU2UDroppedPeer(peerId))
return true;
return false;
}
// always permit a TSDU or PDU
if (duid == P25_DUID_TSDU || duid == P25_DUID_PDU)
return true;
// always permit a terminator
if (duid == P25_DUID_TDU || duid == P25_DUID_TDULC)
if (duid == P25_DUID_HDU) {
if (m_network->m_filterHeaders) {
if (control.getSrcId() != 0U && control.getDstId() != 0U) {
// is this a group call?
lookups::TalkgroupRuleGroupVoice tg = m_network->m_tidLookup->find(control.getDstId());
if (!tg.isInvalid()) {
return true;
}
tg = m_network->m_tidLookup->findByRewrite(peerId, control.getDstId());
if (!tg.isInvalid()) {
return true;
}
// is this a U2U call?
lookups::RadioId rid = m_network->m_ridLookup->find(control.getDstId());
if (!rid.radioDefault() && rid.radioEnabled()) {
return true;
}
return false;
}
}
// always permit a headers
return true;
}
if (duid == P25_DUID_TDULC) {
// always permit a terminator
return true;
}
if (duid == P25_DUID_TDU) {
if (m_network->m_filterTerminators) {
if (control.getSrcId() != 0U && control.getDstId() != 0U) {
// is this a group call?
lookups::TalkgroupRuleGroupVoice tg = m_network->m_tidLookup->find(control.getDstId());
if (!tg.isInvalid()) {
return true;
}
tg = m_network->m_tidLookup->findByRewrite(peerId, control.getDstId());
if (!tg.isInvalid()) {
return true;
}
// is this a U2U call?
lookups::RadioId rid = m_network->m_ridLookup->find(control.getDstId());
if (!rid.radioDefault() && rid.radioEnabled()) {
return true;
}
return false;
}
}
// always permit a terminator
return true;
}
// is this a group call?
lookups::TalkgroupRuleGroupVoice tg = m_network->m_tidLookup->find(control.getDstId());

Loading…
Cancel
Save

Powered by TurnKey Linux.