add try {} catch {} around some critical ASIO read calls to prevent application crash (this won't resolve the errors but should prevent application crash); implement support for peer ID list that *always* receives traffic for a TGID regardless of affiliation rules;

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

@ -24,6 +24,8 @@ groupVoice:
exclusion: []
# List of peer talkgroup rewrites.
rewrite: []
# List of peer IDs that always receive traffic for this talkgroup regardless of affiliation rules.
always: []
# List of site CC peer IDs defining talkgroup access preference (peers listed here will be preferred for access,
# sites not listed here will be non-preferred and will cause a AFF_GRP_RSP DENY, typically triggering roaming).
# If this list is empty *all* peers are preferred. (Trunking Only)
@ -55,6 +57,8 @@ groupVoice:
exclusion: []
# List of peer talkgroup rewrites.
rewrite: []
# List of peer IDs that always receive traffic for this talkgroup regardless of affiliation rules.
always: []
# List of site CC peer IDs defining talkgroup access preference (peers listed here will be preferred for access,
# sites not listed here will be non-preferred and will cause a AFF_GRP_RSP DENY, typically triggering roaming).
# If this list is empty *all* peers are preferred. (Trunking Only)
@ -92,6 +96,8 @@ groupVoice:
tgid: 9999
# DMR slot number.
slot: 1
# List of peer IDs that always receive traffic for this talkgroup regardless of affiliation rules.
always: []
# List of site CC peer IDs defining talkgroup access preference (peers listed here will be preferred for access,
# sites not listed here will be non-preferred and will cause a AFF_GRP_RSP DENY, typically triggering roaming).
# If this list is empty *all* peers are preferred. (Trunking Only)
@ -121,6 +127,8 @@ groupVoice:
exclusion: []
# List of peer talkgroup rewrites.
rewrite: []
# List of peer IDs that always receive traffic for this talkgroup regardless of affiliation rules.
always: []
# List of site CC peer IDs defining talkgroup access preference (peers listed here will be preferred for access,
# sites not listed here will be non-preferred and will cause a AFF_GRP_RSP DENY, typically triggering roaming).
# If this list is empty *all* peers are preferred. (Trunking Only)
@ -150,6 +158,8 @@ groupVoice:
exclusion: []
# List of peer talkgroup rewrites.
rewrite: []
# List of peer IDs that always receive traffic for this talkgroup regardless of affiliation rules.
always: []
# List of site CC peer IDs defining talkgroup access preference (peers listed here will be preferred for access,
# sites not listed here will be non-preferred and will cause a AFF_GRP_RSP DENY, typically triggering roaming).
# If this list is empty *all* peers are preferred. (Trunking Only)
@ -179,6 +189,8 @@ groupVoice:
exclusion: []
# List of peer talkgroup rewrites.
rewrite: []
# List of peer IDs that always receive traffic for this talkgroup regardless of affiliation rules.
always: []
# List of site CC peer IDs defining talkgroup access preference (peers listed here will be preferred for access,
# sites not listed here will be non-preferred and will cause a AFF_GRP_RSP DENY, typically triggering roaming).
# If this list is empty *all* peers are preferred. (Trunking Only)

@ -143,6 +143,7 @@ namespace lookups
m_inclusion(),
m_exclusion(),
m_rewrite(),
m_alwaysSend(),
m_preferred(),
m_nonPreferred(false)
{
@ -181,6 +182,14 @@ namespace lookups
}
}
yaml::Node& alwaysSendList = node["always"];
if (alwaysSendList.size() > 0U) {
for (size_t i = 0; i < alwaysSendList.size(); i++) {
uint32_t peerId = alwaysSendList[i].as<uint32_t>(0U);
m_alwaysSend.push_back(peerId);
}
}
yaml::Node& preferredList = node["preferred"];
if (preferredList.size() > 0U) {
for (size_t i = 0; i < preferredList.size(); i++) {
@ -200,6 +209,7 @@ namespace lookups
m_inclusion = data.m_inclusion;
m_exclusion = data.m_exclusion;
m_rewrite = data.m_rewrite;
m_alwaysSend = data.m_alwaysSend;
m_preferred = data.m_preferred;
m_nonPreferred = data.m_nonPreferred;
}
@ -213,6 +223,8 @@ namespace lookups
uint8_t exclusionSize() const { return m_exclusion.size(); }
/// <summary>Gets the count of rewrites.</summary>
uint8_t rewriteSize() const { return m_rewrite.size(); }
/// <summary>Gets the count of always send.</summary>
uint8_t alwaysSendSize() const { return m_alwaysSend.size(); }
/// <summary>Gets the count of rewrites.</summary>
uint8_t preferredSize() const { return m_preferred.size(); }
@ -252,6 +264,15 @@ namespace lookups
}
node["rewrite"] = rewriteList;
yaml::Node alwaysSendList;
if (m_alwaysSend.size() > 0U) {
for (auto alw : m_alwaysSend) {
yaml::Node& newAlw = alwaysSendList.push_back();
newAlw = __INT_STR(alw);
}
}
node["always"] = alwaysSendList;
yaml::Node preferredList;
if (m_preferred.size() > 0U) {
for (auto pref : m_preferred) {
@ -275,6 +296,8 @@ namespace lookups
__PROPERTY_PLAIN(std::vector<uint32_t>, exclusion);
/// <summary>List of rewrites performed by this rule.</summary>
__PROPERTY_PLAIN(std::vector<TalkgroupRuleRewrite>, rewrite);
/// <summary>List of always send performed by this rule.</summary>
__PROPERTY_PLAIN(std::vector<uint32_t>, alwaysSend);
/// <summary>List of peer IDs preferred by this rule.</summary>
__PROPERTY_PLAIN(std::vector<uint32_t>, preferred);

@ -7,7 +7,7 @@
* @package DVM / Common Library
* @license GPLv2 License (https://opensource.org/licenses/GPL-2.0)
*
* Copyright (C) 2023 Bryan Biedenkapp, N2PLL
* Copyright (C) 2023,2024 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__REST_HTTP__CLIENT_CONNECTION_H__)
@ -100,25 +100,29 @@ namespace network
HTTPLexer::ResultType result;
char* content;
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
m_request.headers.add("RemoteHost", m_socket.remote_endpoint().address().to_string());
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
}
else if (result == HTTPLexer::BAD) {
return;
}
else {
read();
try
{
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
m_request.headers.add("RemoteHost", m_socket.remote_endpoint().address().to_string());
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
}
else if (result == HTTPLexer::BAD) {
return;
}
else {
read();
}
}
catch(const std::exception& e) { ::LogError(LOG_REST, "ClientConnection::read(), %s", ec.message().c_str()); }
}
else if (ec != asio::error::operation_aborted) {
if (ec) {

@ -114,25 +114,29 @@ namespace network
HTTPLexer::ResultType result;
char* content;
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
m_request.headers.add("RemoteHost", m_socket.lowest_layer().remote_endpoint().address().to_string());
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
}
else if (result == HTTPLexer::BAD) {
return;
}
else {
read();
try
{
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
m_request.headers.add("RemoteHost", m_socket.lowest_layer().remote_endpoint().address().to_string());
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
}
else if (result == HTTPLexer::BAD) {
return;
}
else {
read();
}
}
catch(const std::exception& e) { ::LogError(LOG_REST, "SecureClientConnection::read(), %s", ec.message().c_str()); }
}
else if (ec != asio::error::operation_aborted) {
if (ec) {

@ -110,27 +110,32 @@ namespace network
HTTPLexer::ResultType result;
char* content;
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
// catch exceptions here so we don't blatently crash the system
try
{
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
m_request.headers.add("RemoteHost", m_socket.lowest_layer().remote_endpoint().address().to_string());
m_request.headers.add("RemoteHost", m_socket.lowest_layer().remote_endpoint().address().to_string());
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
write();
}
else if (result == HTTPLexer::BAD) {
m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST);
write();
}
else {
read();
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
write();
}
else if (result == HTTPLexer::BAD) {
m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST);
write();
}
else {
read();
}
}
catch(const std::exception& e) { ::LogError(LOG_REST, "SecureServerConnection::read(), %s", ec.message().c_str()); }
}
else if (ec != asio::error::operation_aborted) {
if (ec) {

@ -9,7 +9,7 @@
* @license BSL-1.0 License (https://opensource.org/license/bsl1-0-html)
*
* Copyright (c) 2003-2013 Christopher M. Kohlhoff
* Copyright (C) 2023 Bryan Biedenkapp, N2PLL
* Copyright (C) 2023,2024 Bryan Biedenkapp, N2PLL
*
*/
#if !defined(__REST_HTTP__SERVER_CONNECTION_H__)
@ -93,27 +93,32 @@ namespace network
HTTPLexer::ResultType result;
char* content;
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
// catch exceptions here so we don't blatently crash the system
try
{
std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length);
}
m_request.headers.add("RemoteHost", m_socket.remote_endpoint().address().to_string());
m_request.headers.add("RemoteHost", m_socket.remote_endpoint().address().to_string());
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
write();
}
else if (result == HTTPLexer::BAD) {
m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST);
write();
}
else {
read();
if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply);
write();
}
else if (result == HTTPLexer::BAD) {
m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST);
write();
}
else {
read();
}
}
catch(const std::exception& e) { ::LogError(LOG_REST, "ServerConnection::read(), %s", ec.message().c_str()); }
}
else if (ec != asio::error::operation_aborted) {
if (ec) {
@ -151,7 +156,7 @@ namespace network
asio::error_code ignored_ec;
m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec);
}
catch(const std::exception& e) { ::LogError(LOG_REST, "%s", ec.message().c_str()); }
catch(const std::exception& e) { ::LogError(LOG_REST, "ServerConnection::write(), %s", ec.message().c_str()); }
}
if (ec != asio::error::operation_aborted) {

@ -641,6 +641,15 @@ bool TagDMRData::isPeerPermitted(uint32_t peerId, data::Data& data, uint32_t str
}
}
// peer always send list takes priority over any following affiliation rules
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()) {
return true; // skip any following checks and always send traffic
}
}
FNEPeerConnection* connection = nullptr;
if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) {
connection = m_network->m_peers[peerId];

@ -450,6 +450,15 @@ bool TagNXDNData::isPeerPermitted(uint32_t peerId, lc::RTCH& lc, uint8_t message
}
}
// peer always send list takes priority over any following affiliation rules
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()) {
return true; // skip any following checks and always send traffic
}
}
FNEPeerConnection* connection = nullptr;
if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) {
connection = m_network->m_peers[peerId];

@ -941,6 +941,15 @@ bool TagP25Data::isPeerPermitted(uint32_t peerId, lc::LC& control, uint8_t duid,
}
}
// peer always send list takes priority over any following affiliation rules
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()) {
return true; // skip any following checks and always send traffic
}
}
FNEPeerConnection* connection = nullptr;
if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) {
connection = m_network->m_peers[peerId];

Loading…
Cancel
Save

Powered by TurnKey Linux.