correct serious issue with affiliation REST API lockup, in some cases the way locking was being done on the REST API could cause it to become deadlocked when querying affils; correct issue with auth token length in REST API;

pull/121/merge
Bryan Biedenkapp 3 weeks ago
parent 03a5e6a1db
commit 3d6a196ea8

@ -1889,7 +1889,7 @@ void TrafficNetwork::taskNetworkRx(NetPacketRequest* req)
FNEPeerConnection* connection = network->m_peers[peerId]; FNEPeerConnection* connection = network->m_peers[peerId];
if (connection != nullptr) { if (connection != nullptr) {
std::string ip = udp::Socket::address(req->address); std::string ip = udp::Socket::address(req->address);
lookups::AffiliationLookup* aff = network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str()); LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str());
network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID); network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID);
@ -1928,7 +1928,7 @@ void TrafficNetwork::taskNetworkRx(NetPacketRequest* req)
FNEPeerConnection* connection = network->m_peers[peerId]; FNEPeerConnection* connection = network->m_peers[peerId];
if (connection != nullptr) { if (connection != nullptr) {
std::string ip = udp::Socket::address(req->address); std::string ip = udp::Socket::address(req->address);
fne_lookups::AffiliationLookup* aff = network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str()); LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str());
network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID); network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID);
@ -1965,7 +1965,7 @@ void TrafficNetwork::taskNetworkRx(NetPacketRequest* req)
FNEPeerConnection* connection = network->m_peers[peerId]; FNEPeerConnection* connection = network->m_peers[peerId];
if (connection != nullptr) { if (connection != nullptr) {
std::string ip = udp::Socket::address(req->address); std::string ip = udp::Socket::address(req->address);
lookups::AffiliationLookup* aff = network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str()); LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str());
network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID); network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID);
@ -2003,7 +2003,7 @@ void TrafficNetwork::taskNetworkRx(NetPacketRequest* req)
FNEPeerConnection* connection = network->m_peers[peerId]; FNEPeerConnection* connection = network->m_peers[peerId];
if (connection != nullptr) { if (connection != nullptr) {
std::string ip = udp::Socket::address(req->address); std::string ip = udp::Socket::address(req->address);
lookups::AffiliationLookup* aff = network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str()); LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str());
network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID); network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID);
@ -2044,7 +2044,7 @@ void TrafficNetwork::taskNetworkRx(NetPacketRequest* req)
// validate peer (simple validation really) // validate peer (simple validation really)
if (connection->connected() && connection->address() == ip) { if (connection->connected() && connection->address() == ip) {
lookups::AffiliationLookup* aff = network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str()); LogError(LOG_MASTER, "PEER %u (%s) has uninitialized affiliations lookup?", peerId, connection->identWithQualifier().c_str());
network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID); network->writePeerNAK(peerId, streamId, TAG_ANNOUNCE, NET_CONN_NAK_INVALID);
@ -2227,34 +2227,74 @@ void TrafficNetwork::eraseStreamPktSeq(uint32_t peerId, uint32_t streamId)
void TrafficNetwork::createPeerAffiliations(uint32_t peerId, std::string peerName) void TrafficNetwork::createPeerAffiliations(uint32_t peerId, std::string peerName)
{ {
erasePeerAffiliations(peerId); std::lock_guard<std::mutex> lock(m_peerAffiliationsMutex);
auto it = m_peerAffiliations.find(peerId);
if (it != m_peerAffiliations.end()) {
m_peerAffiliations.erase(peerId);
}
lookups::ChannelLookup* chLookup = new lookups::ChannelLookup(); lookups::ChannelLookup* chLookup = new lookups::ChannelLookup();
m_peerAffiliations[peerId] = new fne_lookups::AffiliationLookup(peerName, chLookup, m_verbose); std::shared_ptr<fne_lookups::AffiliationLookup> aff(
m_peerAffiliations[peerId]->setDisableUnitRegTimeout(true); // FNE doesn't allow unit registration timeouts (notification must come from the peers) new fne_lookups::AffiliationLookup(peerName, chLookup, m_verbose),
[](fne_lookups::AffiliationLookup* p) {
if (p != nullptr) {
lookups::ChannelLookup* rfCh = p->rfCh();
if (rfCh != nullptr) {
delete rfCh;
}
delete p;
}
});
aff->setDisableUnitRegTimeout(true); // FNE doesn't allow unit registration timeouts (notification must come from the peers)
m_peerAffiliations.insert(peerId, aff);
} }
/* Helper to erase the peer from the peers affiliations list. */ /* Helper to erase the peer from the peers affiliations list. */
bool TrafficNetwork::erasePeerAffiliations(uint32_t peerId) bool TrafficNetwork::erasePeerAffiliations(uint32_t peerId)
{ {
auto it = std::find_if(m_peerAffiliations.begin(), m_peerAffiliations.end(), [&](PeerAffiliationMapPair x) { return x.first == peerId; }); std::lock_guard<std::mutex> lock(m_peerAffiliationsMutex);
auto it = m_peerAffiliations.find(peerId);
if (it != m_peerAffiliations.end()) { if (it != m_peerAffiliations.end()) {
lookups::AffiliationLookup* aff = m_peerAffiliations[peerId];
if (aff != nullptr) {
lookups::ChannelLookup* rfCh = aff->rfCh();
if (rfCh != nullptr)
delete rfCh;
delete aff;
}
m_peerAffiliations.erase(peerId); m_peerAffiliations.erase(peerId);
return true; return true;
} }
return false; return false;
} }
/* Helper to get the peer affiliations entry for a peer. */
std::shared_ptr<fne_lookups::AffiliationLookup> TrafficNetwork::getPeerAffiliations(uint32_t peerId) const
{
std::lock_guard<std::mutex> lock(m_peerAffiliationsMutex);
auto it = m_peerAffiliations.find(peerId);
if (it != m_peerAffiliations.end()) {
return it->second;
}
return nullptr;
}
/* Helper to create a snapshot of all peer affiliation entries. */
std::vector<TrafficNetwork::PeerAffiliationMapPair> TrafficNetwork::peerAffiliationsSnapshot() const
{
std::vector<TrafficNetwork::PeerAffiliationMapPair> snapshot;
std::lock_guard<std::mutex> lock(m_peerAffiliationsMutex);
snapshot.reserve(m_peerAffiliations.size());
for (auto it = m_peerAffiliations.begin(); it != m_peerAffiliations.end(); ++it) {
snapshot.push_back(*it);
}
return snapshot;
}
/* Helper to disconnect a downstream peer. */ /* Helper to disconnect a downstream peer. */
void TrafficNetwork::disconnectPeer(uint32_t peerId, FNEPeerConnection* connection) void TrafficNetwork::disconnectPeer(uint32_t peerId, FNEPeerConnection* connection)
@ -2356,8 +2396,9 @@ bool TrafficNetwork::isPeerLocal(uint32_t peerId)
uint32_t TrafficNetwork::findPeerUnitReg(uint32_t srcId) uint32_t TrafficNetwork::findPeerUnitReg(uint32_t srcId)
{ {
for (auto it = m_peerAffiliations.begin(); it != m_peerAffiliations.end(); ++it) { std::vector<PeerAffiliationMapPair> affSnapshot = peerAffiliationsSnapshot();
fne_lookups::AffiliationLookup* aff = it->second; for (const auto& entry : affSnapshot) {
std::shared_ptr<fne_lookups::AffiliationLookup> aff = entry.second;
if (aff != nullptr) { if (aff != nullptr) {
if (aff->isUnitReg(srcId)) { if (aff->isUnitReg(srcId)) {
return aff->getSSRCByUnitReg(srcId); return aff->getSSRCByUnitReg(srcId);

@ -46,6 +46,7 @@
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include <unordered_map> #include <unordered_map>
#include <memory>
#include <mutex> #include <mutex>
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -339,8 +340,9 @@ namespace network
typedef std::pair<const uint32_t, network::FNEPeerConnection*> PeerMapPair; typedef std::pair<const uint32_t, network::FNEPeerConnection*> PeerMapPair;
concurrent::shared_unordered_map<uint32_t, FNEPeerConnection*> m_peers; concurrent::shared_unordered_map<uint32_t, FNEPeerConnection*> m_peers;
concurrent::unordered_map<uint32_t, json::array> m_peerReplicaPeers; concurrent::unordered_map<uint32_t, json::array> m_peerReplicaPeers;
typedef std::pair<const uint32_t, lookups::AffiliationLookup*> PeerAffiliationMapPair; typedef std::pair<const uint32_t, std::shared_ptr<fne_lookups::AffiliationLookup>> PeerAffiliationMapPair;
concurrent::unordered_map<uint32_t, fne_lookups::AffiliationLookup*> m_peerAffiliations; concurrent::unordered_map<uint32_t, std::shared_ptr<fne_lookups::AffiliationLookup>> m_peerAffiliations;
mutable std::mutex m_peerAffiliationsMutex;
concurrent::shared_unordered_map<uint32_t, std::vector<uint32_t>> m_ccPeerMap; concurrent::shared_unordered_map<uint32_t, std::vector<uint32_t>> m_ccPeerMap;
static std::timed_mutex s_keyQueueMutex; static std::timed_mutex s_keyQueueMutex;
std::unordered_map<uint32_t, uint16_t> m_peerReplicaKeyQueue; std::unordered_map<uint32_t, uint16_t> m_peerReplicaKeyQueue;
@ -470,6 +472,17 @@ namespace network
* @returns bool True, if the peer affiliations were deleted, otherwise false. * @returns bool True, if the peer affiliations were deleted, otherwise false.
*/ */
bool erasePeerAffiliations(uint32_t peerId); bool erasePeerAffiliations(uint32_t peerId);
/**
* @brief Helper to get the peer affiliations entry for a peer.
* @param peerId Peer ID.
* @returns std::shared_ptr<fne_lookups::AffiliationLookup> Shared affiliations lookup instance.
*/
std::shared_ptr<fne_lookups::AffiliationLookup> getPeerAffiliations(uint32_t peerId) const;
/**
* @brief Helper to create a snapshot of all peer affiliation entries.
* @returns std::vector<PeerAffiliationMapPair> Snapshot of peer affiliation entries.
*/
std::vector<PeerAffiliationMapPair> peerAffiliationsSnapshot() const;
/** /**
* @brief Helper to disconnect a downstream peer. * @brief Helper to disconnect a downstream peer.
* @param peerId Peer ID. * @param peerId Peer ID.

@ -646,7 +646,7 @@ bool TagAnalogData::isPeerPermitted(uint32_t peerId, data::NetData& data, uint32
} }
// check the affiliations for this peer to see if we can repeat traffic // check the affiliations for this peer to see if we can repeat traffic
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[lookupPeerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(lookupPeerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId); std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId);
//LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str()); //LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str());

@ -1067,7 +1067,7 @@ bool TagDMRData::isPeerPermitted(uint32_t peerId, data::NetData& data, uint32_t
} }
// check the affiliations for this peer to see if we can repeat traffic // check the affiliations for this peer to see if we can repeat traffic
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[lookupPeerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(lookupPeerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId); std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId);
//LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str()); //LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str());
@ -1405,7 +1405,7 @@ bool TagDMRData::write_CSBK_Grant(uint32_t peerId, uint32_t srcId, uint32_t dstI
} }
// check the affiliations for this peer to see if we can grant traffic // check the affiliations for this peer to see if we can grant traffic
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(peerId); std::string peerIdentity = m_network->resolvePeerIdentity(peerId);
LogError(LOG_MASTER, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", peerId, peerIdentity.c_str()); LogError(LOG_MASTER, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", peerId, peerIdentity.c_str());

@ -941,7 +941,7 @@ bool TagNXDNData::isPeerPermitted(uint32_t peerId, lc::RTCH& lc, uint8_t message
} }
// check the affiliations for this peer to see if we can repeat traffic // check the affiliations for this peer to see if we can repeat traffic
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[lookupPeerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(lookupPeerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId); std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId);
//LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str()); //LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str());
@ -1186,7 +1186,7 @@ bool TagNXDNData::write_Message_Grant(uint32_t peerId, uint32_t srcId, uint32_t
std::unique_ptr<lc::rcch::MESSAGE_TYPE_VCALL_CONN> rcch = std::make_unique<lc::rcch::MESSAGE_TYPE_VCALL_CONN>(); std::unique_ptr<lc::rcch::MESSAGE_TYPE_VCALL_CONN> rcch = std::make_unique<lc::rcch::MESSAGE_TYPE_VCALL_CONN>();
// check the affiliations for this peer to see if we can grant traffic // check the affiliations for this peer to see if we can grant traffic
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(peerId); std::string peerIdentity = m_network->resolvePeerIdentity(peerId);
LogError(LOG_MASTER, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", peerId, peerIdentity.c_str()); LogError(LOG_MASTER, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", peerId, peerIdentity.c_str());

@ -1286,7 +1286,7 @@ bool TagP25Data::processTSDUTo(uint8_t* buffer, uint32_t peerId, uint8_t duid)
} }
// check the affiliations for this peer to see if we can repeat the TSDU // check the affiliations for this peer to see if we can repeat the TSDU
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[lookupPeerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(lookupPeerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId); std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId);
//LogError(LOG_P25, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str()); //LogError(LOG_P25, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str());
@ -1513,7 +1513,7 @@ bool TagP25Data::isPeerPermitted(uint32_t peerId, lc::LC& control, DUID::E duid,
} }
// check the affiliations for this peer to see if we can repeat traffic // check the affiliations for this peer to see if we can repeat traffic
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[lookupPeerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(lookupPeerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId); std::string peerIdentity = m_network->resolvePeerIdentity(lookupPeerId);
//LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str()); //LogError(LOG_NET, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", lookupPeerId, peerIdentity.c_str());
@ -1889,7 +1889,7 @@ bool TagP25Data::write_TSDU_Grant(uint32_t peerId, uint32_t srcId, uint32_t dstI
} }
// check the affiliations for this peer to see if we can grant traffic // check the affiliations for this peer to see if we can grant traffic
lookups::AffiliationLookup* aff = m_network->m_peerAffiliations[peerId]; std::shared_ptr<fne_lookups::AffiliationLookup> aff = m_network->getPeerAffiliations(peerId);
if (aff == nullptr) { if (aff == nullptr) {
std::string peerIdentity = m_network->resolvePeerIdentity(peerId); std::string peerIdentity = m_network->resolvePeerIdentity(peerId);
LogError(LOG_MASTER, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", peerId, peerIdentity.c_str()); LogError(LOG_MASTER, "PEER %u (%s) has an invalid affiliations lookup? This shouldn't happen BUGBUG.", peerId, peerIdentity.c_str());

@ -770,9 +770,9 @@ void RESTAPI::restAPI_PutAuth(const HTTPPayload& request, HTTPPayload& reply, co
return; return;
} }
if (auth.size() > 64) { if (auth.size() != 64) {
invalidateHostToken(host); invalidateHostToken(host);
errorPayload(reply, "auth cannot be longer than 64 characters"); errorPayload(reply, "auth must be 64 characters");
return; return;
} }
@ -2083,40 +2083,44 @@ void RESTAPI::restAPI_GetAffList(const HTTPPayload& request, HTTPPayload& reply,
if (m_network != nullptr) { if (m_network != nullptr) {
uint32_t totalAffiliations = 0U; uint32_t totalAffiliations = 0U;
if (m_network->m_peers.size() > 0) { if (m_network->m_peers.size() > 0) {
std::vector<uint32_t> peerIds = std::vector<uint32_t>();
m_network->m_peers.shared_lock(); m_network->m_peers.shared_lock();
m_network->m_peerAffiliations.lock(false);
for (auto entry : m_network->m_peers) { for (auto entry : m_network->m_peers) {
uint32_t peerId = entry.first; uint32_t peerId = entry.first;
network::FNEPeerConnection* peer = entry.second; network::FNEPeerConnection* peer = entry.second;
if (peer != nullptr) { if (peer != nullptr) {
lookups::AffiliationLookup* affLookup = m_network->m_peerAffiliations[peerId]; peerIds.push_back(peerId);
if (affLookup != nullptr) { }
std::unordered_map<uint32_t, uint32_t> affTable = affLookup->grpAffTable(); }
m_network->m_peers.shared_unlock();
json::object peerObj = json::object();
peerObj["peerId"].set<uint32_t>(peerId); for (uint32_t peerId : peerIds) {
std::shared_ptr<fne_lookups::AffiliationLookup> affLookup = m_network->getPeerAffiliations(peerId);
json::array peerAffs = json::array(); if (affLookup != nullptr) {
if (affLookup->grpAffSize() > 0U) { std::unordered_map<uint32_t, uint32_t> affTable = affLookup->grpAffTable();
for (auto entry : affTable) {
uint32_t srcId = entry.first;
uint32_t dstId = entry.second;
json::object affObj = json::object();
affObj["srcId"].set<uint32_t>(srcId);
affObj["dstId"].set<uint32_t>(dstId);
peerAffs.push_back(json::value(affObj));
}
}
peerObj["affiliations"].set<json::array>(peerAffs); json::object peerObj = json::object();
affs.push_back(json::value(peerObj)); peerObj["peerId"].set<uint32_t>(peerId);
++totalAffiliations;
json::array peerAffs = json::array();
if (affLookup->grpAffSize() > 0U) {
for (auto entry : affTable) {
uint32_t srcId = entry.first;
uint32_t dstId = entry.second;
json::object affObj = json::object();
affObj["srcId"].set<uint32_t>(srcId);
affObj["dstId"].set<uint32_t>(dstId);
peerAffs.push_back(json::value(affObj));
}
} }
peerObj["affiliations"].set<json::array>(peerAffs);
affs.push_back(json::value(peerObj));
++totalAffiliations;
} }
} }
m_network->m_peerAffiliations.unlock();
m_network->m_peers.shared_unlock();
} }
response["totalAffiliations"].set<uint32_t>(totalAffiliations); response["totalAffiliations"].set<uint32_t>(totalAffiliations);

@ -407,9 +407,9 @@ void RESTAPI::restAPI_PutAuth(const HTTPPayload& request, HTTPPayload& reply, co
return; return;
} }
if (auth.size() > 64) { if (auth.size() != 64) {
invalidateHostToken(host); invalidateHostToken(host);
errorPayload(reply, "auth cannot be longer than 64 characters"); errorPayload(reply, "auth must be 64 characters");
return; return;
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.