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: [] exclusion: []
# List of peer talkgroup rewrites. # List of peer talkgroup rewrites.
rewrite: [] 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, # 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). # 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) # If this list is empty *all* peers are preferred. (Trunking Only)
@ -55,6 +57,8 @@ groupVoice:
exclusion: [] exclusion: []
# List of peer talkgroup rewrites. # List of peer talkgroup rewrites.
rewrite: [] 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, # 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). # 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) # If this list is empty *all* peers are preferred. (Trunking Only)
@ -92,6 +96,8 @@ groupVoice:
tgid: 9999 tgid: 9999
# DMR slot number. # DMR slot number.
slot: 1 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, # 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). # 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) # If this list is empty *all* peers are preferred. (Trunking Only)
@ -121,6 +127,8 @@ groupVoice:
exclusion: [] exclusion: []
# List of peer talkgroup rewrites. # List of peer talkgroup rewrites.
rewrite: [] 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, # 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). # 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) # If this list is empty *all* peers are preferred. (Trunking Only)
@ -150,6 +158,8 @@ groupVoice:
exclusion: [] exclusion: []
# List of peer talkgroup rewrites. # List of peer talkgroup rewrites.
rewrite: [] 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, # 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). # 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) # If this list is empty *all* peers are preferred. (Trunking Only)
@ -179,6 +189,8 @@ groupVoice:
exclusion: [] exclusion: []
# List of peer talkgroup rewrites. # List of peer talkgroup rewrites.
rewrite: [] 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, # 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). # 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) # If this list is empty *all* peers are preferred. (Trunking Only)

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

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

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

@ -110,27 +110,32 @@ namespace network
HTTPLexer::ResultType result; HTTPLexer::ResultType result;
char* content; 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::string contentLength = m_request.headers.find("Content-Length"); {
if (contentLength != "") { std::tie(result, content) = m_lexer.parse(m_request, m_buffer.data(), m_buffer.data() + bytes_transferred);
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.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) { if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply); m_requestHandler.handleRequest(m_request, m_reply);
write(); write();
} }
else if (result == HTTPLexer::BAD) { else if (result == HTTPLexer::BAD) {
m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST); m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST);
write(); write();
} }
else { else {
read(); read();
}
} }
catch(const std::exception& e) { ::LogError(LOG_REST, "SecureServerConnection::read(), %s", ec.message().c_str()); }
} }
else if (ec != asio::error::operation_aborted) { else if (ec != asio::error::operation_aborted) {
if (ec) { if (ec) {

@ -9,7 +9,7 @@
* @license BSL-1.0 License (https://opensource.org/license/bsl1-0-html) * @license BSL-1.0 License (https://opensource.org/license/bsl1-0-html)
* *
* Copyright (c) 2003-2013 Christopher M. Kohlhoff * 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__) #if !defined(__REST_HTTP__SERVER_CONNECTION_H__)
@ -93,27 +93,32 @@ namespace network
HTTPLexer::ResultType result; HTTPLexer::ResultType result;
char* content; 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"); std::string contentLength = m_request.headers.find("Content-Length");
if (contentLength != "") { if (contentLength != "") {
size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10); size_t length = (size_t)::strtoul(contentLength.c_str(), NULL, 10);
m_request.content = std::string(content, length); 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) { if (result == HTTPLexer::GOOD) {
m_requestHandler.handleRequest(m_request, m_reply); m_requestHandler.handleRequest(m_request, m_reply);
write(); write();
} }
else if (result == HTTPLexer::BAD) { else if (result == HTTPLexer::BAD) {
m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST); m_reply = HTTPPayload::statusPayload(HTTPPayload::BAD_REQUEST);
write(); write();
} }
else { else {
read(); read();
}
} }
catch(const std::exception& e) { ::LogError(LOG_REST, "ServerConnection::read(), %s", ec.message().c_str()); }
} }
else if (ec != asio::error::operation_aborted) { else if (ec != asio::error::operation_aborted) {
if (ec) { if (ec) {
@ -151,7 +156,7 @@ namespace network
asio::error_code ignored_ec; asio::error_code ignored_ec;
m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, 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) { 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; FNEPeerConnection* connection = nullptr;
if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) { if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) {
connection = m_network->m_peers[peerId]; 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; FNEPeerConnection* connection = nullptr;
if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) { if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) {
connection = m_network->m_peers[peerId]; 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; FNEPeerConnection* connection = nullptr;
if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) { if (peerId > 0 && (m_network->m_peers.find(peerId) != m_network->m_peers.end())) {
connection = m_network->m_peers[peerId]; connection = m_network->m_peers[peerId];

Loading…
Cancel
Save

Powered by TurnKey Linux.