bump version to 4.20G (from 4.11G) [THIS MARKS INCLUSION OF IN-CALL CONTROL IN MASTER]; ensure always peers can violate the rules as usual; add permitted RIDs assignment to JSON handling for REST APIs;

pull/86/head
Bryan Biedenkapp 1 year ago
parent 6812029491
commit 0ee2b5c756

@ -108,7 +108,7 @@ typedef unsigned long long ulong64_t;
#define __EXE_NAME__ "" #define __EXE_NAME__ ""
#define VERSION_MAJOR "04" #define VERSION_MAJOR "04"
#define VERSION_MINOR "11" #define VERSION_MINOR "20"
#define VERSION_REV "G" #define VERSION_REV "G"
#define __NETVER__ "DVM_R" VERSION_MAJOR VERSION_REV VERSION_MINOR #define __NETVER__ "DVM_R" VERSION_MAJOR VERSION_REV VERSION_MINOR

@ -4,7 +4,7 @@
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* Copyright (C) 2024 Bryan Biedenkapp, N2PLL * Copyright (C) 2024-2025 Bryan Biedenkapp, N2PLL
* Copyright (C) 2024 Patrick McDonnell, W3AXL * Copyright (C) 2024 Patrick McDonnell, W3AXL
* *
*/ */
@ -222,6 +222,16 @@ json::object tgToJson(const TalkgroupRuleGroupVoice& groupVoice)
} }
config["preferred"].set<json::array>(preferreds); config["preferred"].set<json::array>(preferreds);
json::array permittedRIDs = json::array();
std::vector<uint32_t> permittedRID = groupVoice.config().permittedRIDs();
if (permittedRID.size() > 0) {
for (auto entry : permittedRID) {
uint32_t rid = entry;
permittedRIDs.push_back(json::value((double)rid));
}
}
config["permittedRids"].set<json::array>(permittedRIDs);
tg["config"].set<json::object>(config); tg["config"].set<json::object>(config);
} }
@ -445,6 +455,27 @@ TalkgroupRuleGroupVoice jsonToTG(json::object& req, HTTPPayload& reply)
config.preferred(preferred); config.preferred(preferred);
} }
if (!configObj["permittedRids"].is<json::array>()) {
errorPayload(reply, "TG configuration \"permittedRids\" was not a valid JSON array");
LogDebug(LOG_REST, "TG configuration \"permittedRids\" was not a valid JSON array");
return TalkgroupRuleGroupVoice();
}
json::array permittedRIDs = configObj["permittedRids"].get<json::array>();
std::vector<uint32_t> permittedRID = groupVoice.config().permittedRIDs();
if (permittedRIDs.size() > 0) {
for (auto entry : permittedRIDs) {
if (!entry.is<uint32_t>()) {
errorPayload(reply, "TG configuration permitted RID value was not a valid number");
LogDebug(LOG_REST, "TG configuration permitted RID value was not a valid number");
return TalkgroupRuleGroupVoice();
}
permittedRID.push_back(entry.get<uint32_t>());
}
config.permittedRIDs(permittedRID);
}
groupVoice.config(config); groupVoice.config(config);
} }

@ -876,6 +876,16 @@ bool TagDMRData::validate(uint32_t peerId, data::NetData& data, uint32_t streamI
return false; return false;
} }
// peer always send list takes priority over any following affiliation rules
bool isAlwaysPeer = false;
std::vector<uint32_t> alwaysSend = tg.config().alwaysSend();
if (alwaysSend.size() > 0) {
auto it = std::find(alwaysSend.begin(), alwaysSend.end(), peerId);
if (it != alwaysSend.end()) {
isAlwaysPeer = true; // skip any following checks and always send traffic
}
}
// check the DMR slot number // check the DMR slot number
if (tg.source().tgSlot() != data.getSlotNo()) { if (tg.source().tgSlot() != data.getSlotNo()) {
// report error event to InfluxDB // report error event to InfluxDB
@ -918,27 +928,30 @@ bool TagDMRData::validate(uint32_t peerId, data::NetData& data, uint32_t streamI
return false; return false;
} }
// does the TGID have a permitted RID list? // always peers can violate the rules...hurray
if (tg.config().permittedRIDs().size() > 0) { if (!isAlwaysPeer) {
// does the transmitting RID have permission? // does the TGID have a permitted RID list?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs(); if (tg.config().permittedRIDs().size() > 0) {
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), data.getSrcId()) == permittedRIDs.end()) { // does the transmitting RID have permission?
// report error event to InfluxDB std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (m_network->m_enableInfluxDB) { if (std::find(permittedRIDs.begin(), permittedRIDs.end(), data.getSrcId()) == permittedRIDs.end()) {
influxdb::QueryBuilder() // report error event to InfluxDB
.meas("call_error_event") if (m_network->m_enableInfluxDB) {
.tag("peerId", std::to_string(peerId)) influxdb::QueryBuilder()
.tag("streamId", std::to_string(streamId)) .meas("call_error_event")
.tag("srcId", std::to_string(data.getSrcId())) .tag("peerId", std::to_string(peerId))
.tag("dstId", std::to_string(data.getDstId())) .tag("streamId", std::to_string(streamId))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED) .tag("srcId", std::to_string(data.getSrcId()))
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count()) .tag("dstId", std::to_string(data.getDstId()))
.request(m_network->m_influxServer); .field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
} .timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// report In-Call Control to the peer sending traffic // report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_DMR, NET_ICC::REJECT_TRAFFIC, data.getDstId(), data.getSlotNo()); m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_DMR, NET_ICC::REJECT_TRAFFIC, data.getDstId(), data.getSlotNo());
return false; return false;
}
} }
} }
} }

