mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-11 00:25:20 +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
|
||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
||||
NodeList::getInstance()->sendDomainServerCheckIn(this->getUUID().toRfc4122().constData());
|
||||
|
||||
if (Logging::shouldSendStats() && numStatCollections > 0) {
|
||||
// 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
|
||||
if (usecTimestampNow() - usecTimestamp(&lastDomainServerCheckIn) >= DOMAIN_SERVER_CHECK_IN_USECS) {
|
||||
gettimeofday(&lastDomainServerCheckIn, NULL);
|
||||
NodeList::getInstance()->sendDomainServerCheckIn();
|
||||
NodeList::getInstance()->sendDomainServerCheckIn(this->getUUID().toRfc4122().constData());
|
||||
}
|
||||
|
||||
if (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) &&
|
||||
|
|
|
@ -247,77 +247,105 @@ int main(int argc, const char* argv[]) {
|
|||
nodePublicAddress.sin_addr.s_addr = 0;
|
||||
}
|
||||
|
||||
Node* newNode = nodeList->addOrUpdateNode((sockaddr*) &nodePublicAddress,
|
||||
(sockaddr*) &nodeLocalAddress,
|
||||
nodeType,
|
||||
nodeList->getLastNodeID());
|
||||
bool matchedUUID = true;
|
||||
|
||||
// if addOrUpdateNode returns NULL this was a solo node we already have, don't talk back to it
|
||||
if (newNode) {
|
||||
if (newNode->getNodeID() == nodeList->getLastNodeID()) {
|
||||
nodeList->increaseNodeID();
|
||||
if ((nodeType == NODE_TYPE_AVATAR_MIXER || nodeType == NODE_TYPE_AUDIO_MIXER) &&
|
||||
!nodeList->soloNodeOfType(nodeType)) {
|
||||
// if this is an audio-mixer or an avatar-mixer and we don't have one yet
|
||||
// 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;
|
||||
startPointer = currentBufferPos;
|
||||
|
||||
unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + sizeof(NODE_TYPE)
|
||||
+ numBytesSocket + sizeof(unsigned char);
|
||||
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)) {
|
||||
// this is not the node themselves
|
||||
// and this is an node of a type in the passed node types of interest
|
||||
// or the node did not pass us any specific types they are interested in
|
||||
|
||||
if (memchr(SOLO_NODE_TYPES, node->getType(), sizeof(SOLO_NODE_TYPES)) == NULL) {
|
||||
// this is an node of which there can be multiple, just add them to the packet
|
||||
// if addOrUpdateNode returns NULL this was a solo node we already have, don't talk back to it
|
||||
if (newNode) {
|
||||
if (newNode->getNodeID() == nodeList->getLastNodeID()) {
|
||||
nodeList->increaseNodeID();
|
||||
}
|
||||
|
||||
int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_DOMAIN);
|
||||
|
||||
currentBufferPos = broadcastPacket + numHeaderBytes;
|
||||
startPointer = currentBufferPos;
|
||||
|
||||
int numBytesUUID = (nodeType == NODE_TYPE_AUDIO_MIXER || nodeType == NODE_TYPE_AVATAR_MIXER)
|
||||
? NUM_BYTES_RFC4122_UUID
|
||||
: 0;
|
||||
|
||||
unsigned char* nodeTypesOfInterest = packetData + numBytesSenderHeader + numBytesUUID +
|
||||
sizeof(NODE_TYPE) + numBytesSocket + sizeof(unsigned char);
|
||||
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
|
||||
if (nodeType != NODE_TYPE_AGENT || node->getType() != NODE_TYPE_AGENT) {
|
||||
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();
|
||||
soloNode != newestSoloNodes.end();
|
||||
soloNode++) {
|
||||
// this is the newest alive solo node, add them to the packet
|
||||
currentBufferPos = addNodeToBroadcastPacket(currentBufferPos, soloNode->second);
|
||||
}
|
||||
// update last receive to now
|
||||
uint64_t timeNow = usecTimestampNow();
|
||||
newNode->setLastHeardMicrostamp(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);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
|
||||
|
@ -355,8 +383,8 @@ int main(int argc, const char* argv[]) {
|
|||
::assignmentQueue.erase(assignment);
|
||||
delete *assignment;
|
||||
}
|
||||
} else {
|
||||
// remove the assignment from the queue
|
||||
} else if ((*assignment)->getType() == Assignment::VoxelServerType) {
|
||||
// this is a voxel-server assignment, remove the assignment from the queue
|
||||
::assignmentQueue.erase(assignment);
|
||||
}
|
||||
|
||||
|
@ -398,7 +426,8 @@ int main(int argc, const char* argv[]) {
|
|||
::assignmentQueue.erase(assignment);
|
||||
delete *assignment;
|
||||
}
|
||||
} else {
|
||||
} else if ((*assignment)->getType() == Assignment::VoxelServerType) {
|
||||
// this is a voxel server assignment
|
||||
// remove the assignment from the queue
|
||||
::assignmentQueue.erase(assignment);
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
const char IPv4_ADDRESS_DESIGNATOR = 4;
|
||||
const char IPv6_ADDRESS_DESIGNATOR = 6;
|
||||
|
||||
const int NUM_BYTES_RFC4122_UUID = 16;
|
||||
|
||||
Assignment::Assignment(Assignment::Command command, Assignment::Type type, Assignment::Location location) :
|
||||
_command(command),
|
||||
_type(type),
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "NodeList.h"
|
||||
|
||||
const int NUM_BYTES_RFC4122_UUID = 16;
|
||||
|
||||
/// Holds information used for request, creation, and deployment of assignments
|
||||
class Assignment : public QObject {
|
||||
Q_OBJECT
|
||||
|
|
|
@ -268,7 +268,7 @@ void NodeList::setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNo
|
|||
_nodeTypesOfInterest[numNodeTypesOfInterest] = '\0';
|
||||
}
|
||||
|
||||
void NodeList::sendDomainServerCheckIn() {
|
||||
void NodeList::sendDomainServerCheckIn(const char* assignmentUUID) {
|
||||
static bool printedDomainServerIP = false;
|
||||
|
||||
// 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;
|
||||
|
||||
// check in packet has header, node type, port, IP, node types of interest, null termination
|
||||
int numPacketBytes = sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION) + sizeof(NODE_TYPE) + sizeof(uint16_t) +
|
||||
IP_ADDRESS_BYTES + numBytesNodesOfInterest + sizeof(unsigned char);
|
||||
// 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) +
|
||||
NUM_BYTES_RFC4122_UUID + sizeof(uint16_t) + IP_ADDRESS_BYTES + numBytesNodesOfInterest + sizeof(unsigned char);
|
||||
|
||||
checkInPacket = new unsigned char[numPacketBytes];
|
||||
unsigned char* packetPosition = checkInPacket;
|
||||
|
@ -313,7 +313,13 @@ void NodeList::sendDomainServerCheckIn() {
|
|||
|
||||
*(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(),
|
||||
htons(_nodeSocket.getListeningPort()));
|
||||
|
||||
|
|
|
@ -97,7 +97,7 @@ public:
|
|||
|
||||
void setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest);
|
||||
|
||||
void sendDomainServerCheckIn();
|
||||
void sendDomainServerCheckIn(const char* assignmentUUID = NULL);
|
||||
int processDomainServerList(unsigned char *packetData, size_t dataBytes);
|
||||
|
||||
void setAssignmentServerSocket(sockaddr* serverSocket) { _assignmentServerSocket = serverSocket; }
|
||||
|
|
|
@ -26,7 +26,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type) {
|
|||
return 1;
|
||||
|
||||
case PACKET_TYPE_VOXEL_STATS:
|
||||
return 2;
|
||||
return 2;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue