diff --git a/src/common/lookups/AffiliationLookup.cpp b/src/common/lookups/AffiliationLookup.cpp
index 1646c349..0fbc84a5 100644
--- a/src/common/lookups/AffiliationLookup.cpp
+++ b/src/common/lookups/AffiliationLookup.cpp
@@ -463,6 +463,27 @@ uint32_t AffiliationLookup::getGrantedCh(uint32_t dstId)
return 0U;
}
+///
+/// Helper to get the destination ID granted to the given source ID.
+///
+///
+///
+uint32_t AffiliationLookup::getGrantedBySrcId(uint32_t srcId)
+{
+ if (srcId == 0U) {
+ return 0U;
+ }
+
+ // lookup dynamic channel grant table entry
+ for (auto entry : m_grantSrcIdTable) {
+ if (entry.second == srcId) {
+ return entry.first;
+ }
+ }
+
+ return 0U;
+}
+
///
/// Helper to get the source ID granted for the given destination ID.
///
diff --git a/src/common/lookups/AffiliationLookup.h b/src/common/lookups/AffiliationLookup.h
index 2966bf4f..8385b839 100644
--- a/src/common/lookups/AffiliationLookup.h
+++ b/src/common/lookups/AffiliationLookup.h
@@ -161,6 +161,8 @@ namespace lookups
virtual bool isNetGranted(uint32_t dstId) const;
/// Helper to get the channel granted for the given destination ID.
virtual uint32_t getGrantedCh(uint32_t dstId);
+ /// Helper to get the destination ID granted to the given source ID.
+ virtual uint32_t getGrantedBySrcId(uint32_t srcId);
/// Helper to get the source ID granted for the given destination ID.
virtual uint32_t getGrantedSrcId(uint32_t dstId);
diff --git a/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp b/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp
index c294a07a..e43a3128 100644
--- a/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp
+++ b/src/common/p25/lc/tsbk/OSP_RFSS_STS_BCAST.cpp
@@ -77,8 +77,8 @@ void OSP_RFSS_STS_BCAST::encode(uint8_t* data, bool rawTSBK, bool noTrellis)
tsbkValue = m_siteData.lra(); // Location Registration Area
tsbkValue = (tsbkValue << 4) +
- (m_roamerReaccess) ? 0x02U : 0x00U + // Roamer Reaccess Method
- (m_siteData.netActive()) ? 0x01U : 0x00U; // Network Active
+ ((m_roamerReaccess) ? 0x02U : 0x00U) + // Roamer Reaccess Method
+ ((m_siteData.netActive()) ? 0x01U : 0x00U); // Network Active
tsbkValue = (tsbkValue << 12) + m_siteData.sysId(); // System ID
tsbkValue = (tsbkValue << 8) + m_siteData.rfssId(); // RF Sub-System ID
tsbkValue = (tsbkValue << 8) + m_siteData.siteId(); // Site ID
diff --git a/src/fne/network/FNENetwork.cpp b/src/fne/network/FNENetwork.cpp
index c18f7549..d0bd4f98 100644
--- a/src/fne/network/FNENetwork.cpp
+++ b/src/fne/network/FNENetwork.cpp
@@ -142,20 +142,25 @@ void FNENetwork::clock(uint32_t ms)
std::vector peersToRemove = std::vector();
for (auto peer : m_peers) {
uint32_t id = peer.first;
- FNEPeerConnection connection = peer.second;
-
- if (connection.connected()) {
- uint64_t dt = connection.lastPing() + (m_host->m_pingTime * m_host->m_maxMissedPings);
- if (dt < now) {
- LogInfoEx(LOG_NET, "PEER %u timed out, dt = %u, now = %u", id, dt, now);
- peersToRemove.push_back(id);
+ FNEPeerConnection* connection = peer.second;
+ if (connection != nullptr) {
+ if (connection->connected()) {
+ uint64_t dt = connection->lastPing() + (m_host->m_pingTime * m_host->m_maxMissedPings);
+ if (dt < now) {
+ LogInfoEx(LOG_NET, "PEER %u timed out, dt = %u, now = %u", id, dt, now);
+ peersToRemove.push_back(id);
+ }
}
}
}
// remove any peers
for (uint32_t peerId : peersToRemove) {
+ FNEPeerConnection* connection = m_peers[peerId];
m_peers.erase(peerId);
+ if (connection != nullptr) {
+ delete connection;
+ }
}
// roll the RTP timestamp if no call is in progress
@@ -197,19 +202,20 @@ void FNENetwork::clock(uint32_t ms)
// update current peer packet sequence and stream ID
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end()) && streamId != 0U) {
- FNEPeerConnection connection = m_peers[peerId];
-
+ FNEPeerConnection* connection = m_peers[peerId];
uint16_t pktSeq = rtpHeader.getSequence();
- if ((connection.currStreamId() == streamId) && (pktSeq != connection.pktNextSeq())) {
- LogWarning(LOG_NET, "PEER %u Stream %u out-of-sequence; %u != %u", peerId, streamId, pktSeq, connection.pktNextSeq());
- }
+ if (connection != nullptr) {
+ if ((connection->currStreamId() == streamId) && (pktSeq != connection->pktNextSeq())) {
+ LogWarning(LOG_NET, "PEER %u Stream %u out-of-sequence; %u != %u", peerId, streamId, pktSeq, connection->pktNextSeq());
+ }
- connection.currStreamId(streamId);
- connection.pktLastSeq(pktSeq);
- connection.pktNextSeq(pktSeq + 1);
- if (connection.pktNextSeq() > UINT16_MAX) {
- connection.pktNextSeq(0U);
+ connection->currStreamId(streamId);
+ connection->pktLastSeq(pktSeq);
+ connection->pktNextSeq(pktSeq + 1);
+ if (connection->pktNextSeq() > UINT16_MAX) {
+ connection->pktNextSeq(0U);
+ }
}
m_peers[peerId] = connection;
@@ -228,14 +234,16 @@ void FNENetwork::clock(uint32_t ms)
{
if (fneHeader.getSubFunction() == NET_PROTOCOL_SUBFUNC_DMR) { // Encapsulated DMR data frame
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- if (m_dmrEnabled) {
- if (m_tagDMR != nullptr) {
- m_tagDMR->processFrame(buffer.get(), length, peerId, rtpHeader.getSequence(), streamId);
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ if (m_dmrEnabled) {
+ if (m_tagDMR != nullptr) {
+ m_tagDMR->processFrame(buffer.get(), length, peerId, rtpHeader.getSequence(), streamId);
+ }
}
}
}
@@ -243,14 +251,16 @@ void FNENetwork::clock(uint32_t ms)
}
else if (fneHeader.getSubFunction() == NET_PROTOCOL_SUBFUNC_P25) { // Encapsulated P25 data frame
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- if (m_p25Enabled) {
- if (m_tagP25 != nullptr) {
- m_tagP25->processFrame(buffer.get(), length, peerId, rtpHeader.getSequence(), streamId);
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ if (m_p25Enabled) {
+ if (m_tagP25 != nullptr) {
+ m_tagP25->processFrame(buffer.get(), length, peerId, rtpHeader.getSequence(), streamId);
+ }
}
}
}
@@ -258,14 +268,16 @@ void FNENetwork::clock(uint32_t ms)
}
else if (fneHeader.getSubFunction() == NET_PROTOCOL_SUBFUNC_NXDN) { // Encapsulated NXDN data frame
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- if (m_nxdnEnabled) {
- if (m_tagNXDN != nullptr) {
- m_tagNXDN->processFrame(buffer.get(), length, peerId, rtpHeader.getSequence(), streamId);
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ if (m_nxdnEnabled) {
+ if (m_tagNXDN != nullptr) {
+ m_tagNXDN->processFrame(buffer.get(), length, peerId, rtpHeader.getSequence(), streamId);
+ }
}
}
}
@@ -280,22 +292,22 @@ void FNENetwork::clock(uint32_t ms)
case NET_FUNC_RPTL: // Repeater Login
{
if (peerId > 0 && (m_peers.find(peerId) == m_peers.end())) {
- FNEPeerConnection connection = FNEPeerConnection(peerId, address, addrLen);
- connection.lastPing(now);
- connection.currStreamId(streamId);
+ FNEPeerConnection* connection = new FNEPeerConnection(peerId, address, addrLen);
+ connection->lastPing(now);
+ connection->currStreamId(streamId);
std::uniform_int_distribution dist(DVM_RAND_MIN, DVM_RAND_MAX);
- connection.salt(dist(m_random));
+ connection->salt(dist(m_random));
- LogInfoEx(LOG_NET, "Repeater logging in with PEER %u, %s:%u", peerId, connection.address().c_str(), connection.port());
+ LogInfoEx(LOG_NET, "Repeater logging in with PEER %u, %s:%u", peerId, connection->address().c_str(), connection->port());
- connection.connectionState(NET_STAT_WAITING_AUTHORISATION);
+ connection->connectionState(NET_STAT_WAITING_AUTHORISATION);
m_peers[peerId] = connection;
// transmit salt to peer
uint8_t salt[4U];
::memset(salt, 0x00U, 4U);
- __SET_UINT32(connection.salt(), salt, 0U);
+ __SET_UINT32(connection->salt(), salt, 0U);
writePeerACK(peerId, salt, 4U);
LogInfoEx(LOG_NET, "Challenge response send to PEER %u for login", peerId);
@@ -306,13 +318,16 @@ void FNENetwork::clock(uint32_t ms)
// check if the peer is in our peer list -- if he is, and he isn't in a running state, reset
// the login sequence
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- connection.lastPing(now);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ connection->lastPing(now);
- if (connection.connectionState() != NET_STAT_RUNNING) {
- auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
- if (it != m_peers.end()) {
- m_peers.erase(peerId);
+ if (connection->connectionState() != NET_STAT_RUNNING) {
+ auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
+ if (it != m_peers.end()) {
+ m_peers.erase(peerId);
+ delete connection;
+ }
}
}
}
@@ -322,67 +337,69 @@ void FNENetwork::clock(uint32_t ms)
case NET_FUNC_RPTK: // Repeater Authentication
{
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- connection.lastPing(now);
-
- if (connection.connectionState() == NET_STAT_WAITING_AUTHORISATION) {
- // get the hash from the frame message
- uint8_t hash[length - 8U];
- ::memset(hash, 0x00U, length - 8U);
- ::memcpy(hash, buffer.get() + 8U, length - 8U);
-
- // generate our own hash
- uint8_t salt[4U];
- ::memset(salt, 0x00U, 4U);
- __SET_UINT32(connection.salt(), salt, 0U);
-
- size_t size = m_password.size();
- uint8_t* in = new uint8_t[size + sizeof(uint32_t)];
- ::memcpy(in, salt, sizeof(uint32_t));
- for (size_t i = 0U; i < size; i++)
- in[i + sizeof(uint32_t)] = m_password.at(i);
-
- uint8_t out[32U];
- edac::SHA256 sha256;
- sha256.buffer(in, (uint32_t)(size + sizeof(uint32_t)), out);
-
- delete[] in;
-
- // validate hash
- bool valid = false;
- if (length - 8U == 32U) {
- valid = true;
- for (uint8_t i = 0; i < 32U; i++) {
- if (hash[i] != out[i]) {
- valid = false;
- break;
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ connection->lastPing(now);
+
+ if (connection->connectionState() == NET_STAT_WAITING_AUTHORISATION) {
+ // get the hash from the frame message
+ uint8_t hash[length - 8U];
+ ::memset(hash, 0x00U, length - 8U);
+ ::memcpy(hash, buffer.get() + 8U, length - 8U);
+
+ // generate our own hash
+ uint8_t salt[4U];
+ ::memset(salt, 0x00U, 4U);
+ __SET_UINT32(connection->salt(), salt, 0U);
+
+ size_t size = m_password.size();
+ uint8_t* in = new uint8_t[size + sizeof(uint32_t)];
+ ::memcpy(in, salt, sizeof(uint32_t));
+ for (size_t i = 0U; i < size; i++)
+ in[i + sizeof(uint32_t)] = m_password.at(i);
+
+ uint8_t out[32U];
+ edac::SHA256 sha256;
+ sha256.buffer(in, (uint32_t)(size + sizeof(uint32_t)), out);
+
+ delete[] in;
+
+ // validate hash
+ bool valid = false;
+ if (length - 8U == 32U) {
+ valid = true;
+ for (uint8_t i = 0; i < 32U; i++) {
+ if (hash[i] != out[i]) {
+ valid = false;
+ break;
+ }
}
}
- }
- if (valid) {
- connection.connectionState(NET_STAT_WAITING_CONFIG);
- writePeerACK(peerId);
- LogInfoEx(LOG_NET, "PEER %u has completed the login exchange", peerId);
+ if (valid) {
+ connection->connectionState(NET_STAT_WAITING_CONFIG);
+ writePeerACK(peerId);
+ LogInfoEx(LOG_NET, "PEER %u has completed the login exchange", peerId);
+ }
+ else {
+ LogWarning(LOG_NET, "PEER %u has failed the login exchange", peerId);
+ writePeerNAK(peerId, TAG_REPEATER_AUTH);
+ auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
+ if (it != m_peers.end()) {
+ m_peers.erase(peerId);
+ }
+ }
+
+ m_peers[peerId] = connection;
}
else {
- LogWarning(LOG_NET, "PEER %u has failed the login exchange", peerId);
+ LogWarning(LOG_NET, "PEER %u tried login exchange while in an incorrect state?", peerId);
writePeerNAK(peerId, TAG_REPEATER_AUTH);
auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
if (it != m_peers.end()) {
m_peers.erase(peerId);
}
}
-
- m_peers[peerId] = connection;
- }
- else {
- LogWarning(LOG_NET, "PEER %u tried login exchange while in an incorrect state?", peerId);
- writePeerNAK(peerId, TAG_REPEATER_AUTH);
- auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
- if (it != m_peers.end()) {
- m_peers.erase(peerId);
- }
}
}
else {
@@ -393,29 +410,20 @@ void FNENetwork::clock(uint32_t ms)
case NET_FUNC_RPTC: // Repeater Configuration
{
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- connection.lastPing(now);
-
- if (connection.connectionState() == NET_STAT_WAITING_CONFIG) {
- uint8_t rawPayload[length - 8U];
- ::memset(rawPayload, 0x00U, length - 8U);
- ::memcpy(rawPayload, buffer.get() + 8U, length - 8U);
- std::string payload(rawPayload, rawPayload + (length - 8U));
-
- // parse JSON body
- json::value v;
- std::string err = json::parse(v, payload);
- if (!err.empty()) {
- LogWarning(LOG_NET, "PEER %u has supplied invalid configuration data", peerId);
- writePeerNAK(peerId, TAG_REPEATER_AUTH);
- auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
- if (it != m_peers.end()) {
- m_peers.erase(peerId);
- }
- }
- else {
- // ensure parsed JSON is an object
- if (!v.is()) {
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ connection->lastPing(now);
+
+ if (connection->connectionState() == NET_STAT_WAITING_CONFIG) {
+ uint8_t rawPayload[length - 8U];
+ ::memset(rawPayload, 0x00U, length - 8U);
+ ::memcpy(rawPayload, buffer.get() + 8U, length - 8U);
+ std::string payload(rawPayload, rawPayload + (length - 8U));
+
+ // parse JSON body
+ json::value v;
+ std::string err = json::parse(v, payload);
+ if (!err.empty()) {
LogWarning(LOG_NET, "PEER %u has supplied invalid configuration data", peerId);
writePeerNAK(peerId, TAG_REPEATER_AUTH);
auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
@@ -423,40 +431,51 @@ void FNENetwork::clock(uint32_t ms)
m_peers.erase(peerId);
}
}
- else {
- connection.config(v.get());
- connection.connectionState(NET_STAT_RUNNING);
- connection.connected(true);
- connection.pingsReceived(0U);
- connection.lastPing(now);
- m_peers[peerId] = connection;
-
- writePeerACK(peerId);
- LogInfoEx(LOG_NET, "PEER %u has completed the configuration exchange", peerId);
-
- // queue final update messages and flush
- writeWhitelistRIDs(peerId, true);
- writeBlacklistRIDs(peerId, true);
- m_frameQueue->flushQueue();
-
- writeTGIDs(peerId, true);
- writeDeactiveTGIDs(peerId, true);
- m_frameQueue->flushQueue();
-
- json::object peerConfig = connection.config();
- if (peerConfig["software"].is()) {
- std::string software = peerConfig["software"].get();
- LogInfoEx(LOG_NET, "PEER %u reports software %s", peerId, software.c_str());
+ else {
+ // ensure parsed JSON is an object
+ if (!v.is()) {
+ LogWarning(LOG_NET, "PEER %u has supplied invalid configuration data", peerId);
+ writePeerNAK(peerId, TAG_REPEATER_AUTH);
+ auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
+ if (it != m_peers.end()) {
+ m_peers.erase(peerId);
+ }
+ }
+ else {
+ connection->config(v.get());
+ connection->connectionState(NET_STAT_RUNNING);
+ connection->connected(true);
+ connection->pingsReceived(0U);
+ connection->lastPing(now);
+ m_peers[peerId] = connection;
+
+ writePeerACK(peerId);
+ LogInfoEx(LOG_NET, "PEER %u has completed the configuration exchange", peerId);
+
+ // queue final update messages and flush
+ writeWhitelistRIDs(peerId, true);
+ writeBlacklistRIDs(peerId, true);
+ m_frameQueue->flushQueue();
+
+ writeTGIDs(peerId, true);
+ writeDeactiveTGIDs(peerId, true);
+ m_frameQueue->flushQueue();
+
+ json::object peerConfig = connection->config();
+ if (peerConfig["software"].is()) {
+ std::string software = peerConfig["software"].get();
+ LogInfoEx(LOG_NET, "PEER %u reports software %s", peerId, software.c_str());
+ }
}
}
}
- }
- else {
- LogWarning(LOG_NET, "PEER %u tried login exchange while in an incorrect state?", peerId);
- writePeerNAK(peerId, TAG_REPEATER_CONFIG);
- auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
- if (it != m_peers.end()) {
- m_peers.erase(peerId);
+ else {
+ LogWarning(LOG_NET, "PEER %u tried login exchange while in an incorrect state?", peerId);
+ writePeerNAK(peerId, TAG_REPEATER_CONFIG);
+ auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
+ if (it != m_peers.end()) {
+ m_peers.erase(peerId);
+ }
}
}
}
@@ -469,16 +488,19 @@ void FNENetwork::clock(uint32_t ms)
case NET_FUNC_RPT_CLOSING: // Repeater Closing (Disconnect)
{
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- LogInfoEx(LOG_NET, "PEER %u is closing down", peerId);
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ LogInfoEx(LOG_NET, "PEER %u is closing down", peerId);
- auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
- if (it != m_peers.end()) {
- m_peers.erase(peerId);
+ auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
+ if (it != m_peers.end()) {
+ m_peers.erase(peerId);
+ delete connection;
+ }
}
}
}
@@ -487,27 +509,29 @@ void FNENetwork::clock(uint32_t ms)
case NET_FUNC_PING: // Repeater Ping
{
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
-
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- uint32_t pingsRx = connection.pingsReceived();
- pingsRx++;
-
- connection.pingsReceived(pingsRx);
- connection.lastPing(now);
- connection.pktLastSeq(connection.pktLastSeq() + 1);
-
- m_peers[peerId] = connection;
- writePeerCommand(peerId, { NET_FUNC_PONG, NET_SUBFUNC_NOP });
-
- if (m_debug) {
- LogDebug(LOG_NET, "PEER %u ping received and answered, pingsReceived = %u", peerId, connection.pingsReceived());
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
+
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ uint32_t pingsRx = connection->pingsReceived();
+ pingsRx++;
+
+ connection->pingsReceived(pingsRx);
+ connection->lastPing(now);
+ connection->pktLastSeq(connection->pktLastSeq() + 1);
+
+ m_peers[peerId] = connection;
+ writePeerCommand(peerId, { NET_FUNC_PONG, NET_SUBFUNC_NOP });
+
+ if (m_debug) {
+ LogDebug(LOG_NET, "PEER %u ping received and answered, pingsReceived = %u", peerId, connection->pingsReceived());
+ }
+ }
+ else {
+ writePeerNAK(peerId, TAG_REPEATER_PING);
}
- }
- else {
- writePeerNAK(peerId, TAG_REPEATER_PING);
}
}
}
@@ -516,15 +540,17 @@ void FNENetwork::clock(uint32_t ms)
case NET_FUNC_GRANT_REQ: // Repeater Grant Request
{
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- /* ignored */
- }
- else {
- writePeerNAK(peerId, TAG_REPEATER_GRANT);
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ /* ignored */
+ }
+ else {
+ writePeerNAK(peerId, TAG_REPEATER_GRANT);
+ }
}
}
}
@@ -535,20 +561,22 @@ void FNENetwork::clock(uint32_t ms)
if (fneHeader.getSubFunction() == NET_TRANSFER_SUBFUNC_ACTIVITY) { // Peer Activity Log Transfer
if (m_allowActivityTransfer) {
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
-
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- uint8_t rawPayload[length - 11U];
- ::memset(rawPayload, 0x00U, length - 11U);
- ::memcpy(rawPayload, buffer.get() + 11U, length - 11U);
- std::string payload(rawPayload, rawPayload + (length - 11U));
-
- ::ActivityLog("%u %s", peerId, payload.c_str());
- }
- else {
- writePeerNAK(peerId, TAG_TRANSFER_ACT_LOG);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
+
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ uint8_t rawPayload[length - 11U];
+ ::memset(rawPayload, 0x00U, length - 11U);
+ ::memcpy(rawPayload, buffer.get() + 11U, length - 11U);
+ std::string payload(rawPayload, rawPayload + (length - 11U));
+
+ ::ActivityLog("%u %s", peerId, payload.c_str());
+ }
+ else {
+ writePeerNAK(peerId, TAG_TRANSFER_ACT_LOG);
+ }
}
}
}
@@ -556,23 +584,25 @@ void FNENetwork::clock(uint32_t ms)
else if (fneHeader.getSubFunction() == NET_TRANSFER_SUBFUNC_DIAG) { // Peer Diagnostic Log Transfer
if (m_allowDiagnosticTransfer) {
if (peerId > 0 && (m_peers.find(peerId) != m_peers.end())) {
- FNEPeerConnection connection = m_peers[peerId];
- std::string ip = UDPSocket::address(address);
-
- // validate peer (simple validation really)
- if (connection.connected() && connection.address() == ip) {
- uint8_t rawPayload[length - 11U];
- ::memset(rawPayload, 0x00U, length - 11U);
- ::memcpy(rawPayload, buffer.get() + 11U, length - 11U);
- std::string payload(rawPayload, rawPayload + (length - 11U));
-
- bool currState = g_disableTimeDisplay;
- g_disableTimeDisplay = true;
- ::Log(9999U, nullptr, "%u %s", peerId, payload.c_str());
- g_disableTimeDisplay = currState;
- }
- else {
- writePeerNAK(peerId, TAG_TRANSFER_DIAG_LOG);
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ std::string ip = UDPSocket::address(address);
+
+ // validate peer (simple validation really)
+ if (connection->connected() && connection->address() == ip) {
+ uint8_t rawPayload[length - 11U];
+ ::memset(rawPayload, 0x00U, length - 11U);
+ ::memcpy(rawPayload, buffer.get() + 11U, length - 11U);
+ std::string payload(rawPayload, rawPayload + (length - 11U));
+
+ bool currState = g_disableTimeDisplay;
+ g_disableTimeDisplay = true;
+ ::Log(9999U, nullptr, "%u %s", peerId, payload.c_str());
+ g_disableTimeDisplay = currState;
+ }
+ else {
+ writePeerNAK(peerId, TAG_TRANSFER_DIAG_LOG);
+ }
}
}
}
@@ -931,17 +961,20 @@ bool FNENetwork::writePeer(uint32_t peerId, FrameQueue::OpcodePair opcode, const
{
auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
if (it != m_peers.end()) {
- uint32_t peerStreamId = m_peers[peerId].currStreamId();
- if (streamId == 0U) {
- streamId = peerStreamId;
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ uint32_t peerStreamId = connection->currStreamId();
+ if (streamId == 0U) {
+ streamId = peerStreamId;
+ }
+ sockaddr_storage addr = connection->socketStorage();
+ uint32_t addrLen = connection->sockStorageLen();
+
+ m_frameQueue->enqueueMessage(data, length, streamId, peerId, m_peerId, opcode, pktSeq, addr, addrLen);
+ if (queueOnly)
+ return true;
+ return m_frameQueue->flushQueue();
}
- sockaddr_storage addr = m_peers[peerId].socketStorage();
- uint32_t addrLen = m_peers[peerId].sockStorageLen();
-
- m_frameQueue->enqueueMessage(data, length, streamId, peerId, m_peerId, opcode, pktSeq, addr, addrLen);
- if (queueOnly)
- return true;
- return m_frameQueue->flushQueue();
}
return false;
@@ -961,12 +994,15 @@ bool FNENetwork::writePeer(uint32_t peerId, FrameQueue::OpcodePair opcode, const
{
auto it = std::find_if(m_peers.begin(), m_peers.end(), [&](PeerMapPair x) { return x.first == peerId; });
if (it != m_peers.end()) {
- if (incPktSeq) {
- m_peers[peerId].pktLastSeq(m_peers[peerId].pktLastSeq() + 1);
- }
- uint16_t pktSeq = m_peers[peerId].pktLastSeq();
+ FNEPeerConnection* connection = m_peers[peerId];
+ if (connection != nullptr) {
+ if (incPktSeq) {
+ connection->pktLastSeq(connection->pktLastSeq() + 1);
+ }
+ uint16_t pktSeq = connection->pktLastSeq();
- return writePeer(peerId, opcode, data, length, pktSeq, streamId, queueOnly);
+ return writePeer(peerId, opcode, data, length, pktSeq, streamId, queueOnly);
+ }
}
return false;
diff --git a/src/fne/network/FNENetwork.h b/src/fne/network/FNENetwork.h
index 03970ec1..1a1996ce 100644
--- a/src/fne/network/FNENetwork.h
+++ b/src/fne/network/FNENetwork.h
@@ -56,6 +56,10 @@ namespace network
class HOST_SW_API FNEPeerConnection {
public:
+ auto operator=(FNEPeerConnection&) -> FNEPeerConnection& = delete;
+ auto operator=(FNEPeerConnection&&) -> FNEPeerConnection& = delete;
+ FNEPeerConnection(FNEPeerConnection&) = delete;
+
/// Initializes a new insatnce of the FNEPeerConnection class.
FNEPeerConnection() :
m_id(0U),
@@ -101,37 +105,6 @@ namespace network
assert(m_port > 0U);
}
- /// Equals operator. Copies this FNEPeerConnection to another FNEPeerConnection.
- virtual FNEPeerConnection& operator=(const FNEPeerConnection& data)
- {
- if (this != &data) {
- m_id = data.m_id;
-
- m_currStreamId = data.m_currStreamId;
-
- m_socketStorage = data.m_socketStorage;
- m_sockStorageLen = data.m_sockStorageLen;
-
- m_address = data.m_address;
- m_port = data.m_port;
-
- m_salt = data.m_salt;
-
- m_connected = data.m_connected;
- m_connectionState = data.m_connectionState;
-
- m_pingsReceived = data.m_pingsReceived;
- m_lastPing = data.m_lastPing;
-
- m_config = data.m_config;
-
- m_pktLastSeq = data.m_pktLastSeq;
- m_pktNextSeq = data.m_pktNextSeq;
- }
-
- return *this;
- }
-
public:
/// Peer ID.
__PROPERTY_PLAIN(uint32_t, id);
@@ -235,8 +208,8 @@ namespace network
NET_CONN_STATUS m_status;
- typedef std::pair PeerMapPair;
- std::unordered_map m_peers;
+ typedef std::pair PeerMapPair;
+ std::unordered_map m_peers;
Timer m_maintainenceTimer;
Timer m_updateLookupTimer;
diff --git a/src/fne/network/RESTAPI.cpp b/src/fne/network/RESTAPI.cpp
index 97915043..1d17abff 100644
--- a/src/fne/network/RESTAPI.cpp
+++ b/src/fne/network/RESTAPI.cpp
@@ -461,30 +461,31 @@ void RESTAPI::restAPI_GetPeerList(const HTTPPayload& request, HTTPPayload& reply
if (m_network->m_peers.size() > 0) {
for (auto entry : m_network->m_peers) {
uint32_t peerId = entry.first;
- network::FNEPeerConnection peer = entry.second;
-
- json::object peerObj = json::object();
- peerObj["peerId"].set(peerId);
-
- std::string address = peer.address();
- peerObj["address"].set(address);
- uint16_t port = peer.port();
- peerObj["port"].set(port);
- bool connected = peer.connected();
- peerObj["connected"].set(connected);
- uint32_t connectionState = (uint32_t)peer.connectionState();
- peerObj["connectionState"].set(connectionState);
- uint32_t pingsReceived = peer.pingsReceived();
- peerObj["pingsReceived"].set(pingsReceived);
- uint64_t lastPing = peer.lastPing();
- peerObj["lastPing"].set(lastPing);
-
- json::object peerConfig = peer.config();
- if (peerConfig["rcon"].is())
- peerConfig.erase("rcon");
- peerObj["config"].set(peerConfig);
-
- peers.push_back(json::value(peerObj));
+ network::FNEPeerConnection* peer = entry.second;
+ if (peer != nullptr) {
+ json::object peerObj = json::object();
+ peerObj["peerId"].set(peerId);
+
+ std::string address = peer->address();
+ peerObj["address"].set(address);
+ uint16_t port = peer->port();
+ peerObj["port"].set(port);
+ bool connected = peer->connected();
+ peerObj["connected"].set(connected);
+ uint32_t connectionState = (uint32_t)peer->connectionState();
+ peerObj["connectionState"].set(connectionState);
+ uint32_t pingsReceived = peer->pingsReceived();
+ peerObj["pingsReceived"].set(pingsReceived);
+ uint64_t lastPing = peer->lastPing();
+ peerObj["lastPing"].set(lastPing);
+
+ json::object peerConfig = peer->config();
+ if (peerConfig["rcon"].is())
+ peerConfig.erase("rcon");
+ peerObj["config"].set(peerConfig);
+
+ peers.push_back(json::value(peerObj));
+ }
}
}
}