@ -682,6 +682,16 @@ bool TagNXDNData::validate(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, u
return false; return false;
} }
// peer always send list takes priority over any following affiliation rules
bool isAlwaysPeer = false;
std::vector<uint32_t> alwaysSend = tg.config().alwaysSend();
if (alwaysSend.size() > 0) {
auto it = std::find(alwaysSend.begin(), alwaysSend.end(), peerId);
if (it != alwaysSend.end()) {
isAlwaysPeer = true; // skip any following checks and always send traffic
}
}
// is the TGID active? // is the TGID active?
if (!tg.config().active()) { if (!tg.config().active()) {
// report error event to InfluxDB // report error event to InfluxDB
@ -702,27 +712,30 @@ bool TagNXDNData::validate(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, u
return false; return false;
} }
// does the TGID have a permitted RID list? // always peers can violate the rules...hurray
if (tg.config().permittedRIDs().size() > 0) { if (!isAlwaysPeer) {
// does the transmitting RID have permission? // does the TGID have a permitted RID list?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs(); if (tg.config().permittedRIDs().size() > 0) {
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), lc.getSrcId()) == permittedRIDs.end()) { // does the transmitting RID have permission?
// report error event to InfluxDB std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (m_network->m_enableInfluxDB) { if (std::find(permittedRIDs.begin(), permittedRIDs.end(), lc.getSrcId()) == permittedRIDs.end()) {
influxdb::QueryBuilder() // report error event to InfluxDB
.meas("call_error_event") if (m_network->m_enableInfluxDB) {
.tag("peerId", std::to_string(peerId)) influxdb::QueryBuilder()
.tag("streamId", std::to_string(streamId)) .meas("call_error_event")
.tag("srcId", std::to_string(lc.getSrcId())) .tag("peerId", std::to_string(peerId))
.tag("dstId", std::to_string(lc.getDstId())) .tag("streamId", std::to_string(streamId))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED) .tag("srcId", std::to_string(lc.getSrcId()))
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count()) .tag("dstId", std::to_string(lc.getDstId()))
.request(m_network->m_influxServer); .field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
} .timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// report In-Call Control to the peer sending traffic // report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId()); m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId());
return false; return false;
}
} }
} }

@ -1072,7 +1072,7 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const
skipRidCheck = true; skipRidCheck = true;
} }
LogDebug(LOG_NET, "P25, duid = $%02X, mfId = $%02X, lco = $%02X, srcId = %u, dstId = %u", duid, control.getMFId(), control.getLCO(), control.getSrcId(), control.getDstId()); //LogDebug(LOG_NET, "P25, duid = $%02X, mfId = $%02X, lco = $%02X, srcId = %u, dstId = %u", duid, control.getMFId(), control.getLCO(), control.getSrcId(), control.getDstId());
// is the source ID a blacklisted ID? // is the source ID a blacklisted ID?
if (!skipRidCheck) { if (!skipRidCheck) {
@ -1249,6 +1249,16 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const
return false; return false;
} }
// peer always send list takes priority over any following affiliation rules
bool isAlwaysPeer = false;
std::vector<uint32_t> alwaysSend = tg.config().alwaysSend();
if (alwaysSend.size() > 0) {
auto it = std::find(alwaysSend.begin(), alwaysSend.end(), peerId);
if (it != alwaysSend.end()) {
isAlwaysPeer = true; // skip any following checks and always send traffic
}
}
// is the TGID active? // is the TGID active?
if (!tg.config().active()) { if (!tg.config().active()) {
// report error event to InfluxDB // report error event to InfluxDB
@ -1269,34 +1279,36 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const
return false; return false;
} }
// does the TGID have a permitted RID list? // always peers can violate the rules...hurray
if (tg.config().permittedRIDs().size() > 0) { if (!isAlwaysPeer) {
// does the transmitting RID have permission? // does the TGID have a permitted RID list?
std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs(); if (tg.config().permittedRIDs().size() > 0) {
if (std::find(permittedRIDs.begin(), permittedRIDs.end(), control.getSrcId()) == permittedRIDs.end()) { // does the transmitting RID have permission?
// report error event to InfluxDB std::vector<uint32_t> permittedRIDs = tg.config().permittedRIDs();
if (m_network->m_enableInfluxDB) { if (std::find(permittedRIDs.begin(), permittedRIDs.end(), control.getSrcId()) == permittedRIDs.end()) {
influxdb::QueryBuilder() // report error event to InfluxDB
.meas("call_error_event") if (m_network->m_enableInfluxDB) {
.tag("peerId", std::to_string(peerId)) influxdb::QueryBuilder()
.tag("streamId", std::to_string(streamId)) .meas("call_error_event")
.tag("srcId", std::to_string(control.getSrcId())) .tag("peerId", std::to_string(peerId))
.tag("dstId", std::to_string(control.getDstId())) .tag("streamId", std::to_string(streamId))
.field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED) .tag("srcId", std::to_string(control.getSrcId()))
.timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count()) .tag("dstId", std::to_string(control.getDstId()))
.request(m_network->m_influxServer); .field("message", INFLUXDB_ERRSTR_RID_NOT_PERMITTED)
} .timestamp(std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()).count())
.request(m_network->m_influxServer);
}
// report In-Call Control to the peer sending traffic // report In-Call Control to the peer sending traffic
m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId()); m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId());
return false; return false;
}
} }
} }
return true; return true;
} }
/* Helper to write a grant packet. */ /* Helper to write a grant packet. */
bool TagP25Data::write_TSDU_Grant(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp) bool TagP25Data::write_TSDU_Grant(uint32_t peerId, uint32_t srcId, uint32_t dstId, uint8_t serviceOptions, bool grp)

Loading…
Cancel
Save

Powered by TurnKey Linux.