mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 07:47:30 +02:00
have domain-server reject audio and avatar mixers with bad UUID
This commit is contained in:
parent
89546f7140
commit
001432ec55
8 changed files with 106 additions and 71 deletions
|
@ -129,7 +129,7 @@ void AudioMixer::run() {
|
||||||
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
||||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
NodeList::getInstance()->sendDomainServerCheckIn(this->getUUID().toRfc4122().constData());
|
||||||
|
|
||||||
if (Logging::shouldSendStats() && numStatCollections > 0) {
|
if (Logging::shouldSendStats() && numStatCollections > 0) {
|
||||||
// if we should be sending stats to Logstash send the appropriate average now
|
// if we should be sending stats to Logstash send the appropriate average now
|
||||||
|
|
|
@ -119,7 +119,7 @@ void AvatarMixer::run() {
|
||||||
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
// send a check in packet to the domain server if DOMAIN_SERVER_CHECK_IN_USECS has elapsed
|
||||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
NodeList::getInstance()->sendDomainServerCheckIn(this->getUUID().toRfc4122().constData());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) &&
|
if (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) &&
|
||||||
|
|
|
@ -247,77 +247,105 @@ int main(int argc, const char* argv[]) {
|
||||||
nodePublicAddress.sin_addr.s_addr = 0;
|
nodePublicAddress.sin_addr.s_addr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* newNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
|
bool matchedUUID = true;
|
||||||
(sockaddr*) &nodeLocalAddress,
|
|
||||||
nodeType,
|
|
||||||
nodeList->getLastNodeID());
|
|
||||||
|
|
||||||
// if addOrUpdateNode returns NULL this was a solo node we already have, don't talk back to it
|
if ((nodeType == NODE_TYPE_AVATAR_MIXER || nodeType == NODE_TYPE_AUDIO_MIXER) &&
|
||||||
if (newNode) {
|
!nodeList->soloNodeOfType(nodeType)) {
|
||||||
if (newNode->getNodeID() == nodeList->getLastNodeID()) {
|
// if this is an audio-mixer or an avatar-mixer and we don't have one yet
|
||||||
nodeList->increaseNodeID();
|
// we need to check the GUID of the assignment in the queue
|
||||||
|
// (if it exists) to make sure there is a match
|
||||||
|
|
||||||
|
// reset matchedUUID to false so there is no match by default
|
||||||
|
matchedUUID = false;
|
||||||
|
|
||||||
|
// pull the UUID passed with the check in
|
||||||
|
QUuid checkInUUID = QUuid::fromRfc4122(QByteArray((const char*) packetData + numBytesSenderHeader +
|
||||||
|
sizeof(NODE_TYPE),
|
||||||
|
NUM_BYTES_RFC4122_UUID));
|
||||||
|
|
||||||
|
// lock the assignment queue
|
||||||
|
::assignmentQueueMutex.lock();
|
||||||
|
|
||||||
|
std::deque<Assignment*>::iterator assignment = ::assignmentQueue.begin();
|
||||||
|
|
||||||
|
Assignment::Type matchType = nodeType == NODE_TYPE_AUDIO_MIXER
|
||||||
|
? Assignment::AudioMixerType : Assignment::AvatarMixerType;
|
||||||
|
|
||||||
|
// enumerate the assignments and see if there is a type and UUID match
|
||||||
|
while (assignment != ::assignmentQueue.end()) {
|
||||||
|
if ((*assignment)->getType() == matchType
|
||||||
|
&& (*assignment)->getUUID() == checkInUUID) {
|
||||||
|
// type and UUID match
|
||||||
|
matchedUUID = true;
|
||||||
|
|
||||||
|
// remove this assignment from the queue
|
||||||
|
::assignmentQueue.erase(assignment);
|
||||||
|
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// no match, keep looking
|
||||||
|
assignment++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
|
// unlock the assignment queue
|
||||||
|
::assignmentQueueMutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matchedUUID) {
|
||||||
|
Node* newNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
|
||||||
|
(sockaddr*) &nodeLocalAddress,
|
||||||
|
nodeType,
|
||||||
|
nodeList->getLastNodeID());
|
||||||
|
|
||||||
currentBufferPos = broadcastPacket + numHeaderBytes;
|
// if addOrUpdateNode returns NULL this was a solo node we already have, don't talk back to it
|
||||||
startPointer = currentBufferPos;
|
if (newNode) {
|
||||||
|
if (newNode->getNodeID() == nodeList->getLastNodeID()) {
|
||||||
unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + sizeof(NODE_TYPE)
|
nodeList->increaseNodeID();
|
||||||
+ numBytesSocket + sizeof(unsigned char);
|
}
|
||||||
int numInterestTypes = *(nodeTypesOfInterest - 1);
|
|
||||||
|
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
|
||||||
if (numInterestTypes > 0) {
|
|
||||||
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
currentBufferPos = broadcastPacket + numHeaderBytes;
|
||||||
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
startPointer = currentBufferPos;
|
||||||
if (!node->matches((sockaddr*) &nodePublicAddress, (sockaddr*) &nodeLocalAddress, nodeType) &&
|
|
||||||
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
int numBytesUUID = (nodeType == NODE_TYPE_AUDIO_MIXER || nodeType == NODE_TYPE_AVATAR_MIXER)
|
||||||
// this is not the node themselves
|
? NUM_BYTES_RFC4122_UUID
|
||||||
// and this is an node of a type in the passed node types of interest
|
: 0;
|
||||||
// or the node did not pass us any specific types they are interested in
|
|
||||||
|
unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + numBytesUUID +
|
||||||
if (memchr(SOLO_NODE_TYPES, node->getType(), sizeof(SOLO_NODE_TYPES)) == NULL) {
|
sizeof(NODE_TYPE) + numBytesSocket + sizeof(unsigned char);
|
||||||
// this is an node of which there can be multiple, just add them to the packet
|
int numInterestTypes = *(nodeTypesOfInterest - 1);
|
||||||
|
|
||||||
|
if (numInterestTypes > 0) {
|
||||||
|
// if the node has sent no types of interest, assume they want nothing but their own ID back
|
||||||
|
for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) {
|
||||||
|
if (!node->matches((sockaddr*) &nodePublicAddress, (sockaddr*) &nodeLocalAddress, nodeType) &&
|
||||||
|
memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) {
|
||||||
|
|
||||||
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
// don't send avatar nodes to other avatars, that will come from avatar mixer
|
||||||
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
||||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node));
|
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, &(*node));
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
// solo node, we need to only send newest
|
|
||||||
if (newestSoloNodes[node->getType()] == NULL ||
|
|
||||||
newestSoloNodes[node->getType()]->getWakeMicrostamp() < node->getWakeMicrostamp()) {
|
|
||||||
// we have to set the newer solo node to add it to the broadcast later
|
|
||||||
newestSoloNodes[node->getType()] = &(*node);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::map<char, Node *>::iterator soloNode = newestSoloNodes.begin();
|
// update last receive to now
|
||||||
soloNode != newestSoloNodes.end();
|
uint64_t timeNow = usecTimestampNow();
|
||||||
soloNode++) {
|
newNode->setLastHeardMicrostamp(timeNow);
|
||||||
// this is the newest alive solo node, add them to the packet
|
|
||||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, soloNode->second);
|
// add the node ID to the end of the pointer
|
||||||
}
|
currentBufferPos += packNodeId(currentBufferPos, newNode->getNodeID());
|
||||||
|
|
||||||
|
// send the constructed list back to this node
|
||||||
|
nodeList->getNodeSocket()->send((sockaddr*)&replyDestinationSocket,
|
||||||
|
broadcastPacket,
|
||||||
|
(currentBufferPos - startPointer) + numHeaderBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update last receive to now
|
|
||||||
uint64_t timeNow = usecTimestampNow();
|
|
||||||
newNode->setLastHeardMicrostamp(timeNow);
|
|
||||||
|
|
||||||
if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY
|
|
||||||
&& memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) {
|
|
||||||
newNode->setWakeMicrostamp(timeNow);
|
|
||||||
}
|
|
||||||
|
|
||||||
// add the node ID to the end of the pointer
|
|
||||||
currentBufferPos += packNodeId(currentBufferPos, newNode->getNodeID());
|
|
||||||
|
|
||||||
// send the constructed list back to this node
|
|
||||||
nodeList->getNodeSocket()->send((sockaddr*)&replyDestinationSocket,
|
|
||||||
broadcastPacket,
|
|
||||||
(currentBufferPos - startPointer) + numHeaderBytes);
|
|
||||||
}
|
}
|
||||||
} else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
} else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
|
||||||
|
|
||||||
|
@ -355,8 +383,8 @@ int main(int argc, const char* argv[]) {
|
||||||
::assignmentQueue.erase(assignment);
|
::assignmentQueue.erase(assignment);
|
||||||
delete *assignment;
|
delete *assignment;
|
||||||
}
|
}
|
||||||
} else {
|
} else if ((*assignment)->getType() == Assignment::VoxelServerType) {
|
||||||
// remove the assignment from the queue
|
// this is a voxel-server assignment, remove the assignment from the queue
|
||||||
::assignmentQueue.erase(assignment);
|
::assignmentQueue.erase(assignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,7 +426,8 @@ int main(int argc, const char* argv[]) {
|
||||||
::assignmentQueue.erase(assignment);
|
::assignmentQueue.erase(assignment);
|
||||||
delete *assignment;
|
delete *assignment;
|
||||||
}
|
}
|
||||||
} else {
|
} else if ((*assignment)->getType() == Assignment::VoxelServerType) {
|
||||||
|
// this is a voxel server assignment
|
||||||
// remove the assignment from the queue
|
// remove the assignment from the queue
|
||||||
::assignmentQueue.erase(assignment);
|
::assignmentQueue.erase(assignment);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
const char IPv4_ADDRESS_DESIGNATOR = 4;
|
const char IPv4_ADDRESS_DESIGNATOR = 4;
|
||||||
const char IPv6_ADDRESS_DESIGNATOR = 6;
|
const char IPv6_ADDRESS_DESIGNATOR = 6;
|
||||||
|
|
||||||
const int NUM_BYTES_RFC4122_UUID = 16;
|
|
||||||
|
|
||||||
Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) :
|
Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) :
|
||||||
_command(command),
|
_command(command),
|
||||||
_type(type),
|
_type(type),
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
#include "NodeList.h"
|
#include "NodeList.h"
|
||||||
|
|
||||||
|
const int NUM_BYTES_RFC4122_UUID = 16;
|
||||||
|
|
||||||
/// Holds information used for request, creation, and deployment of assignments
|
/// Holds information used for request, creation, and deployment of assignments
|
||||||
class Assignment : public QObject {
|
class Assignment : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
|
@ -268,7 +268,7 @@ void NodeList::setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNo
|
||||||
_nodeTypesOfInterest[numNodeTypesOfInterest] = '\0';
|
_nodeTypesOfInterest[numNodeTypesOfInterest] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::sendDomainServerCheckIn() {
|
void NodeList::sendDomainServerCheckIn(const char* assignmentUUID) {
|
||||||
static bool printedDomainServerIP = false;
|
static bool printedDomainServerIP = false;
|
||||||
|
|
||||||
// Lookup the IP address of the domain server if we need to
|
// Lookup the IP address of the domain server if we need to
|
||||||
|
@ -297,9 +297,9 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
|
|
||||||
const int IP_ADDRESS_BYTES = 4;
|
const int IP_ADDRESS_BYTES = 4;
|
||||||
|
|
||||||
// check in packet has header, node type, port, IP, node types of interest, null termination
|
// check in packet has header, optional UUID, node type, port, IP, node types of interest, null termination
|
||||||
int numPacketBytes = sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION) + sizeof(NODE_TYPE) + sizeof(uint16_t) +
|
int numPacketBytes = sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION) + sizeof(NODE_TYPE) +
|
||||||
IP_ADDRESS_BYTES + numBytesNodesOfInterest + sizeof(unsigned char);
|
NUM_BYTES_RFC4122_UUID + sizeof(uint16_t) + IP_ADDRESS_BYTES + numBytesNodesOfInterest + sizeof(unsigned char);
|
||||||
|
|
||||||
checkInPacket = new unsigned char[numPacketBytes];
|
checkInPacket = new unsigned char[numPacketBytes];
|
||||||
unsigned char* packetPosition = checkInPacket;
|
unsigned char* packetPosition = checkInPacket;
|
||||||
|
@ -313,7 +313,13 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
|
|
||||||
*(packetPosition++) = _ownerType;
|
*(packetPosition++) = _ownerType;
|
||||||
|
|
||||||
packetPosition += packSocket(checkInPacket + numHeaderBytes + sizeof(NODE_TYPE),
|
if (assignmentUUID) {
|
||||||
|
// if we've got an assignment UUID to send add that here
|
||||||
|
memcpy(packetPosition, assignmentUUID, NUM_BYTES_RFC4122_UUID);
|
||||||
|
packetPosition += NUM_BYTES_RFC4122_UUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
packetPosition += packSocket(checkInPacket + (packetPosition - checkInPacket),
|
||||||
getLocalAddress(),
|
getLocalAddress(),
|
||||||
htons(_nodeSocket.getListeningPort()));
|
htons(_nodeSocket.getListeningPort()));
|
||||||
|
|
||||||
|
|
|
@ -97,7 +97,7 @@ public:
|
||||||
|
|
||||||
void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest);
|
void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest);
|
||||||
|
|
||||||
void sendDomainServerCheckIn();
|
void sendDomainServerCheckIn(const char* assignmentUUID = NULL);
|
||||||
int processDomainServerList(unsigned char *packetData, size_t dataBytes);
|
int processDomainServerList(unsigned char *packetData, size_t dataBytes);
|
||||||
|
|
||||||
void setAssignmentServerSocket(sockaddr* serverSocket) { _assignmentServerSocket = serverSocket; }
|
void setAssignmentServerSocket(sockaddr* serverSocket) { _assignmentServerSocket = serverSocket; }
|
||||||
|
|
|
@ -26,7 +26,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case PACKET_TYPE_VOXEL_STATS:
|
case PACKET_TYPE_VOXEL_STATS:
|
||||||
return 2;
|
return 2;
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue