From 141394a6648cced1cf440df394d9fe75dc3262b8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 2 Dec 2013 13:34:29 -0800 Subject: [PATCH] replace UDPSocket with QUDPSocket --- CMakeLists.txt | 1 - animation-server/src/main.cpp | 10 +- assignment-client/src/Agent.cpp | 21 +- assignment-client/src/Agent.h | 2 - assignment-client/src/AssignmentClient.cpp | 6 +- assignment-client/src/AssignmentClient.h | 2 +- assignment-client/src/audio/AudioMixer.cpp | 16 +- assignment-client/src/avatars/AvatarMixer.cpp | 23 +- assignment-client/src/main.cpp | 4 +- .../src/voxels/VoxelScriptingInterface.cpp | 10 +- .../src/voxels/VoxelScriptingInterface.h | 3 + domain-server/src/DomainServer.cpp | 101 ++---- domain-server/src/DomainServer.h | 4 +- interface/src/Application.cpp | 106 +------ interface/src/Application.h | 3 +- interface/src/Audio.cpp | 7 +- interface/src/DataServerClient.cpp | 15 +- interface/src/Environment.cpp | 31 +- interface/src/Environment.h | 6 +- interface/src/PairingHandler.cpp | 25 +- interface/src/VoxelPacketProcessor.cpp | 8 +- interface/src/VoxelPacketProcessor.h | 2 +- interface/src/VoxelSystem.h | 1 - libraries/audio/src/AudioInjectionManager.cpp | 77 ----- libraries/audio/src/AudioInjectionManager.h | 36 --- libraries/audio/src/AudioInjector.cpp | 137 -------- libraries/audio/src/AudioInjector.h | 73 ----- .../audio/src/InjectedAudioRingBuffer.cpp | 2 + libraries/audio/src/InjectedAudioRingBuffer.h | 2 - libraries/shared/src/HifiSockAddr.cpp | 110 +++++++ libraries/shared/src/HifiSockAddr.h | 48 +++ libraries/shared/src/Logging.cpp | 27 +- libraries/shared/src/Logging.h | 6 +- libraries/shared/src/NetworkPacket.cpp | 12 +- libraries/shared/src/NetworkPacket.h | 12 +- libraries/shared/src/Node.cpp | 51 +-- libraries/shared/src/Node.h | 21 +- libraries/shared/src/NodeList.cpp | 154 +++++---- libraries/shared/src/NodeList.h | 45 ++- libraries/shared/src/PacketSender.cpp | 8 +- libraries/shared/src/PacketSender.h | 4 +- .../shared/src/ReceivedPacketProcessor.cpp | 6 +- .../shared/src/ReceivedPacketProcessor.h | 4 +- libraries/shared/src/UDPSocket.cpp | 293 ------------------ libraries/shared/src/UDPSocket.h | 53 ---- .../src/VoxelSendThread.cpp | 22 +- .../voxel-server-library/src/VoxelServer.cpp | 14 +- .../src/VoxelServerPacketProcessor.cpp | 9 +- .../src/VoxelServerPacketProcessor.h | 2 +- libraries/voxels/src/JurisdictionListener.cpp | 6 +- libraries/voxels/src/JurisdictionListener.h | 2 +- libraries/voxels/src/JurisdictionSender.cpp | 6 +- libraries/voxels/src/JurisdictionSender.h | 2 +- .../voxels/src/VoxelEditPacketSender.cpp | 2 +- pairing-server/CMakeLists.txt | 4 + pairing-server/src/main.cpp | 29 +- space-server/CMakeLists.txt | 13 - space-server/example.data.txt | 2 - space-server/src/TreeNode.cpp | 20 -- space-server/src/TreeNode.h | 26 -- space-server/src/main.cpp | 160 ---------- 61 files changed, 521 insertions(+), 1386 deletions(-) delete mode 100644 libraries/audio/src/AudioInjectionManager.cpp delete mode 100644 libraries/audio/src/AudioInjectionManager.h delete mode 100644 libraries/audio/src/AudioInjector.cpp delete mode 100644 libraries/audio/src/AudioInjector.h create mode 100644 libraries/shared/src/HifiSockAddr.cpp create mode 100644 libraries/shared/src/HifiSockAddr.h delete mode 100644 libraries/shared/src/UDPSocket.cpp delete mode 100644 libraries/shared/src/UDPSocket.h delete mode 100644 space-server/CMakeLists.txt delete mode 100644 space-server/example.data.txt delete mode 100644 space-server/src/TreeNode.cpp delete mode 100644 space-server/src/TreeNode.h delete mode 100644 space-server/src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7f43bbc3af..c533f360f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,5 +17,4 @@ add_subdirectory(assignment-client) add_subdirectory(domain-server) add_subdirectory(interface) add_subdirectory(pairing-server) -add_subdirectory(space-server) add_subdirectory(voxel-edit) \ No newline at end of file diff --git a/animation-server/src/main.cpp b/animation-server/src/main.cpp index e9e8a9857d..281c761c00 100644 --- a/animation-server/src/main.cpp +++ b/animation-server/src/main.cpp @@ -841,7 +841,7 @@ int main(int argc, const char * argv[]) pthread_t animateVoxelThread; pthread_create(&animateVoxelThread, NULL, animateVoxels, NULL); - sockaddr nodePublicAddress; + HifiSockAddr nodeSockAddr; unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; ssize_t receivedBytes; @@ -858,15 +858,17 @@ int main(int argc, const char * argv[]) } // Nodes sending messages to us... - if (nodeList->getNodeSocket()->receive(&nodePublicAddress, packetData, &receivedBytes) && + if ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE, + nodeSockAddr.getAddressPointer(), + nodeSockAddr.getPortPointer())) && packetVersionMatch(packetData)) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { if (::jurisdictionListener) { - ::jurisdictionListener->queueReceivedPacket(nodePublicAddress, packetData, receivedBytes); + ::jurisdictionListener->queueReceivedPacket(nodeSockAddr, packetData, receivedBytes); } } - NodeList::getInstance()->processNodeData(&nodePublicAddress, packetData, receivedBytes); + NodeList::getInstance()->processNodeData(nodeSockAddr, packetData, receivedBytes); } } diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 2492138857..bedaab87c4 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -51,8 +51,6 @@ void Agent::run() { const char AGENT_NODE_TYPES_OF_INTEREST[1] = { NODE_TYPE_VOXEL_SERVER }; nodeList->setNodeTypesOfInterest(AGENT_NODE_TYPES_OF_INTEREST, sizeof(AGENT_NODE_TYPES_OF_INTEREST)); - - nodeList->getNodeSocket()->setBlocking(false); // figure out the URL for the script for this agent assignment QString scriptURLString("http://%1:8080/assignment/%2"); @@ -90,11 +88,6 @@ void Agent::run() { // let the VoxelPacketSender know how frequently we plan to call it voxelScripter.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_CALLBACK_USECS); - // hook in a constructor for audio injectorss - AudioInjector scriptedAudioInjector(BUFFER_LENGTH_SAMPLES_PER_CHANNEL); - QScriptValue audioInjectorValue = engine.newQObject(&scriptedAudioInjector); - engine.globalObject().setProperty("AudioInjector", audioInjectorValue); - qDebug() << "Downloaded script:" << scriptContents << "\n"; QScriptValue result = engine.evaluate(scriptContents); qDebug() << "Evaluated script.\n"; @@ -109,7 +102,8 @@ void Agent::run() { timeval lastDomainServerCheckIn = {}; - sockaddr_in senderAddress; + + HifiSockAddr senderSockAddr; unsigned char receivedData[MAX_PACKET_SIZE]; ssize_t receivedBytes; @@ -153,14 +147,17 @@ void Agent::run() { qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; } - while (NodeList::getInstance()->getNodeSocket()->receive((sockaddr*) &senderAddress, receivedData, &receivedBytes) - && packetVersionMatch(receivedData)) { + while ((receivedBytes = NodeList::getInstance()->getNodeSocket().readDatagram((char*) receivedBytes, + MAX_PACKET_SIZE, + senderSockAddr.getAddressPointer(), + senderSockAddr.getPortPointer())) + && packetVersionMatch(receivedData)) { if (receivedData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { - voxelScripter.getJurisdictionListener()->queueReceivedPacket((sockaddr&) senderAddress, + voxelScripter.getJurisdictionListener()->queueReceivedPacket(senderSockAddr, receivedData, receivedBytes); } else { - NodeList::getInstance()->processNodeData((sockaddr*) &senderAddress, receivedData, receivedBytes); + NodeList::getInstance()->processNodeData(senderSockAddr, receivedData, receivedBytes); } } } diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 552910e04d..2ad7eba1e6 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -15,7 +15,6 @@ #include #include -#include #include class Agent : public Assignment { @@ -33,7 +32,6 @@ private: static QScriptValue AudioInjectorConstructor(QScriptContext *context, QScriptEngine *engine); bool volatile _shouldStop; - std::vector _audioInjectors; }; #endif /* defined(__hifi__Agent__) */ diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index 92d394f41a..f694795466 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -23,7 +23,7 @@ const long long ASSIGNMENT_REQUEST_INTERVAL_MSECS = 1 * 1000; AssignmentClient::AssignmentClient(int &argc, char **argv, Assignment::Type requestAssignmentType, - const sockaddr_in& customAssignmentServerSocket, + const HifiSockAddr& customAssignmentServerSocket, const char* requestAssignmentPool) : QCoreApplication(argc, argv), _requestAssignment(Assignment::RequestCommand, requestAssignmentType, requestAssignmentPool) @@ -35,8 +35,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv, NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED); // set the custom assignment socket if we have it - if (customAssignmentServerSocket.sin_addr.s_addr != 0) { - nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentServerSocket); + if (!customAssignmentServerSocket.isNull()) { + nodeList->setAssignmentServerSocket(customAssignmentServerSocket); } // call a timer function every ASSIGNMENT_REQUEST_INTERVAL_MSECS to ask for assignment, if required diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 97ccc6e805..e7072e816a 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -16,7 +16,7 @@ class AssignmentClient : public QCoreApplication { public: AssignmentClient(int &argc, char **argv, Assignment::Type requestAssignmentType = Assignment::AllTypes, - const sockaddr_in& customAssignmentServerSocket = sockaddr_in(), + const HifiSockAddr& customAssignmentServerSocket = HifiSockAddr(), const char* requestAssignmentPool = NULL); private slots: void sendAssignmentRequest(); diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index c8897fe2b1..0d11a63344 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -235,10 +235,7 @@ void AudioMixer::run() { unsigned char packetData[MAX_PACKET_SIZE] = {}; - sockaddr* nodeAddress = new sockaddr; - - // make sure our node socket is non-blocking - nodeList->getNodeSocket()->setBlocking(false); + HifiSockAddr nodeSockAddr; int nextFrame = 0; timeval startTime; @@ -301,7 +298,9 @@ void AudioMixer::run() { prepareMixForListeningNode(&(*node)); memcpy(clientPacket + numBytesPacketHeader, _clientSamples, sizeof(_clientSamples)); - nodeList->getNodeSocket()->send(node->getActiveSocket(), clientPacket, sizeof(clientPacket)); + nodeList->getNodeSocket().writeDatagram((char*) clientPacket, sizeof(clientPacket), + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); } } @@ -313,7 +312,8 @@ void AudioMixer::run() { } // pull any new audio data from nodes off of the network stack - while (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) && + while ((receivedBytes = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE, + nodeSockAddr.getAddressPointer(), nodeSockAddr.getPortPointer())) && packetVersionMatch(packetData)) { if (packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_NO_ECHO || packetData[0] == PACKET_TYPE_MICROPHONE_AUDIO_WITH_ECHO @@ -325,7 +325,7 @@ void AudioMixer::run() { Node* matchingNode = nodeList->nodeWithUUID(nodeUUID); if (matchingNode) { - nodeList->updateNodeWithData(matchingNode, nodeAddress, packetData, receivedBytes); + nodeList->updateNodeWithData(matchingNode, nodeSockAddr, packetData, receivedBytes); if (!matchingNode->getActiveSocket()) { // we don't have an active socket for this node, but they're talking to us @@ -335,7 +335,7 @@ void AudioMixer::run() { } } else { // let processNodeData handle it. - nodeList->processNodeData(nodeAddress, packetData, receivedBytes); + nodeList->processNodeData(nodeSockAddr, packetData, receivedBytes); } } diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index b13c92e0ed..787771a269 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -46,7 +46,7 @@ void attachAvatarDataToNode(Node* newNode) { // 3) if we need to rate limit the amount of data we send, we can use a distance weighted "semi-random" function to // determine which avatars are included in the packet stream // 4) we should optimize the avatar data format to be more compact (100 bytes is pretty wasteful). -void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, sockaddr* receiverAddress) { +void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, const HifiSockAddr& receiverSockAddr) { static unsigned char broadcastPacketBuffer[MAX_PACKET_SIZE]; static unsigned char avatarDataBuffer[MAX_PACKET_SIZE]; unsigned char* broadcastPacket = (unsigned char*)&broadcastPacketBuffer[0]; @@ -68,7 +68,8 @@ void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, sockaddr } else { packetsSent++; //printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength); - nodeList->getNodeSocket()->send(receiverAddress, broadcastPacket, currentBufferPosition - broadcastPacket); + nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket, + receiverSockAddr.getAddress(), receiverSockAddr.getPort()); // reset the packet currentBufferPosition = broadcastPacket + numHeaderBytes; @@ -83,7 +84,8 @@ void broadcastAvatarData(NodeList* nodeList, const QUuid& receiverUUID, sockaddr } packetsSent++; //printf("packetsSent=%d packetLength=%d\n", packetsSent, packetLength); - nodeList->getNodeSocket()->send(receiverAddress, broadcastPacket, currentBufferPosition - broadcastPacket); + nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, currentBufferPosition - broadcastPacket, + receiverSockAddr.getAddress(), receiverSockAddr.getPort()); } AvatarMixer::AvatarMixer(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes) { @@ -103,7 +105,7 @@ void AvatarMixer::run() { nodeList->startSilentNodeRemovalThread(); - sockaddr nodeAddress = {}; + HifiSockAddr nodeSockAddr; ssize_t receivedBytes = 0; unsigned char packetData[MAX_PACKET_SIZE]; @@ -127,7 +129,8 @@ void AvatarMixer::run() { nodeList->possiblyPingInactiveNodes(); - if (nodeList->getNodeSocket()->receive(&nodeAddress, packetData, &receivedBytes) && + if (nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE, + nodeSockAddr.getAddressPointer(), nodeSockAddr.getPortPointer()) && packetVersionMatch(packetData)) { switch (packetData[0]) { case PACKET_TYPE_HEAD_DATA: @@ -139,12 +142,12 @@ void AvatarMixer::run() { if (avatarNode) { // parse positional data from an node - nodeList->updateNodeWithData(avatarNode, &nodeAddress, packetData, receivedBytes); + nodeList->updateNodeWithData(avatarNode, nodeSockAddr, packetData, receivedBytes); } else { break; } case PACKET_TYPE_INJECT_AUDIO: - broadcastAvatarData(nodeList, nodeUUID, &nodeAddress); + broadcastAvatarData(nodeList, nodeUUID, nodeSockAddr); break; case PACKET_TYPE_KILL_NODE: case PACKET_TYPE_AVATAR_URLS: @@ -154,14 +157,16 @@ void AvatarMixer::run() { // let everyone else know about the update for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { if (node->getActiveSocket() && node->getUUID() != nodeUUID) { - nodeList->getNodeSocket()->send(node->getActiveSocket(), packetData, receivedBytes); + nodeList->getNodeSocket().writeDatagram((char*) packetData, receivedBytes, + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); } } // let node kills fall through to default behavior default: // hand this off to the NodeList - nodeList->processNodeData(&nodeAddress, packetData, receivedBytes); + nodeList->processNodeData(nodeSockAddr, packetData, receivedBytes); break; } } diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 5f98f4f856..cef77610c4 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -28,7 +28,7 @@ const char PARENT_TARGET_NAME[] = "assignment-client-monitor"; pid_t* childForks = NULL; -sockaddr_in customAssignmentSocket = {}; +HifiSockAddr customAssignmentSocket; int numForks = 0; Assignment::Type overiddenAssignmentType = Assignment::AllTypes; const char* assignmentPool = NULL; @@ -130,7 +130,7 @@ int main(int argc, char* argv[]) { customAssignmentServerHostname = LOCAL_ASSIGNMENT_SERVER_HOSTNAME; } - ::customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServerHostname, assignmentServerPort); + ::customAssignmentSocket = HifiSockAddr(customAssignmentServerHostname, assignmentServerPort); } const char ASSIGNMENT_TYPE_OVVERIDE_OPTION[] = "-t"; diff --git a/assignment-client/src/voxels/VoxelScriptingInterface.cpp b/assignment-client/src/voxels/VoxelScriptingInterface.cpp index 1801c621c4..b967c23187 100644 --- a/assignment-client/src/voxels/VoxelScriptingInterface.cpp +++ b/assignment-client/src/voxels/VoxelScriptingInterface.cpp @@ -27,11 +27,13 @@ void VoxelScriptingInterface::queueVoxelAdd(float x, float y, float z, float sca void VoxelScriptingInterface::queueDestructiveVoxelAdd(float x, float y, float z, float scale, uchar red, uchar green, uchar blue) { - // setup a VoxelDetail struct with the data - VoxelDetail addVoxelDetail = {x, y, z, scale, red, green, blue}; +// // setup a VoxelDetail struct with the data +// VoxelDetail addVoxelDetail = {x, y, z, scale, red, green, blue}; +// +// // queue the destructive add +// queueVoxelAdd(PACKET_TYPE_SET_VOXEL_DESTRUCTIVE, addVoxelDetail); - // queue the destructive add - queueVoxelAdd(PACKET_TYPE_SET_VOXEL_DESTRUCTIVE, addVoxelDetail); + _voxelTree.createVoxel(x, y, z, scale, red, green, blue); } void VoxelScriptingInterface::queueVoxelDelete(float x, float y, float z, float scale) { diff --git a/assignment-client/src/voxels/VoxelScriptingInterface.h b/assignment-client/src/voxels/VoxelScriptingInterface.h index 473cf3035c..fc1426ebbc 100644 --- a/assignment-client/src/voxels/VoxelScriptingInterface.h +++ b/assignment-client/src/voxels/VoxelScriptingInterface.h @@ -13,6 +13,7 @@ #include #include +#include /// handles scripting of voxel commands from JS passed to assigned clients class VoxelScriptingInterface : public QObject { @@ -22,6 +23,7 @@ public: VoxelEditPacketSender* getVoxelPacketSender() { return &_voxelPacketSender; } JurisdictionListener* getJurisdictionListener() { return &_jurisdictionListener; } + VoxelTree* getVoxelTree() { return &_voxelTree; } public slots: /// queues the creation of a voxel which will be sent by calling process on the PacketSender /// \param x the x-coordinate of the voxel (in VS space) @@ -105,6 +107,7 @@ private: /// attached VoxelEditPacketSender that handles queuing and sending of packets to VS VoxelEditPacketSender _voxelPacketSender; JurisdictionListener _jurisdictionListener; + VoxelTree _voxelTree; void queueVoxelAdd(PACKET_TYPE addPacketType, VoxelDetail& addVoxelDetails); }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 792942f846..9aba991f16 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -30,14 +30,11 @@ void DomainServer::setDomainServerInstance(DomainServer* domainServer) { domainServerInstance = domainServer; } -QJsonObject jsonForSocket(sockaddr* socket) { +QJsonObject jsonForSocket(const HifiSockAddr& socket) { QJsonObject socketJSON; - if (socket->sa_family == AF_INET) { - sockaddr_in* socketIPv4 = (sockaddr_in*) socket; - socketJSON["ip"] = QString(inet_ntoa(socketIPv4->sin_addr)); - socketJSON["port"] = (int) ntohs(socketIPv4->sin_port); - } + socketJSON["ip"] = socket.getAddress().toString(); + socketJSON["port"] = ntohs(socket.getPort()); return socketJSON; } @@ -288,8 +285,8 @@ unsigned char* DomainServer::addNodeToBroadcastPacket(unsigned char* currentPosi memcpy(currentPosition, rfcUUID.constData(), rfcUUID.size()); currentPosition += rfcUUID.size(); - currentPosition += packSocket(currentPosition, nodeToAdd->getPublicSocket()); - currentPosition += packSocket(currentPosition, nodeToAdd->getLocalSocket()); + currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getPublicSocket()); + currentPosition += HifiSockAddr::packSockAddr(currentPosition, nodeToAdd->getLocalSocket()); // return the new unsigned char * for broadcast packet return currentPosition; @@ -506,15 +503,15 @@ void DomainServer::removeAssignmentFromQueue(Assignment* removableAssignment) { _assignmentQueueMutex.unlock(); } -bool DomainServer::checkInWithUUIDMatchesExistingNode(sockaddr* nodePublicSocket, - sockaddr* nodeLocalSocket, +bool DomainServer::checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePublicSocket, + const HifiSockAddr& nodeLocalSocket, const QUuid& checkInUUID) { NodeList* nodeList = NodeList::getInstance(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { if (node->getLinkedData() - && socketMatch(node->getPublicSocket(), nodePublicSocket) - && socketMatch(node->getLocalSocket(), nodeLocalSocket) + && nodePublicSocket == node->getPublicSocket() + && nodeLocalSocket == node->getLocalSocket() && node->getUUID() == checkInUUID) { // this is a matching existing node if the public socket, local socket, and UUID match return true; @@ -588,9 +585,11 @@ int DomainServer::run() { unsigned char* currentBufferPos; unsigned char* startPointer; - sockaddr_in senderAddress, nodePublicAddress, nodeLocalAddress; - nodePublicAddress.sin_family = AF_INET; - nodeLocalAddress.sin_family = AF_INET; + QHostAddress senderAddress; + quint16 senderPort; + HifiSockAddr nodePublicAddress, nodeLocalAddress; + + nodeList->startSilentNodeRemovalThread(); @@ -614,7 +613,7 @@ int DomainServer::run() { gettimeofday(&startTime, NULL); while (true) { - while (nodeList->getNodeSocket()->receive((sockaddr *)&senderAddress, packetData, &receivedBytes) && + while (nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE, &senderAddress, &senderPort) && packetVersionMatch(packetData)) { if (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) { // this is an RFD or domain list request packet, and there is a version match @@ -627,23 +626,23 @@ int DomainServer::run() { QUuid nodeUUID = QUuid::fromRfc4122(QByteArray(((char*) packetData + packetIndex), NUM_BYTES_RFC4122_UUID)); packetIndex += NUM_BYTES_RFC4122_UUID; - int numBytesPrivateSocket = unpackSocket(packetData + packetIndex, (sockaddr*) &nodePublicAddress); + int numBytesPrivateSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodePublicAddress); packetIndex += numBytesPrivateSocket; - if (nodePublicAddress.sin_addr.s_addr == 0) { + if (nodePublicAddress.getAddress().isNull() == 0) { // this node wants to use us its STUN server // so set the node public address to whatever we perceive the public address to be - nodePublicAddress = senderAddress; + nodePublicAddress.setAddress(senderAddress); // if the sender is on our box then leave its public address to 0 so that // other users attempt to reach it on the same address they have for the domain-server - if (senderAddress.sin_addr.s_addr == htonl(INADDR_LOOPBACK)) { - nodePublicAddress.sin_addr.s_addr = 0; + if (senderAddress.isLoopback()) { + nodePublicAddress.setAddress(QHostAddress()); } } - int numBytesPublicSocket = unpackSocket(packetData + packetIndex, (sockaddr*) &nodeLocalAddress); + int numBytesPublicSocket = HifiSockAddr::unpackSockAddr(packetData + packetIndex, nodeLocalAddress); packetIndex += numBytesPublicSocket; const char STATICALLY_ASSIGNED_NODES[3] = { @@ -656,14 +655,14 @@ int DomainServer::run() { if (memchr(STATICALLY_ASSIGNED_NODES, nodeType, sizeof(STATICALLY_ASSIGNED_NODES)) == NULL || ((matchingStaticAssignment = matchingStaticAssignmentForCheckIn(nodeUUID, nodeType)) - || checkInWithUUIDMatchesExistingNode((sockaddr*) &nodePublicAddress, - (sockaddr*) &nodeLocalAddress, + || checkInWithUUIDMatchesExistingNode(nodePublicAddress, + nodeLocalAddress, nodeUUID))) { Node* checkInNode = nodeList->addOrUpdateNode(nodeUUID, nodeType, - (sockaddr*) &nodePublicAddress, - (sockaddr*) &nodeLocalAddress); + nodePublicAddress, + nodeLocalAddress); if (matchingStaticAssignment) { // this was a newly added node with a matching static assignment @@ -691,7 +690,7 @@ int DomainServer::run() { 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) && + if (node->getUUID() != nodeUUID && memchr(nodeTypesOfInterest, node->getType(), numInterestTypes)) { // don't send avatar nodes to other avatars, that will come from avatar mixer @@ -708,9 +707,9 @@ int DomainServer::run() { checkInNode->setLastHeardMicrostamp(timeNow); // send the constructed list back to this node - nodeList->getNodeSocket()->send((sockaddr*)&senderAddress, - broadcastPacket, - (currentBufferPos - startPointer) + numHeaderBytes); + nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, + (currentBufferPos - startPointer) + numHeaderBytes, + senderAddress, senderPort); } } else if (packetData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) { @@ -732,9 +731,8 @@ int DomainServer::run() { int numHeaderBytes = populateTypeAndVersion(broadcastPacket, PACKET_TYPE_CREATE_ASSIGNMENT); int numAssignmentBytes = assignmentToDeploy->packToBuffer(broadcastPacket + numHeaderBytes); - nodeList->getNodeSocket()->send((sockaddr*) &senderAddress, - broadcastPacket, - numHeaderBytes + numAssignmentBytes); + nodeList->getNodeSocket().writeDatagram((char*) broadcastPacket, numHeaderBytes + numAssignmentBytes, + senderAddress, senderPort); if (assignmentToDeploy->getNumberOfInstances() == 0) { // there are no more instances of this script to send out, delete it @@ -743,43 +741,6 @@ int DomainServer::run() { } } - } else if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT) { - // this is a create assignment likely recieved from a server needed more clients to help with load - - // unpack it - Assignment* createAssignment = new Assignment(packetData, receivedBytes); - - qDebug() << "Received a create assignment -" << *createAssignment << "\n"; - - // make sure we have a matching node with the UUID packed with the assignment - // 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->getLinkedData() - && socketMatch((sockaddr*) &senderAddress, node->getPublicSocket()) - && ((Assignment*) node->getLinkedData())->getUUID() == createAssignment->getUUID()) { - - // give the create assignment a new UUID - createAssignment->resetUUID(); - - // add the assignment at the back of the queue - _assignmentQueueMutex.lock(); - _assignmentQueue.push_back(createAssignment); - _assignmentQueueMutex.unlock(); - - // find the first available spot in the static assignments and put this assignment there - for (int i = 0; i < MAX_STATIC_ASSIGNMENT_FILE_ASSIGNMENTS; i++) { - if (_staticAssignments[i].getUUID().isNull()) { - _staticAssignments[i] = *createAssignment; - - // we've stuck the assignment in, break out - break; - } - } - - // we found the matching node that asked for create assignment, break out - break; - } - } } } diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 45730847ac..755f73485c 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -45,7 +45,9 @@ private: Assignment* matchingStaticAssignmentForCheckIn(const QUuid& checkInUUID, NODE_TYPE nodeType); Assignment* deployableAssignmentForRequest(Assignment& requestAssignment); void removeAssignmentFromQueue(Assignment* removableAssignment); - bool checkInWithUUIDMatchesExistingNode(sockaddr* nodePublicSocket, sockaddr* nodeLocalSocket, const QUuid& checkInUUI); + bool checkInWithUUIDMatchesExistingNode(const HifiSockAddr& nodePublicSocket, + const HifiSockAddr& nodeLocalSocket, + const QUuid& checkInUUI); void possiblyAddStaticAssignmentsBackToQueueAfterRestart(timeval* startTime); void addReleasedAssignmentBackToQueue(Assignment* releasedAssignment); diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 58629df41e..84f72242c4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -19,6 +19,7 @@ #include #endif +#include #include #include @@ -47,8 +48,6 @@ #include #include -#include -#include #include #include #include @@ -172,9 +171,6 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : // network receive thread and voxel parsing thread are both controlled by the --nonblocking command line _enableProcessVoxelsThread = _enableNetworkThread = !cmdOptionExists(argc, constArgv, "--nonblocking"); - if (!_enableNetworkThread) { - NodeList::getInstance()->getNodeSocket()->setBlocking(false); - } // setup QSettings #ifdef Q_OS_MAC @@ -1463,8 +1459,9 @@ void Application::checkBandwidthMeterClick() { // ... to be called upon button release if (Menu::getInstance()->isOptionChecked(MenuOption::Bandwidth) && - glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY))) <= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH && - _bandwidthMeter.isWithinArea(_mouseX, _mouseY, _glWidget->width(), _glWidget->height())) { + glm::compMax(glm::abs(glm::ivec2(_mouseX - _mouseDragStartedX, _mouseY - _mouseDragStartedY))) + <= BANDWIDTH_METER_CLICK_MAX_DRAG_LENGTH + && _bandwidthMeter.isWithinArea(_mouseX, _mouseY, _glWidget->width(), _glWidget->height())) { // The bandwidth meter is visible, the click didn't get dragged too far and // we actually hit the bandwidth meter @@ -2661,7 +2658,6 @@ void Application::queryVoxels() { qDebug("perServerPPS: %d perUnknownServer: %d\n", perServerPPS, perUnknownServer); } - UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { // only send to the NodeTypes that are NODE_TYPE_VOXEL_SERVER if (node->getActiveSocket() != NULL && node->getType() == NODE_TYPE_VOXEL_SERVER) { @@ -2747,7 +2743,8 @@ void Application::queryVoxels() { int packetLength = endOfVoxelQueryPacket - voxelQueryPacket; - nodeSocket->send(node->getActiveSocket(), voxelQueryPacket, packetLength); + nodeList->getNodeSocket().writeDatagram((char*) voxelQueryPacket, packetLength, + node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort()); // Feed number of bytes to corresponding channel of the bandwidth meter _bandwidthMeter.outputStream(BandwidthMeter::VOXELS).updateValue(packetLength); @@ -4034,62 +4031,6 @@ void Application::renderViewFrustum(ViewFrustum& viewFrustum) { } } -void Application::injectVoxelAddedSoundEffect() { - AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(11025); - - if (voxelInjector) { - voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z)); - //voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw()); - voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value - - /* for (int i = 0; i - < 22050; i++) { - if (i % 4 == 0) { - voxelInjector->addSample(4000); - } else if (i % 4 == 1) { - voxelInjector->addSample(0); - } else if (i % 4 == 2) { - voxelInjector->addSample(-4000); - } else { - voxelInjector->addSample(0); - } - */ - - const float BIG_VOXEL_MIN_SIZE = .01f; - - for (int i = 0; i < 11025; i++) { - - /* - A440 square wave - if (sin(i * 2 * PIE / 50)>=0) { - voxelInjector->addSample(4000); - } else { - voxelInjector->addSample(-4000); - } - */ - - if (_mouseVoxel.s > BIG_VOXEL_MIN_SIZE) { - voxelInjector->addSample(20000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 200)))); - } else { - voxelInjector->addSample(16000 * sin(i / (1.5 * log (_mouseVoxel.s / .0001) * ((i + 11025) / 5512.5)))); //808 - } - } - - //voxelInjector->addSample(32500 * sin(i/(2 * 1 * ((i+5000)/5512.5)))); //80 - //voxelInjector->addSample(20000 * sin(i/(6 * (_mouseVoxel.s/.001) *((i+5512.5)/5512.5)))); //808 - //voxelInjector->addSample(20000 * sin(i/(6 * ((i+5512.5)/5512.5)))); //808 - //voxelInjector->addSample(4000 * sin(i * 2 * PIE /50)); //A440 sine wave - //voxelInjector->addSample(4000 * sin(i * 2 * PIE /50) * sin (i/500)); //A440 sine wave with amplitude modulation - - //FM library - //voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(500*sin((i+1)/200)))); //FM 1 dubstep - //voxelInjector->addSample(20000 * sin((i * 2 * PIE) /(300*sin((i+1)/5.0)))); //FM 2 flange sweep - //voxelInjector->addSample(10000 * sin((i * 2 * PIE) /(500*sin((i+1)/500.0)))); //FM 3 resonant pulse - - AudioInjectionManager::threadInjector(voxelInjector); - } -} - bool Application::maybeEditVoxelUnderCursor() { if (Menu::getInstance()->isOptionChecked(MenuOption::VoxelAddMode) || Menu::getInstance()->isOptionChecked(MenuOption::VoxelColorMode)) { @@ -4114,9 +4055,6 @@ bool Application::maybeEditVoxelUnderCursor() { fade.voxelDetails.s = _mouseVoxel.s + slightlyBigger + slightlyBigger; _voxelFades.push_back(fade); - // inject a sound effect - injectVoxelAddedSoundEffect(); - // remember the position for drag detection _justEditedVoxel = true; @@ -4149,21 +4087,6 @@ void Application::deleteVoxelUnderCursor() { // delete it locally to see the effect immediately (and in case no voxel server is present) _voxels.deleteVoxelAt(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z, _mouseVoxel.s); - AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(5000); - - if (voxelInjector) { - voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z)); - //voxelInjector->setBearing(0); //straight down the z axis - voxelInjector->setVolume (255); //255 is max, and also default value - - - for (int i = 0; i < 5000; i++) { - voxelInjector->addSample(10000 * sin((i * 2 * PIE) / (500 * sin((i + 1) / 500.0)))); //FM 3 resonant pulse - //voxelInjector->addSample(20000 * sin((i) /((4 / _mouseVoxel.s) * sin((i)/(20 * _mouseVoxel.s / .001))))); //FM 2 comb filter - } - - AudioInjectionManager::threadInjector(voxelInjector); - } } // remember the position for drag detection _justEditedVoxel = true; @@ -4321,10 +4244,10 @@ void Application::nodeKilled(Node* node) { } } -int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress) { +int Application::parseVoxelStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderSockAddr) { // But, also identify the sender, and keep track of the contained jurisdiction root for this server - Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress); + Node* voxelServer = NodeList::getInstance()->nodeWithAddress(senderSockAddr); // parse the incoming stats datas stick it in a temporary object for now, while we // determine which server it belongs to @@ -4377,12 +4300,15 @@ void* Application::networkReceive(void* args) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::networkReceive()"); - sockaddr senderAddress; + HifiSockAddr senderSockAddr; ssize_t bytesReceived; Application* app = Application::getInstance(); while (!app->_stopNetworkReceiveThread) { - if (NodeList::getInstance()->getNodeSocket()->receive(&senderAddress, app->_incomingPacket, &bytesReceived)) { + if ((bytesReceived = NodeList::getInstance()->getNodeSocket().readDatagram((char*) app->_incomingPacket, + MAX_PACKET_SIZE, + senderSockAddr.getAddressPointer(), + senderSockAddr.getPortPointer()))) { app->_packetCount++; app->_bytesCount += bytesReceived; @@ -4408,11 +4334,11 @@ void* Application::networkReceive(void* args) { "Application::networkReceive()... _voxelProcessor.queueReceivedPacket()"); // add this packet to our list of voxel packets and process them on the voxel processing - app->_voxelProcessor.queueReceivedPacket(senderAddress, app->_incomingPacket, bytesReceived); + app->_voxelProcessor.queueReceivedPacket(senderSockAddr, app->_incomingPacket, bytesReceived); break; } case PACKET_TYPE_BULK_AVATAR_DATA: - NodeList::getInstance()->processBulkNodeData(&senderAddress, + NodeList::getInstance()->processBulkNodeData(senderSockAddr, app->_incomingPacket, bytesReceived); getInstance()->_bandwidthMeter.inputStream(BandwidthMeter::AVATARS).updateValue(bytesReceived); @@ -4430,7 +4356,7 @@ void* Application::networkReceive(void* args) { DataServerClient::processMessageFromDataServer(app->_incomingPacket, bytesReceived); break; default: - NodeList::getInstance()->processNodeData(&senderAddress, app->_incomingPacket, bytesReceived); + NodeList::getInstance()->processNodeData(senderSockAddr, app->_incomingPacket, bytesReceived); break; } } diff --git a/interface/src/Application.h b/interface/src/Application.h index 4695a1bf80..05d981ebd8 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -284,7 +284,6 @@ private: bool maybeEditVoxelUnderCursor(); void deleteVoxelUnderCursor(); void eyedropperVoxelUnderCursor(); - void injectVoxelAddedSoundEffect(); void setMenuShortcutsEnabled(bool enabled); @@ -464,7 +463,7 @@ private: PieMenu _pieMenu; - int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, sockaddr senderAddress); + int parseVoxelStats(unsigned char* messageData, ssize_t messageLength, const HifiSockAddr& senderAddress); NodeToJurisdictionMap _voxelServerJurisdictions; NodeToVoxelSceneStats _voxelServerSceneStats; diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index d3b23f273a..21cbfa21a5 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -19,7 +19,6 @@ #include #include #include -#include #include #include "Application.h" @@ -143,9 +142,9 @@ inline void Audio::performIO(int16_t* inputLeft, int16_t* outputLeft, int16_t* o // copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet memcpy(currentPacketPtr, inputLeft, BUFFER_LENGTH_BYTES_PER_CHANNEL); - nodeList->getNodeSocket()->send(audioMixer->getActiveSocket(), - dataPacket, - BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); + nodeList->getNodeSocket().writeDatagram((char*) dataPacket, BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes, + audioMixer->getActiveSocket()->getAddress(), + audioMixer->getActiveSocket()->getPort()); interface->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO).updateValue(BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); diff --git a/interface/src/DataServerClient.cpp b/interface/src/DataServerClient.cpp index 80be4189b1..547b2dcd3f 100644 --- a/interface/src/DataServerClient.cpp +++ b/interface/src/DataServerClient.cpp @@ -7,10 +7,10 @@ // #include +#include #include #include -#include #include #include "Application.h" @@ -24,7 +24,7 @@ const char MULTI_KEY_VALUE_SEPARATOR = '|'; const char DATA_SERVER_HOSTNAME[] = "data.highfidelity.io"; const unsigned short DATA_SERVER_PORT = 3282; -const sockaddr_in DATA_SERVER_SOCKET = socketForHostnameAndHostOrderPort(DATA_SERVER_HOSTNAME, DATA_SERVER_PORT); +const HifiSockAddr DATA_SERVER_SOCKET = HifiSockAddr(DATA_SERVER_HOSTNAME, DATA_SERVER_PORT); void DataServerClient::putValueForKey(const QString& key, const char* value) { QString clientString = Application::getInstance()->getProfile()->getUserString(); @@ -57,7 +57,8 @@ void DataServerClient::putValueForKey(const QString& key, const char* value) { // _unmatchedPackets.insert(std::pair(putPacket, numPacketBytes)); // send this put request to the data server - NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, putPacket, numPacketBytes); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) putPacket, numPacketBytes, + DATA_SERVER_SOCKET.getAddress(), DATA_SERVER_SOCKET.getPort()); } } @@ -96,7 +97,8 @@ void DataServerClient::getValuesForKeysAndUserString(const QStringList& keys, co // _unmatchedPackets.insert(std::pair(getPacket, numPacketBytes)); // send the get to the data server - NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, getPacket, numPacketBytes); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) getPacket, numPacketBytes, + DATA_SERVER_SOCKET.getAddress(), DATA_SERVER_SOCKET.getPort()); } } @@ -236,8 +238,7 @@ void DataServerClient::resendUnmatchedPackets() { mapIterator != _unmatchedPackets.end(); ++mapIterator) { // send the unmatched packet to the data server - NodeList::getInstance()->getNodeSocket()->send((sockaddr*) &DATA_SERVER_SOCKET, - mapIterator->first, - mapIterator->second); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) mapIterator->first, mapIterator->second, + DATA_SERVER_SOCKET.getAddress(), DATA_SERVER_SOCKET.getPort()); } } diff --git a/interface/src/Environment.cpp b/interface/src/Environment.cpp index 4f4e694713..c82356ba65 100644 --- a/interface/src/Environment.cpp +++ b/interface/src/Environment.cpp @@ -18,24 +18,13 @@ #include "renderer/ProgramObject.h" #include "world.h" -uint qHash(const sockaddr& address) { - const sockaddr_in* inetAddress = reinterpret_cast(&address); - if (inetAddress->sin_family != AF_INET) { +uint qHash(const HifiSockAddr& sockAddr) { + if (sockAddr.getAddress().isNull()) { return 0; // shouldn't happen, but if it does, zero is a perfectly valid hash } - return inetAddress->sin_port + qHash(QByteArray::fromRawData( - reinterpret_cast(&inetAddress->sin_addr), sizeof(in_addr))); -} - -bool operator== (const sockaddr& addr1, const sockaddr& addr2) { - return socketMatch(&addr1, &addr2); -} - -static sockaddr getZeroAddress() { - sockaddr addr; - memset(&addr, 0, sizeof(sockaddr)); - addr.sa_family = AF_INET; - return addr; + quint32 address = sockAddr.getAddress().toIPv4Address(); + return sockAddr.getPort() + qHash(QByteArray::fromRawData((char*) &address, + sizeof(address))); } Environment::Environment() @@ -60,14 +49,14 @@ void Environment::init() { _skyFromSpaceProgram = createSkyProgram("Space", _skyFromSpaceUniformLocations); // start off with a default-constructed environment data - _data[getZeroAddress()][0]; + _data[HifiSockAddr()][0]; _initialized = true; } void Environment::resetToDefault() { _data.clear(); - _data[getZeroAddress()][0]; + _data[HifiSockAddr()][0]; } void Environment::renderAtmospheres(Camera& camera) { @@ -159,7 +148,7 @@ bool Environment::findCapsulePenetration(const glm::vec3& start, const glm::vec3 return found; } -int Environment::parseData(sockaddr *senderAddress, unsigned char* sourceBuffer, int numBytes) { +int Environment::parseData(const HifiSockAddr& senderAddress, unsigned char* sourceBuffer, int numBytes) { // push past the packet header unsigned char* start = sourceBuffer; @@ -175,14 +164,14 @@ int Environment::parseData(sockaddr *senderAddress, unsigned char* sourceBuffer, int dataLength = newData.parseData(sourceBuffer, numBytes); // update the mapping by address/ID - _data[*senderAddress][newData.getID()] = newData; + _data[senderAddress][newData.getID()] = newData; sourceBuffer += dataLength; numBytes -= dataLength; } // remove the default mapping, if any - _data.remove(getZeroAddress()); + _data.remove(HifiSockAddr()); return sourceBuffer - start; } diff --git a/interface/src/Environment.h b/interface/src/Environment.h index 1095687ae0..fc572c5e03 100644 --- a/interface/src/Environment.h +++ b/interface/src/Environment.h @@ -12,7 +12,7 @@ #include #include -#include +#include #include "EnvironmentData.h" #include "InterfaceConfig.h" @@ -34,7 +34,7 @@ public: bool findCapsulePenetration(const glm::vec3& start, const glm::vec3& end, float radius, glm::vec3& penetration); - int parseData(sockaddr *senderAddress, unsigned char* sourceBuffer, int numBytes); + int parseData(const HifiSockAddr& senderSockAddr, unsigned char* sourceBuffer, int numBytes); private: @@ -71,7 +71,7 @@ private: typedef QHash ServerData; - QHash _data; + QHash _data; QMutex _mutex; }; diff --git a/interface/src/PairingHandler.cpp b/interface/src/PairingHandler.cpp index c220c5f943..56d7642640 100644 --- a/interface/src/PairingHandler.cpp +++ b/interface/src/PairingHandler.cpp @@ -10,6 +10,9 @@ #include #include +#include + +#include #include #include "PairingHandler.h" @@ -27,14 +30,14 @@ PairingHandler* PairingHandler::getInstance() { return instance; } -void PairingHandler::sendPairRequest() { - // grab the node socket from the NodeList singleton - UDPSocket *nodeSocket = NodeList::getInstance()->getNodeSocket(); +void PairingHandler::sendPairRequest() { // prepare the pairing request packet + NodeList* nodeList = NodeList::getInstance(); + // use the getLocalAddress helper to get this client's listening address - int localAddress = getLocalAddress(); + quint32 localAddress = getLocalAddress(); char pairPacket[24] = {}; sprintf(pairPacket, "Find %d.%d.%d.%d:%hu", @@ -42,19 +45,13 @@ void PairingHandler::sendPairRequest() { (localAddress >> 8) & 0xFF, (localAddress >> 16) & 0xFF, (localAddress >> 24) & 0xFF, - NodeList::getInstance()->getSocketListenPort()); + NodeList::getInstance()->getNodeSocket().localPort()); qDebug("Sending pair packet: %s\n", pairPacket); - sockaddr_in pairingServerSocket; - - pairingServerSocket.sin_family = AF_INET; - - // lookup the pairing server IP by the hostname - struct hostent* hostInfo = gethostbyname(PAIRING_SERVER_HOSTNAME); - memcpy(&pairingServerSocket.sin_addr, hostInfo->h_addr_list[0], hostInfo->h_length); - pairingServerSocket.sin_port = htons(PAIRING_SERVER_PORT); + HifiSockAddr pairingServerSocket(PAIRING_SERVER_HOSTNAME, PAIRING_SERVER_PORT); // send the pair request to the pairing server - nodeSocket->send((sockaddr*) &pairingServerSocket, pairPacket, strlen(pairPacket)); + nodeList->getNodeSocket().writeDatagram((char*) pairPacket, strlen(pairPacket), + pairingServerSocket.getAddress(), pairingServerSocket.getPort()); } diff --git a/interface/src/VoxelPacketProcessor.cpp b/interface/src/VoxelPacketProcessor.cpp index 9087a5a545..0a76ebe5cb 100644 --- a/interface/src/VoxelPacketProcessor.cpp +++ b/interface/src/VoxelPacketProcessor.cpp @@ -14,7 +14,7 @@ #include "Menu.h" #include "VoxelPacketProcessor.h" -void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { +void VoxelPacketProcessor::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "VoxelPacketProcessor::processPacket()"); @@ -50,10 +50,10 @@ void VoxelPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* } // fall through to piggyback message if (Menu::getInstance()->isOptionChecked(MenuOption::Voxels)) { - Node* voxelServer = NodeList::getInstance()->nodeWithAddress(&senderAddress); - if (voxelServer && socketMatch(voxelServer->getActiveSocket(), &senderAddress)) { + Node* voxelServer = NodeList::getInstance()->nodeWithAddress(senderAddress); + if (voxelServer && *voxelServer->getActiveSocket() == senderAddress) { if (packetData[0] == PACKET_TYPE_ENVIRONMENT_DATA) { - app->_environment.parseData(&senderAddress, packetData, messageLength); + app->_environment.parseData(senderAddress, packetData, messageLength); } else { app->_voxels.setDataSourceUUID(voxelServer->getUUID()); app->_voxels.parseData(packetData, messageLength); diff --git a/interface/src/VoxelPacketProcessor.h b/interface/src/VoxelPacketProcessor.h index 87aae397d5..4420ccc6cf 100644 --- a/interface/src/VoxelPacketProcessor.h +++ b/interface/src/VoxelPacketProcessor.h @@ -17,6 +17,6 @@ /// the user is responsible for reading inbound packets and adding them to the processing queue by calling queueReceivedPacket() class VoxelPacketProcessor : public ReceivedPacketProcessor { protected: - virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength); }; #endif // __shared__VoxelPacketProcessor__ diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index d9c672fdf3..7d7a8612d5 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/libraries/audio/src/AudioInjectionManager.cpp b/libraries/audio/src/AudioInjectionManager.cpp deleted file mode 100644 index 16ace5bbb6..0000000000 --- a/libraries/audio/src/AudioInjectionManager.cpp +++ /dev/null @@ -1,77 +0,0 @@ -// -// AudioInjectionManager.cpp -// hifi -// -// Created by Stephen Birarda on 5/16/13. -// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -#include - -#include "SharedUtil.h" -#include "NodeList.h" -#include "NodeTypes.h" -#include "Node.h" -#include "PacketHeaders.h" - -#include "AudioInjectionManager.h" - -UDPSocket* AudioInjectionManager::_injectorSocket = NULL; -sockaddr AudioInjectionManager::_destinationSocket; -bool AudioInjectionManager::_isDestinationSocketExplicit = false; -AudioInjector* AudioInjectionManager::_injectors[50] = {}; - -AudioInjector* AudioInjectionManager::injectorWithCapacity(int capacity) { - for (int i = 0; i < MAX_CONCURRENT_INJECTORS; i++) { - if (!_injectors[i]) { - _injectors[i] = new AudioInjector(capacity); - return _injectors[i]; - } - } - - return NULL; -} - -void AudioInjectionManager::setDestinationSocket(sockaddr& destinationSocket) { - _destinationSocket = destinationSocket; - _isDestinationSocketExplicit = true; -} - -void* AudioInjectionManager::injectAudioViaThread(void* args) { - AudioInjector* injector = (AudioInjector*) args; - - // if we don't have an injectorSocket then grab the one from the node list - if (!_injectorSocket) { - _injectorSocket = NodeList::getInstance()->getNodeSocket(); - } - - // if we don't have an explicit destination socket then pull active socket for current audio mixer from node list - if (!_isDestinationSocketExplicit) { - Node* audioMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AUDIO_MIXER); - if (audioMixer && audioMixer->getActiveSocket()) { - _destinationSocket = *audioMixer->getActiveSocket(); - } else { - pthread_exit(0); - } - } - - injector->injectAudio(_injectorSocket, &_destinationSocket); - - // if this an injector inside the injection manager's array we're responsible for deletion - for (int i = 0; i < MAX_CONCURRENT_INJECTORS; i++) { - if (_injectors[i] == injector) { - // pointer matched - delete this injector - delete injector; - - // set the pointer to NULL so we can reuse this spot - _injectors[i] = NULL; - } - } - - pthread_exit(0); -} - -void AudioInjectionManager::threadInjector(AudioInjector* injector) { - pthread_t audioInjectThread; - pthread_create(&audioInjectThread, NULL, injectAudioViaThread, (void*) injector); -} \ No newline at end of file diff --git a/libraries/audio/src/AudioInjectionManager.h b/libraries/audio/src/AudioInjectionManager.h deleted file mode 100644 index 5f56663a78..0000000000 --- a/libraries/audio/src/AudioInjectionManager.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// AudioInjectionManager.h -// hifi -// -// Created by Stephen Birarda on 5/16/13. -// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -#ifndef __hifi__AudioInjectionManager__ -#define __hifi__AudioInjectionManager__ - -#include - -#include "UDPSocket.h" -#include "AudioInjector.h" - -const int MAX_CONCURRENT_INJECTORS = 50; - -class AudioInjectionManager { -public: - static AudioInjector* injectorWithCapacity(int capacity); - - static void threadInjector(AudioInjector* injector); - - static void setInjectorSocket(UDPSocket* injectorSocket) { _injectorSocket = injectorSocket;} - static void setDestinationSocket(sockaddr& destinationSocket); -private: - static void* injectAudioViaThread(void* args); - - static UDPSocket* _injectorSocket; - static sockaddr _destinationSocket; - static bool _isDestinationSocketExplicit; - static AudioInjector* _injectors[MAX_CONCURRENT_INJECTORS]; -}; - -#endif /* defined(__hifi__AudioInjectionManager__) */ diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp deleted file mode 100644 index 2e58aa13c8..0000000000 --- a/libraries/audio/src/AudioInjector.cpp +++ /dev/null @@ -1,137 +0,0 @@ -// -// AudioInjector.cpp -// hifi -// -// Created by Stephen Birarda on 4/23/13. -// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -#include -#include -#include - -#include -#include -#include -#include - -#include "AudioInjector.h" - -AudioInjector::AudioInjector(int maxNumSamples) : - _streamIdentifier(QUuid::createUuid()), - _numTotalSamples(maxNumSamples), - _position(0.0f, 0.0f, 0.0f), - _orientation(), - _radius(0.0f), - _volume(MAX_INJECTOR_VOLUME), - _indexOfNextSlot(0), - _isInjectingAudio(false) -{ - _audioSampleArray = new int16_t[maxNumSamples]; - memset(_audioSampleArray, 0, _numTotalSamples * sizeof(int16_t)); -} - -AudioInjector::~AudioInjector() { - delete[] _audioSampleArray; -} - -void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destinationSocket) { - if (_audioSampleArray && _indexOfNextSlot > 0) { - _isInjectingAudio = true; - - timeval startTime; - - // calculate the number of bytes required for additional data - int leadingBytes = numBytesForPacketHeader((unsigned char*) &PACKET_TYPE_INJECT_AUDIO) - + NUM_BYTES_RFC4122_UUID - + NUM_BYTES_RFC4122_UUID - + sizeof(_position) - + sizeof(_orientation) - + sizeof(_radius) - + sizeof(_volume); - - unsigned char dataPacket[(BUFFER_LENGTH_SAMPLES_PER_CHANNEL * sizeof(int16_t)) + leadingBytes]; - - unsigned char* currentPacketPtr = dataPacket + populateTypeAndVersion(dataPacket, PACKET_TYPE_INJECT_AUDIO); - - // copy the UUID for the owning node - QByteArray rfcUUID = NodeList::getInstance()->getOwnerUUID().toRfc4122(); - memcpy(currentPacketPtr, rfcUUID.constData(), rfcUUID.size()); - currentPacketPtr += rfcUUID.size(); - - // copy the stream identifier - QByteArray rfcStreamIdentifier = _streamIdentifier.toRfc4122(); - memcpy(currentPacketPtr, rfcStreamIdentifier.constData(), rfcStreamIdentifier.size()); - currentPacketPtr += rfcStreamIdentifier.size(); - - memcpy(currentPacketPtr, &_position, sizeof(_position)); - currentPacketPtr += sizeof(_position); - - memcpy(currentPacketPtr, &_orientation, sizeof(_orientation)); - currentPacketPtr += sizeof(_orientation); - - memcpy(currentPacketPtr, &_radius, sizeof(_radius)); - currentPacketPtr += sizeof(_radius); - - *currentPacketPtr = _volume; - currentPacketPtr++; - - gettimeofday(&startTime, NULL); - int nextFrame = 0; - - for (int i = 0; i < _numTotalSamples; i += BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - int usecToSleep = usecTimestamp(&startTime) + (nextFrame++ * INJECT_INTERVAL_USECS) - usecTimestampNow(); - if (usecToSleep > 0) { - usleep(usecToSleep); - } - - int numSamplesToCopy = BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - - if (_numTotalSamples - i < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - numSamplesToCopy = _numTotalSamples - i; - memset(currentPacketPtr + numSamplesToCopy, - 0, - BUFFER_LENGTH_BYTES_PER_CHANNEL - (numSamplesToCopy * sizeof(int16_t))); - } - - memcpy(currentPacketPtr, _audioSampleArray + i, numSamplesToCopy * sizeof(int16_t)); - - injectorSocket->send(destinationSocket, dataPacket, sizeof(dataPacket)); - } - - _isInjectingAudio = false; - } -} - -void AudioInjector::addSample(const int16_t sample) { - if (_indexOfNextSlot != _numTotalSamples) { - // only add this sample if we actually have space for it - _audioSampleArray[_indexOfNextSlot++] = sample; - } -} - -void AudioInjector::addSamples(int16_t* sampleBuffer, int numSamples) { - if (_audioSampleArray + _indexOfNextSlot + numSamples <= _audioSampleArray + _numTotalSamples) { - // only copy the audio from the sample buffer if there's space - memcpy(_audioSampleArray + _indexOfNextSlot, sampleBuffer, numSamples * sizeof(int16_t)); - _indexOfNextSlot += numSamples; - } -} - -void AudioInjector::clear() { - _indexOfNextSlot = 0; - memset(_audioSampleArray, 0, _numTotalSamples * sizeof(int16_t)); -} - -int16_t& AudioInjector::sampleAt(const int index) { - assert(index >= 0 && index < _numTotalSamples); - - return _audioSampleArray[index]; -} - -void AudioInjector::insertSample(const int index, int sample) { - assert (index >= 0 && index < _numTotalSamples); - - _audioSampleArray[index] = (int16_t) sample; - _indexOfNextSlot = index + 1; -} diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h deleted file mode 100644 index b3a5b82fdf..0000000000 --- a/libraries/audio/src/AudioInjector.h +++ /dev/null @@ -1,73 +0,0 @@ -// -// AudioInjector.h -// hifi -// -// Created by Stephen Birarda on 4/23/13. -// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -#ifndef __hifi__AudioInjector__ -#define __hifi__AudioInjector__ - -#include -#include - -#include -#include - -#include -#include - -#include "AudioRingBuffer.h" - -const int MAX_INJECTOR_VOLUME = 0xFF; - -const int INJECT_INTERVAL_USECS = floorf((BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SAMPLE_RATE) * 1000000); - -class AudioInjector : public QObject { - Q_OBJECT - - Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) - Q_PROPERTY(uchar volume READ getVolume WRITE setVolume); -public: - AudioInjector(int maxNumSamples); - ~AudioInjector(); - - void injectAudio(UDPSocket* injectorSocket, sockaddr* destinationSocket); - - bool isInjectingAudio() const { return _isInjectingAudio; } - - unsigned char getVolume() const { return _volume; } - void setVolume(unsigned char volume) { _volume = volume; } - - const glm::vec3& getPosition() const { return _position; } - void setPosition(const glm::vec3& position) { _position = position; } - - const glm::quat& getOrientation() const { return _orientation; } - void setOrientation(const glm::quat& orientation) { _orientation = orientation; } - - float getRadius() const { return _radius; } - void setRadius(float radius) { _radius = radius; } - - bool hasSamplesToInject() const { return _indexOfNextSlot > 0; } - - void addSample(const int16_t sample); - void addSamples(int16_t* sampleBuffer, int numSamples); - - void clear(); -public slots: - int16_t& sampleAt(const int index); - void insertSample(const int index, int sample); -private: - QUuid _streamIdentifier; - int16_t* _audioSampleArray; - int _numTotalSamples; - glm::vec3 _position; - glm::quat _orientation; - float _radius; - unsigned char _volume; - int _indexOfNextSlot; - bool _isInjectingAudio; -}; - -#endif /* defined(__hifi__AudioInjector__) */ diff --git a/libraries/audio/src/InjectedAudioRingBuffer.cpp b/libraries/audio/src/InjectedAudioRingBuffer.cpp index 18ee037ea9..9adb525b93 100644 --- a/libraries/audio/src/InjectedAudioRingBuffer.cpp +++ b/libraries/audio/src/InjectedAudioRingBuffer.cpp @@ -24,6 +24,8 @@ InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier) } +const uchar MAX_INJECTOR_VOLUME = 255; + int InjectedAudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { unsigned char* currentBuffer = sourceBuffer + numBytesForPacketHeader(sourceBuffer); diff --git a/libraries/audio/src/InjectedAudioRingBuffer.h b/libraries/audio/src/InjectedAudioRingBuffer.h index bab540919d..b5845366fb 100644 --- a/libraries/audio/src/InjectedAudioRingBuffer.h +++ b/libraries/audio/src/InjectedAudioRingBuffer.h @@ -11,8 +11,6 @@ #include -#include "AudioInjector.h" - #include "PositionalAudioRingBuffer.h" class InjectedAudioRingBuffer : public PositionalAudioRingBuffer { diff --git a/libraries/shared/src/HifiSockAddr.cpp b/libraries/shared/src/HifiSockAddr.cpp new file mode 100644 index 0000000000..542b4c2e52 --- /dev/null +++ b/libraries/shared/src/HifiSockAddr.cpp @@ -0,0 +1,110 @@ +// +// HifiSockAddr.cpp +// hifi +// +// Created by Stephen Birarda on 11/26/2013. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#include "HifiSockAddr.h" + +#include +#include + +HifiSockAddr::HifiSockAddr() : + _address(QHostAddress::Null), + _port(0) +{ + +} + +HifiSockAddr::HifiSockAddr(const QHostAddress& address, quint16 port) : + _address(address), + _port(port) +{ + +} + +HifiSockAddr::HifiSockAddr(const HifiSockAddr& otherSockAddr) { + _address = otherSockAddr._address; + _port = otherSockAddr._port; +} + +HifiSockAddr::HifiSockAddr(const QString& hostname, quint16 hostOrderPort) { + // lookup the IP by the hostname + QHostInfo hostInfo = QHostInfo::fromName(hostname); + if (!hostInfo.addresses().isEmpty()) { + // use the first IP address + _address = hostInfo.addresses().first(); + _port = hostOrderPort; } +} + +HifiSockAddr& HifiSockAddr::operator=(const HifiSockAddr& rhsSockAddr) { + HifiSockAddr temp(rhsSockAddr); + swap(temp); + return *this; +} + +void HifiSockAddr::swap(HifiSockAddr& otherSockAddr) { + using std::swap; + + swap(_address, otherSockAddr._address); + swap(_port, otherSockAddr._port); +} + +int HifiSockAddr::packSockAddr(unsigned char* packetData, const HifiSockAddr& packSockAddr) { + unsigned int addressToPack = packSockAddr._address.toIPv4Address(); + memcpy(packetData, &addressToPack, sizeof(packSockAddr._address.toIPv4Address())); + memcpy(packetData, &packSockAddr._port, sizeof(packSockAddr._port)); + + return sizeof(addressToPack) + sizeof(packSockAddr._port); +} + +int HifiSockAddr::unpackSockAddr(const unsigned char* packetData, HifiSockAddr& unpackDestSockAddr) { + unpackDestSockAddr._address = QHostAddress(*((quint32*) packetData)); + unpackDestSockAddr._port = *((quint16*) (packetData + sizeof(quint32))); + + return sizeof(quint32) + sizeof(quint16); +} + +bool HifiSockAddr::operator==(const HifiSockAddr &rhsSockAddr) const { + return _address == rhsSockAddr._address && _port == rhsSockAddr._port; +} + +QDebug operator<<(QDebug debug, const HifiSockAddr &hifiSockAddr) { + debug.nospace() << hifiSockAddr._address.toString() << ":" << hifiSockAddr._port; + return debug; +} + +quint32 getLocalAddress() { + + static int localAddress = 0; + + if (localAddress == 0) { + foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { + if (interface.flags() & QNetworkInterface::IsUp + && interface.flags() & QNetworkInterface::IsRunning + && interface.flags() & ~QNetworkInterface::IsLoopBack) { + // we've decided that this is the active NIC + // enumerate it's addresses to grab the IPv4 address + foreach(const QNetworkAddressEntry &entry, interface.addressEntries()) { + // make sure it's an IPv4 address that isn't the loopback + if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) { + qDebug("Node's local address is %s\n", entry.ip().toString().toLocal8Bit().constData()); + + // set our localAddress and break out + localAddress = htonl(entry.ip().toIPv4Address()); + break; + } + } + } + + if (localAddress != 0) { + break; + } + } + } + + // return the looked up local address + return localAddress; +} diff --git a/libraries/shared/src/HifiSockAddr.h b/libraries/shared/src/HifiSockAddr.h new file mode 100644 index 0000000000..c5a20896e7 --- /dev/null +++ b/libraries/shared/src/HifiSockAddr.h @@ -0,0 +1,48 @@ +// +// HifiSockAddr.h +// hifi +// +// Created by Stephen Birarda on 11/26/2013. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// + +#ifndef __hifi__HifiSockAddr__ +#define __hifi__HifiSockAddr__ + +#include + +class HifiSockAddr { +public: + HifiSockAddr(); + HifiSockAddr(const QHostAddress& address, quint16 port); + HifiSockAddr(const HifiSockAddr& otherSockAddr); + HifiSockAddr(const QString& hostname, quint16 hostOrderPort); + + bool isNull() const { return _address.isNull() && _port == 0; } + + HifiSockAddr& operator=(const HifiSockAddr& rhsSockAddr); + void swap(HifiSockAddr& otherSockAddr); + + bool operator==(const HifiSockAddr& rhsSockAddr) const; + bool operator!=(const HifiSockAddr& rhsSockAddr) const { return !(*this == rhsSockAddr); } + + const QHostAddress& getAddress() const { return _address; } + QHostAddress* getAddressPointer() { return &_address; } + void setAddress(const QHostAddress& address) { _address = address; } + + quint16 getPort() const { return _port; } + quint16* getPortPointer() { return &_port; } + void setPort(quint16 port) { _port = port; } + + static int packSockAddr(unsigned char* packetData, const HifiSockAddr& packSockAddr); + static int unpackSockAddr(const unsigned char* packetData, HifiSockAddr& unpackDestSockAddr); + + friend QDebug operator<<(QDebug debug, const HifiSockAddr &hifiSockAddr); +private: + QHostAddress _address; + quint16 _port; +}; + +quint32 getLocalAddress(); + +#endif /* defined(__hifi__HifiSockAddr__) */ diff --git a/libraries/shared/src/Logging.cpp b/libraries/shared/src/Logging.cpp index 0182034be6..866d603861 100644 --- a/libraries/shared/src/Logging.cpp +++ b/libraries/shared/src/Logging.cpp @@ -11,35 +11,35 @@ #include #include +#include + +#include "HifiSockAddr.h" #include "SharedUtil.h" #include "NodeList.h" #include "Logging.h" -sockaddr_in Logging::logstashSocket = {}; +HifiSockAddr Logging::logstashSocket = HifiSockAddr(); char* Logging::targetName = NULL; -sockaddr* Logging::socket() { +const HifiSockAddr& Logging::socket() { - if (logstashSocket.sin_addr.s_addr == 0) { + if (logstashSocket.getAddress().isNull()) { // we need to construct the socket object - - // assume IPv4 - logstashSocket.sin_family = AF_INET; - // use the constant port - logstashSocket.sin_port = htons(LOGSTASH_UDP_PORT); + logstashSocket.setPort(htons(LOGSTASH_UDP_PORT)); // lookup the IP address for the constant hostname - struct hostent* logstashHostInfo; - if ((logstashHostInfo = gethostbyname(LOGSTASH_HOSTNAME))) { - memcpy(&logstashSocket.sin_addr, logstashHostInfo->h_addr_list[0], logstashHostInfo->h_length); + QHostInfo hostInfo = QHostInfo::fromName(LOGSTASH_HOSTNAME); + if (!hostInfo.addresses().isEmpty()) { + // use the first IP address + logstashSocket.setAddress(hostInfo.addresses().first()); } else { printf("Failed to lookup logstash IP - will try again on next log attempt.\n"); } } - return (sockaddr*) &logstashSocket; + return logstashSocket; } bool Logging::shouldSendStats() { @@ -57,7 +57,8 @@ void Logging::stashValue(char statType, const char* key, float value) { NodeList *nodeList = NodeList::getInstance(); if (nodeList) { - nodeList->getNodeSocket()->send(socket(), logstashPacket, numPacketBytes); + nodeList->getNodeSocket().writeDatagram(logstashPacket, numPacketBytes, + logstashSocket.getAddress(), logstashSocket.getPort()); } } diff --git a/libraries/shared/src/Logging.h b/libraries/shared/src/Logging.h index c4f921070a..d64c39992b 100644 --- a/libraries/shared/src/Logging.h +++ b/libraries/shared/src/Logging.h @@ -20,11 +20,13 @@ const char STAT_TYPE_TIMER = 't'; const char STAT_TYPE_COUNTER = 'c'; const char STAT_TYPE_GAUGE = 'g'; +class HifiSockAddr; + /// Handles custom message handling and sending of stats/logs to Logstash instance class Logging { public: /// \return the socket used to send stats to logstash - static sockaddr* socket(); + static const HifiSockAddr& socket(); /// checks if this target should send stats to logstash, given its current environment /// \return true if the caller should send stats to logstash @@ -44,7 +46,7 @@ public: /// prints various process, message type, and time information static void verboseMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); private: - static sockaddr_in logstashSocket; + static HifiSockAddr logstashSocket; static char* targetName; }; diff --git a/libraries/shared/src/NetworkPacket.cpp b/libraries/shared/src/NetworkPacket.cpp index 0acabbac58..575e80b59b 100644 --- a/libraries/shared/src/NetworkPacket.cpp +++ b/libraries/shared/src/NetworkPacket.cpp @@ -22,10 +22,10 @@ NetworkPacket::~NetworkPacket() { // nothing to do } -void NetworkPacket::copyContents(const sockaddr& address, const unsigned char* packetData, ssize_t packetLength) { +void NetworkPacket::copyContents(const HifiSockAddr& sockAddr, const unsigned char* packetData, ssize_t packetLength) { _packetLength = 0; if (packetLength >=0 && packetLength <= MAX_PACKET_SIZE) { - memcpy(&_address, &address, sizeof(_address)); + _sockAddr = sockAddr; _packetLength = packetLength; memcpy(&_packetData[0], packetData, packetLength); } else { @@ -34,16 +34,16 @@ void NetworkPacket::copyContents(const sockaddr& address, const unsigned char* } NetworkPacket::NetworkPacket(const NetworkPacket& packet) { - copyContents(packet.getAddress(), packet.getData(), packet.getLength()); + copyContents(packet.getSockAddr(), packet.getData(), packet.getLength()); } -NetworkPacket::NetworkPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { - copyContents(address, packetData, packetLength); +NetworkPacket::NetworkPacket(const HifiSockAddr& sockAddr, unsigned char* packetData, ssize_t packetLength) { + copyContents(sockAddr, packetData, packetLength); }; // copy assignment NetworkPacket& NetworkPacket::operator=(NetworkPacket const& other) { - copyContents(other.getAddress(), other.getData(), other.getLength()); + copyContents(other.getSockAddr(), other.getData(), other.getLength()); return *this; } diff --git a/libraries/shared/src/NetworkPacket.h b/libraries/shared/src/NetworkPacket.h index 9c7c61e10f..b30564087d 100644 --- a/libraries/shared/src/NetworkPacket.h +++ b/libraries/shared/src/NetworkPacket.h @@ -15,6 +15,8 @@ #include #include +#include "HifiSockAddr.h" + #include "NodeList.h" // for MAX_PACKET_SIZE /// Storage of not-yet processed inbound, or not yet sent outbound generic UDP network packet @@ -30,19 +32,19 @@ public: NetworkPacket& operator= (NetworkPacket&& other); // move assignment #endif - NetworkPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength); + NetworkPacket(const HifiSockAddr& sockAddr, unsigned char* packetData, ssize_t packetLength); - sockaddr& getAddress() { return _address; } + const HifiSockAddr& getSockAddr() const { return _sockAddr; } ssize_t getLength() const { return _packetLength; } unsigned char* getData() { return &_packetData[0]; } - const sockaddr& getAddress() const { return _address; } + const HifiSockAddr& getAddress() const { return _sockAddr; } const unsigned char* getData() const { return &_packetData[0]; } private: - void copyContents(const sockaddr& address, const unsigned char* packetData, ssize_t packetLength); + void copyContents(const HifiSockAddr& sockAddr, const unsigned char* packetData, ssize_t packetLength); - sockaddr _address; + HifiSockAddr _sockAddr; ssize_t _packetLength; unsigned char _packetData[MAX_PACKET_SIZE]; }; diff --git a/libraries/shared/src/Node.cpp b/libraries/shared/src/Node.cpp index d4bd8a084a..cc82677f9a 100644 --- a/libraries/shared/src/Node.cpp +++ b/libraries/shared/src/Node.cpp @@ -19,30 +19,25 @@ #include "Node.h" #include "NodeTypes.h" #include "SharedUtil.h" -#include "UDPSocket.h" #include -Node::Node(const QUuid& uuid, char type, sockaddr* publicSocket, sockaddr* localSocket) : +Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) : _type(type), _uuid(uuid), _wakeMicrostamp(usecTimestampNow()), _lastHeardMicrostamp(usecTimestampNow()), + _publicSocket(publicSocket), + _localSocket(localSocket), _activeSocket(NULL), _bytesReceivedMovingAverage(NULL), _linkedData(NULL), _isAlive(true) { - setPublicSocket(publicSocket); - setLocalSocket(localSocket); - pthread_mutex_init(&_mutex, 0); } Node::~Node() { - delete _publicSocket; - delete _localSocket; - if (_linkedData) { _linkedData->deleteOrDeleteLater(); } @@ -86,47 +81,32 @@ const char* Node::getTypeName() const { } } -void Node::setPublicSocket(sockaddr* publicSocket) { - if (_activeSocket == _publicSocket) { +void Node::setPublicSocket(const HifiSockAddr& publicSocket) { + if (_activeSocket == &_publicSocket) { // if the active socket was the public socket then reset it to NULL _activeSocket = NULL; } - if (publicSocket) { - _publicSocket = new sockaddr(*publicSocket); - } else { - _publicSocket = NULL; - } + _publicSocket = publicSocket; } -void Node::setLocalSocket(sockaddr* localSocket) { - if (_activeSocket == _localSocket) { +void Node::setLocalSocket(const HifiSockAddr& localSocket) { + if (_activeSocket == &_localSocket) { // if the active socket was the local socket then reset it to NULL _activeSocket = NULL; } - if (localSocket) { - _localSocket = new sockaddr(*localSocket); - } else { - _localSocket = NULL; - } + _localSocket = localSocket; } void Node::activateLocalSocket() { qDebug() << "Activating local socket for node" << *this << "\n"; - _activeSocket = _localSocket; + _activeSocket = &_localSocket; } void Node::activatePublicSocket() { qDebug() << "Activating public socket for node" << *this << "\n"; - _activeSocket = _publicSocket; -} - -bool Node::matches(sockaddr* otherPublicSocket, sockaddr* otherLocalSocket, char otherNodeType) { - // checks if two node objects are the same node (same type + local + public address) - return _type == otherNodeType - && socketMatch(_publicSocket, otherPublicSocket) - && socketMatch(_localSocket, otherLocalSocket); + _activeSocket = &_publicSocket; } void Node::recordBytesReceived(int bytesReceived) { @@ -154,15 +134,8 @@ float Node::getAverageKilobitsPerSecond() { } QDebug operator<<(QDebug debug, const Node &node) { - char publicAddressBuffer[16] = {'\0'}; - unsigned short publicAddressPort = loadBufferWithSocketInfo(publicAddressBuffer, node.getPublicSocket()); - - char localAddressBuffer[16] = {'\0'}; - unsigned short localAddressPort = loadBufferWithSocketInfo(localAddressBuffer, node.getLocalSocket()); - debug.nospace() << node.getTypeName() << " (" << node.getType() << ")"; debug << " " << node.getUUID().toString().toLocal8Bit().constData() << " "; - debug.nospace() << publicAddressBuffer << ":" << publicAddressPort; - debug.nospace() << " / " << localAddressBuffer << ":" << localAddressPort; + debug.nospace() << node.getLocalSocket() << "/" << node.getPublicSocket(); return debug.nospace(); } diff --git a/libraries/shared/src/Node.h b/libraries/shared/src/Node.h index 3f7780d63d..4614a6f0a8 100644 --- a/libraries/shared/src/Node.h +++ b/libraries/shared/src/Node.h @@ -21,19 +21,18 @@ #include #include +#include "HifiSockAddr.h" #include "NodeData.h" #include "SimpleMovingAverage.h" class Node { public: - Node(const QUuid& uuid, char type, sockaddr* publicSocket, sockaddr* localSocket); + Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); ~Node(); bool operator==(const Node& otherNode) const { return _uuid == otherNode._uuid; } bool operator!=(const Node& otherNode) const { return !(*this == otherNode); } - bool matches(sockaddr* otherPublicSocket, sockaddr* otherLocalSocket, char otherNodeType); - char getType() const { return _type; } void setType(char type) { _type = type; } const char* getTypeName() const; @@ -47,12 +46,12 @@ public: uint64_t getLastHeardMicrostamp() const { return _lastHeardMicrostamp; } void setLastHeardMicrostamp(uint64_t lastHeardMicrostamp) { _lastHeardMicrostamp = lastHeardMicrostamp; } - sockaddr* getPublicSocket() const { return _publicSocket; } - void setPublicSocket(sockaddr* publicSocket); - sockaddr* getLocalSocket() const { return _localSocket; } - void setLocalSocket(sockaddr* localSocket); + const HifiSockAddr& getPublicSocket() const { return _publicSocket; } + void setPublicSocket(const HifiSockAddr& publicSocket); + const HifiSockAddr& getLocalSocket() const { return _localSocket; } + void setLocalSocket(const HifiSockAddr& localSocket); - sockaddr* getActiveSocket() const { return _activeSocket; } + const HifiSockAddr* getActiveSocket() const { return _activeSocket; } void activatePublicSocket(); void activateLocalSocket(); @@ -87,9 +86,9 @@ private: QUuid _uuid; uint64_t _wakeMicrostamp; uint64_t _lastHeardMicrostamp; - sockaddr* _publicSocket; - sockaddr* _localSocket; - sockaddr* _activeSocket; + HifiSockAddr _publicSocket; + HifiSockAddr _localSocket; + HifiSockAddr* _activeSocket; SimpleMovingAverage* _bytesReceivedMovingAverage; NodeData* _linkedData; bool _isAlive; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index daa0d7a4b1..59135b05d4 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -15,6 +15,7 @@ #include #include "Assignment.h" +#include "HifiSockAddr.h" #include "Logging.h" #include "NodeList.h" #include "NodeTypes.h" @@ -61,22 +62,20 @@ NodeList* NodeList::getInstance() { NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : _domainHostname(DEFAULT_DOMAIN_HOSTNAME), - _domainIP(), - _domainPort(DEFAULT_DOMAIN_SERVER_PORT), + _domainSockAddr(HifiSockAddr(QHostAddress::Null, DEFAULT_DOMAIN_SERVER_PORT)), _nodeBuckets(), _numNodes(0), - _nodeSocket(newSocketListenPort), + _nodeSocket(), _ownerType(newOwnerType), _nodeTypesOfInterest(NULL), _ownerUUID(QUuid::createUuid()), _numNoReplyDomainCheckIns(0), - _assignmentServerSocket(NULL), - _publicAddress(), - _publicPort(0), + _assignmentServerSocket(), + _publicSockAddr(), _hasCompletedInitialSTUNFailure(false), _stunRequestsSinceSuccess(0) { - + _nodeSocket.bind(QHostAddress::LocalHost, newSocketListenPort); } NodeList::~NodeList() { @@ -100,29 +99,29 @@ void NodeList::setDomainHostname(const QString& domainHostname) { _domainHostname = domainHostname.left(colonIndex); // grab the port by reading the string after the colon - _domainPort = atoi(domainHostname.mid(colonIndex + 1, domainHostname.size()).toLocal8Bit().constData()); + _domainSockAddr.setPort(atoi(domainHostname.mid(colonIndex + 1, domainHostname.size()).toLocal8Bit().constData())); - qDebug() << "Updated hostname to" << _domainHostname << "and port to" << _domainPort << "\n"; + qDebug() << "Updated hostname to" << _domainHostname << "and port to" << _domainSockAddr.getPort() << "\n"; } else { // no port included with the hostname, simply set the member variable and reset the domain server port to default _domainHostname = domainHostname; - _domainPort = DEFAULT_DOMAIN_SERVER_PORT; + _domainSockAddr.setPort(DEFAULT_DOMAIN_SERVER_PORT); } // clear the NodeList so nodes from this domain are killed clear(); // reset our _domainIP to the null address so that a lookup happens on next check in - _domainIP.clear(); + _domainSockAddr.setAddress(QHostAddress::Null); notifyDomainChanged(); } } -void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) { +void NodeList::timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData) { for(NodeList::iterator node = begin(); node != end(); node++) { - if (socketMatch(node->getPublicSocket(), nodeAddress) || - socketMatch(node->getLocalSocket(), nodeAddress)) { + if (node->getPublicSocket() == nodeAddress || + node->getLocalSocket() == nodeAddress) { int pingTime = usecTimestampNow() - *(uint64_t*)(packetData + numBytesForPacketHeader(packetData)); @@ -132,11 +131,11 @@ void NodeList::timePingReply(sockaddr *nodeAddress, unsigned char *packetData) { } } -void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetData, size_t dataBytes) { +void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, unsigned char* packetData, size_t dataBytes) { switch (packetData[0]) { case PACKET_TYPE_DOMAIN: { // only process the DS if this is our current domain server - if (_domainIP == QHostAddress(senderAddress)) { + if (_domainSockAddr == senderSockAddr) { processDomainServerList(packetData, dataBytes); } @@ -145,15 +144,15 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat case PACKET_TYPE_PING: { // send it right back populateTypeAndVersion(packetData, PACKET_TYPE_PING_REPLY); - _nodeSocket.send(senderAddress, packetData, dataBytes); + _nodeSocket.writeDatagram((char*) packetData, dataBytes, senderSockAddr.getAddress(), senderSockAddr.getPort()); break; } case PACKET_TYPE_PING_REPLY: { // activate the appropriate socket for this node, if not yet updated - activateSocketFromNodeCommunication(senderAddress); + activateSocketFromNodeCommunication(senderSockAddr); // set the ping time for this node for stat collection - timePingReply(senderAddress, packetData); + timePingReply(senderSockAddr, packetData); break; } case PACKET_TYPE_STUN_RESPONSE: { @@ -169,7 +168,7 @@ void NodeList::processNodeData(sockaddr* senderAddress, unsigned char* packetDat } } -void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes) { +void NodeList::processBulkNodeData(const HifiSockAddr& senderAddress, unsigned char *packetData, int numTotalBytes) { // find the avatar mixer in our node list and update the lastRecvTime from it Node* bulkSendNode = nodeWithAddress(senderAddress); @@ -198,11 +197,11 @@ void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packe if (!matchingNode) { // we're missing this node, we need to add it to the list - matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, NULL, NULL); + matchingNode = addOrUpdateNode(nodeUUID, NODE_TYPE_AGENT, HifiSockAddr(), HifiSockAddr()); } currentPosition += updateNodeWithData(matchingNode, - NULL, + HifiSockAddr(), packetHolder, numTotalBytes - (currentPosition - startPosition)); @@ -210,16 +209,16 @@ void NodeList::processBulkNodeData(sockaddr *senderAddress, unsigned char *packe } } -int NodeList::updateNodeWithData(Node *node, sockaddr* senderAddress, unsigned char *packetData, int dataBytes) { +int NodeList::updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes) { node->lock(); node->setLastHeardMicrostamp(usecTimestampNow()); - if (senderAddress) { - activateSocketFromNodeCommunication(senderAddress); + if (!senderSockAddr.isNull()) { + activateSocketFromNodeCommunication(senderSockAddr); } - if (node->getActiveSocket() || !senderAddress) { + if (node->getActiveSocket() || senderSockAddr.isNull()) { node->recordBytesReceived(dataBytes); if (!node->getLinkedData() && linkedDataCreateCallback) { @@ -238,9 +237,9 @@ int NodeList::updateNodeWithData(Node *node, sockaddr* senderAddress, unsigned c } } -Node* NodeList::nodeWithAddress(sockaddr *senderAddress) { +Node* NodeList::nodeWithAddress(const HifiSockAddr &senderSockAddr) { for(NodeList::iterator node = begin(); node != end(); node++) { - if (node->getActiveSocket() && socketMatch(node->getActiveSocket(), senderAddress)) { + if (node->getActiveSocket() && *node->getActiveSocket() == senderSockAddr) { return &(*node); } } @@ -350,10 +349,8 @@ void NodeList::sendSTUNRequest() { qDebug("Sending intial stun request to %s\n", stunIPAddress.toLocal8Bit().constData()); } - _nodeSocket.send(stunIPAddress.toLocal8Bit().constData(), - STUN_SERVER_PORT, - stunRequestPacket, - sizeof(stunRequestPacket)); + _nodeSocket.writeDatagram((char*) stunRequestPacket, sizeof(stunRequestPacket), + QHostAddress(stunIPAddress), STUN_SERVER_PORT); break; } @@ -372,8 +369,7 @@ void NodeList::sendSTUNRequest() { } // reset the public address and port - _publicAddress = QHostAddress::Null; - _publicPort = 0; + _publicSockAddr = HifiSockAddr(); } } @@ -425,13 +421,12 @@ void NodeList::processSTUNResponse(unsigned char* packetData, size_t dataBytes) QHostAddress newPublicAddress = QHostAddress(stunAddress); - if (newPublicAddress != _publicAddress || newPublicPort != _publicPort) { - _publicAddress = newPublicAddress; - _publicPort = newPublicPort; + if (newPublicAddress != _publicSockAddr.getAddress() || newPublicPort != _publicSockAddr.getPort()) { + _publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort); qDebug("New public socket received from STUN server is %s:%hu\n", - _publicAddress.toString().toLocal8Bit().constData(), - _publicPort); + _publicSockAddr.getAddress().toString().toLocal8Bit().constData(), + _publicSockAddr.getPort()); } @@ -489,17 +484,17 @@ void NodeList::sendDomainServerCheckIn() { static bool printedDomainServerIP = false; // Lookup the IP address of the domain server if we need to - if (_domainIP.isNull()) { + if (_domainSockAddr.getAddress().isNull()) { qDebug("Looking up DS hostname %s.\n", _domainHostname.toLocal8Bit().constData()); QHostInfo domainServerHostInfo = QHostInfo::fromName(_domainHostname); for (int i = 0; i < domainServerHostInfo.addresses().size(); i++) { if (domainServerHostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { - _domainIP = domainServerHostInfo.addresses()[i]; + _domainSockAddr.setAddress(domainServerHostInfo.addresses()[i]); qDebug("DS at %s is at %s\n", _domainHostname.toLocal8Bit().constData(), - _domainIP.toString().toLocal8Bit().constData()); + _domainSockAddr.getAddress().toString().toLocal8Bit().constData()); printedDomainServerIP = true; @@ -512,11 +507,11 @@ void NodeList::sendDomainServerCheckIn() { } } } else if (!printedDomainServerIP) { - qDebug("Domain Server IP: %s\n", _domainIP.toString().toLocal8Bit().constData()); + qDebug("Domain Server IP: %s\n", _domainSockAddr.getAddress().toString().toLocal8Bit().constData()); printedDomainServerIP = true; } - if (_publicAddress.isNull() && !_hasCompletedInitialSTUNFailure) { + if (_publicSockAddr.isNull() && !_hasCompletedInitialSTUNFailure) { // we don't know our public socket and we need to send it to the domain server // send a STUN request to figure it out sendSTUNRequest(); @@ -548,13 +543,11 @@ void NodeList::sendDomainServerCheckIn() { packetPosition += rfcOwnerUUID.size(); // pack our public address to send to domain-server - packetPosition += packSocket(checkInPacket + (packetPosition - checkInPacket), - htonl(_publicAddress.toIPv4Address()), htons(_publicPort)); + packetPosition += HifiSockAddr::packSockAddr(checkInPacket + (packetPosition - checkInPacket), _publicSockAddr); // pack our local address to send to domain-server - packetPosition += packSocket(checkInPacket + (packetPosition - checkInPacket), - getLocalAddress(), - htons(_nodeSocket.getListeningPort())); + packetPosition += HifiSockAddr::packSockAddr(checkInPacket + (packetPosition - checkInPacket), + HifiSockAddr(_nodeSocket.localAddress(), _nodeSocket.localPort())); // add the number of bytes for node types of interest *(packetPosition++) = numBytesNodesOfInterest; @@ -567,9 +560,8 @@ void NodeList::sendDomainServerCheckIn() { packetPosition += numBytesNodesOfInterest; } - _nodeSocket.send(_domainIP.toString().toLocal8Bit().constData(), _domainPort, checkInPacket, - packetPosition - checkInPacket); - + _nodeSocket.writeDatagram((char*) checkInPacket, packetPosition - checkInPacket, + _domainSockAddr.getAddress(), _domainSockAddr.getPort()); const int NUM_DOMAIN_SERVER_CHECKINS_PER_STUN_REQUEST = 5; static unsigned int numDomainCheckins = 0; @@ -592,10 +584,8 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte char nodeType; // assumes only IPv4 addresses - sockaddr_in nodePublicSocket; - nodePublicSocket.sin_family = AF_INET; - sockaddr_in nodeLocalSocket; - nodeLocalSocket.sin_family = AF_INET; + HifiSockAddr nodePublicSocket; + HifiSockAddr nodeLocalSocket; unsigned char* readPtr = packetData + numBytesForPacketHeader(packetData); unsigned char* startPtr = packetData; @@ -605,24 +595,24 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte QUuid nodeUUID = QUuid::fromRfc4122(QByteArray((char*) readPtr, NUM_BYTES_RFC4122_UUID)); readPtr += NUM_BYTES_RFC4122_UUID; - readPtr += unpackSocket(readPtr, (sockaddr*) &nodePublicSocket); - readPtr += unpackSocket(readPtr, (sockaddr*) &nodeLocalSocket); + readPtr += HifiSockAddr::unpackSockAddr(readPtr, nodePublicSocket); + readPtr += HifiSockAddr::unpackSockAddr(readPtr, nodeLocalSocket); // if the public socket address is 0 then it's reachable at the same IP // as the domain server - if (nodePublicSocket.sin_addr.s_addr == 0) { - nodePublicSocket.sin_addr.s_addr = htonl(_domainIP.toIPv4Address()); + if (nodePublicSocket.getAddress().isNull()) { + nodePublicSocket.setAddress(_domainSockAddr.getAddress()); } - addOrUpdateNode(nodeUUID, nodeType, (sockaddr*) &nodePublicSocket, (sockaddr*) &nodeLocalSocket); + addOrUpdateNode(nodeUUID, nodeType, nodePublicSocket, nodeLocalSocket); } return readNodes; } -const sockaddr_in DEFAULT_LOCAL_ASSIGNMENT_SOCKET = socketForHostnameAndHostOrderPort(LOCAL_ASSIGNMENT_SERVER_HOSTNAME, - DEFAULT_DOMAIN_SERVER_PORT); +const HifiSockAddr DEFAULT_LOCAL_ASSIGNMENT_SOCKET = HifiSockAddr(QHostAddress(LOCAL_ASSIGNMENT_SERVER_HOSTNAME), + DEFAULT_DOMAIN_SERVER_PORT); void NodeList::sendAssignment(Assignment& assignment) { unsigned char assignmentPacket[MAX_PACKET_SIZE]; @@ -633,14 +623,16 @@ void NodeList::sendAssignment(Assignment& assignment) { int numHeaderBytes = populateTypeAndVersion(assignmentPacket, assignmentPacketType); int numAssignmentBytes = assignment.packToBuffer(assignmentPacket + numHeaderBytes); - sockaddr* assignmentServerSocket = (_assignmentServerSocket == NULL) - ? (sockaddr*) &DEFAULT_LOCAL_ASSIGNMENT_SOCKET - : _assignmentServerSocket; + const HifiSockAddr* assignmentServerSocket = _assignmentServerSocket.isNull() + ? &DEFAULT_LOCAL_ASSIGNMENT_SOCKET + : &_assignmentServerSocket; - _nodeSocket.send(assignmentServerSocket, assignmentPacket, numHeaderBytes + numAssignmentBytes); + _nodeSocket.writeDatagram((char*) assignmentPacket, numHeaderBytes + numAssignmentBytes, + assignmentServerSocket->getAddress(), + assignmentServerSocket->getPort()); } -void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) const { +void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) { uint64_t currentTime = 0; @@ -652,11 +644,14 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(Node* node) const { memcpy(pingPacket + numHeaderBytes, ¤tTime, sizeof(currentTime)); // send the ping packet to the local and public sockets for this node - _nodeSocket.send(node->getLocalSocket(), pingPacket, sizeof(pingPacket)); - _nodeSocket.send(node->getPublicSocket(), pingPacket, sizeof(pingPacket)); + _nodeSocket.writeDatagram((char*) pingPacket, sizeof(pingPacket), + node->getLocalSocket().getAddress(), node->getLocalSocket().getPort()); + _nodeSocket.writeDatagram((char*) pingPacket, sizeof(pingPacket), + node->getPublicSocket().getAddress(), node->getPublicSocket().getPort()); } -Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publicSocket, sockaddr* localSocket) { +Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, + const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket) { NodeList::iterator node = end(); for (node = begin(); node != end(); node++) { @@ -684,12 +679,12 @@ Node* NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publ } // check if we need to change this node's public or local sockets - if (!socketMatch(publicSocket, node->getPublicSocket())) { + if (publicSocket != node->getPublicSocket()) { node->setPublicSocket(publicSocket); qDebug() << "Public socket change for node" << *node << "\n"; } - if (!socketMatch(localSocket, node->getLocalSocket())) { + if (localSocket != node->getLocalSocket()) { node->setLocalSocket(localSocket); qDebug() << "Local socket change for node" << *node << "\n"; } @@ -725,7 +720,8 @@ unsigned NodeList::broadcastToNodes(unsigned char* broadcastData, size_t dataByt if (memchr(nodeTypes, node->getType(), numNodeTypes)) { if (getNodeActiveSocketOrPing(&(*node))) { // we know which socket is good for this node, send there - _nodeSocket.send(node->getActiveSocket(), broadcastData, dataBytes); + _nodeSocket.writeDatagram((char*) broadcastData, dataBytes, + node->getActiveSocket()->getAddress(), node->getActiveSocket()->getPort()); ++n; } } @@ -751,7 +747,7 @@ void NodeList::possiblyPingInactiveNodes() { } } -sockaddr* NodeList::getNodeActiveSocketOrPing(Node* node) { +const HifiSockAddr* NodeList::getNodeActiveSocketOrPing(Node* node) { if (node->getActiveSocket()) { return node->getActiveSocket(); } else { @@ -760,15 +756,15 @@ sockaddr* NodeList::getNodeActiveSocketOrPing(Node* node) { } } -void NodeList::activateSocketFromNodeCommunication(sockaddr *nodeAddress) { +void NodeList::activateSocketFromNodeCommunication(const HifiSockAddr& nodeAddress) { for(NodeList::iterator node = begin(); node != end(); node++) { if (!node->getActiveSocket()) { // check both the public and local addresses for each node to see if we find a match // prioritize the private address so that we prune erroneous local matches - if (socketMatch(node->getPublicSocket(), nodeAddress)) { + if (node->getPublicSocket() == nodeAddress) { node->activatePublicSocket(); break; - } else if (socketMatch(node->getLocalSocket(), nodeAddress)) { + } else if (node->getLocalSocket() == nodeAddress) { node->activateLocalSocket(); break; } @@ -969,7 +965,7 @@ void NodeListIterator::skipDeadAndStopIncrement() { void NodeList::addDomainListener(DomainChangeListener* listener) { _domainListeners.push_back(listener); - QString domain = _domainHostname.isEmpty() ? _domainIP.toString() : _domainHostname; + QString domain = _domainHostname.isEmpty() ? _domainSockAddr.getAddress().toString() : _domainHostname; listener->domainChanged(domain); } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 1e7b181cb0..7efc4b2682 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -15,11 +15,11 @@ #include #include +#include #include #include "Node.h" #include "NodeTypes.h" -#include "UDPSocket.h" #ifdef _WIN32 #include "pthread.h" @@ -45,6 +45,7 @@ const char LOCAL_ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5; class Assignment; +class HifiSockAddr; class NodeListIterator; // Callers who want to hook add/kill callbacks should implement this class @@ -75,19 +76,15 @@ public: const QString& getDomainHostname() const { return _domainHostname; } void setDomainHostname(const QString& domainHostname); - const QHostAddress& getDomainIP() const { return _domainIP; } - void setDomainIP(const QHostAddress& domainIP) { _domainIP = domainIP; } - void setDomainIPToLocalhost() { _domainIP = QHostAddress(INADDR_LOOPBACK); } + const QHostAddress& getDomainIP() const { return _domainSockAddr.getAddress(); } + void setDomainIPToLocalhost() { _domainSockAddr.setAddress(QHostAddress(INADDR_LOOPBACK)); } - unsigned short getDomainPort() const { return _domainPort; } - void setDomainPort(unsigned short domainPort) { _domainPort = domainPort; } + unsigned short getDomainPort() const { return _domainSockAddr.getPort(); } const QUuid& getOwnerUUID() const { return _ownerUUID; } void setOwnerUUID(const QUuid& ownerUUID) { _ownerUUID = ownerUUID; } - UDPSocket* getNodeSocket() { return &_nodeSocket; } - - unsigned short int getSocketListenPort() const { return _nodeSocket.getListeningPort(); } + QUdpSocket& getNodeSocket() { return _nodeSocket; } void(*linkedDataCreateCallback)(Node *); @@ -104,23 +101,23 @@ public: void sendDomainServerCheckIn(); int processDomainServerList(unsigned char *packetData, size_t dataBytes); - void setAssignmentServerSocket(sockaddr* serverSocket) { _assignmentServerSocket = serverSocket; } + void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } void sendAssignment(Assignment& assignment); - void pingPublicAndLocalSocketsForInactiveNode(Node* node) const; + void pingPublicAndLocalSocketsForInactiveNode(Node* node); void sendKillNode(const char* nodeTypes, int numNodeTypes); - Node* nodeWithAddress(sockaddr *senderAddress); + Node* nodeWithAddress(const HifiSockAddr& senderSockAddr); Node* nodeWithUUID(const QUuid& nodeUUID); - Node* addOrUpdateNode(const QUuid& uuid, char nodeType, sockaddr* publicSocket, sockaddr* localSocket); + Node* addOrUpdateNode(const QUuid& uuid, char nodeType, const HifiSockAddr& publicSocket, const HifiSockAddr& localSocket); void killNode(Node* node, bool mustLockNode = true); - void processNodeData(sockaddr *senderAddress, unsigned char *packetData, size_t dataBytes); - void processBulkNodeData(sockaddr *senderAddress, unsigned char *packetData, int numTotalBytes); + void processNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, size_t dataBytes); + void processBulkNodeData(const HifiSockAddr& senderSockAddr, unsigned char *packetData, int numTotalBytes); - int updateNodeWithData(Node *node, sockaddr* senderAddress, unsigned char *packetData, int dataBytes); + int updateNodeWithData(Node *node, const HifiSockAddr& senderSockAddr, unsigned char *packetData, int dataBytes); unsigned broadcastToNodes(unsigned char *broadcastData, size_t dataBytes, const char* nodeTypes, int numNodeTypes); @@ -143,7 +140,7 @@ public: void removeDomainListener(DomainChangeListener* listener); void possiblyPingInactiveNodes(); - sockaddr* getNodeActiveSocketOrPing(Node* node); + const HifiSockAddr* getNodeActiveSocketOrPing(Node* node); private: static NodeList* _sharedInstance; @@ -160,25 +157,23 @@ private: void processKillNode(unsigned char* packetData, size_t dataBytes); QString _domainHostname; - QHostAddress _domainIP; - unsigned short _domainPort; + HifiSockAddr _domainSockAddr; Node** _nodeBuckets[MAX_NUM_NODES / NODES_PER_BUCKET]; int _numNodes; - UDPSocket _nodeSocket; + QUdpSocket _nodeSocket; char _ownerType; char* _nodeTypesOfInterest; QUuid _ownerUUID; pthread_t removeSilentNodesThread; pthread_t checkInWithDomainServerThread; int _numNoReplyDomainCheckIns; - sockaddr* _assignmentServerSocket; - QHostAddress _publicAddress; - uint16_t _publicPort; + HifiSockAddr _assignmentServerSocket; + HifiSockAddr _publicSockAddr; bool _hasCompletedInitialSTUNFailure; unsigned int _stunRequestsSinceSuccess; - void activateSocketFromNodeCommunication(sockaddr *nodeAddress); - void timePingReply(sockaddr *nodeAddress, unsigned char *packetData); + void activateSocketFromNodeCommunication(const HifiSockAddr& nodeSockAddr); + void timePingReply(const HifiSockAddr& nodeAddress, unsigned char *packetData); std::vector _hooks; std::vector _domainListeners; diff --git a/libraries/shared/src/PacketSender.cpp b/libraries/shared/src/PacketSender.cpp index 3c0b0c80d8..f829a80ac0 100644 --- a/libraries/shared/src/PacketSender.cpp +++ b/libraries/shared/src/PacketSender.cpp @@ -44,7 +44,7 @@ PacketSender::PacketSender(PacketSenderNotify* notify, int packetsPerSecond) : } -void PacketSender::queuePacketForSending(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { +void PacketSender::queuePacketForSending(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength) { NetworkPacket packet(address, packetData, packetLength); lock(); _packets.push_back(packet); @@ -334,9 +334,9 @@ bool PacketSender::nonThreadedProcess() { unlock(); // send the packet through the NodeList... - UDPSocket* nodeSocket = NodeList::getInstance()->getNodeSocket(); - - nodeSocket->send(&temporary.getAddress(), temporary.getData(), temporary.getLength()); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) temporary.getData(), temporary.getLength(), + temporary.getSockAddr().getAddress(), + temporary.getSockAddr().getPort()); packetsSentThisCall++; _packetsOverCheckInterval++; _totalPacketsSent++; diff --git a/libraries/shared/src/PacketSender.h b/libraries/shared/src/PacketSender.h index 1731f70cbf..b05e42d11b 100644 --- a/libraries/shared/src/PacketSender.h +++ b/libraries/shared/src/PacketSender.h @@ -38,11 +38,11 @@ public: PacketSender(PacketSenderNotify* notify = NULL, int packetsPerSecond = DEFAULT_PACKETS_PER_SECOND); /// Add packet to outbound queue. - /// \param sockaddr& address the destination address + /// \param HifiSockAddr& address the destination address /// \param packetData pointer to data /// \param ssize_t packetLength size of data /// \thread any thread, typically the application thread - void queuePacketForSending(sockaddr& address, unsigned char* packetData, ssize_t packetLength); + void queuePacketForSending(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength); void setPacketsPerSecond(int packetsPerSecond) { _packetsPerSecond = std::max(MINIMUM_PACKETS_PER_SECOND, packetsPerSecond); } diff --git a/libraries/shared/src/ReceivedPacketProcessor.cpp b/libraries/shared/src/ReceivedPacketProcessor.cpp index a46cd36dbe..4ad869460e 100644 --- a/libraries/shared/src/ReceivedPacketProcessor.cpp +++ b/libraries/shared/src/ReceivedPacketProcessor.cpp @@ -16,9 +16,9 @@ ReceivedPacketProcessor::ReceivedPacketProcessor() { _dontSleep = false; } -void ReceivedPacketProcessor::queueReceivedPacket(sockaddr& address, unsigned char* packetData, ssize_t packetLength) { +void ReceivedPacketProcessor::queueReceivedPacket(const HifiSockAddr& address, unsigned char* packetData, ssize_t packetLength) { // Make sure our Node and NodeList knows we've heard from this node. - Node* node = NodeList::getInstance()->nodeWithAddress(&address); + Node* node = NodeList::getInstance()->nodeWithAddress(address); if (node) { node->setLastHeardMicrostamp(usecTimestampNow()); } @@ -44,7 +44,7 @@ bool ReceivedPacketProcessor::process() { NetworkPacket temporary = packet; // make a copy of the packet in case the vector is resized on us _packets.erase(_packets.begin()); // remove the oldest packet unlock(); // let others add to the packets - processPacket(temporary.getAddress(), temporary.getData(), temporary.getLength()); // process our temporary copy + processPacket(temporary.getSockAddr(), temporary.getData(), temporary.getLength()); // process our temporary copy } return isStillRunning(); // keep running till they terminate us } diff --git a/libraries/shared/src/ReceivedPacketProcessor.h b/libraries/shared/src/ReceivedPacketProcessor.h index f36473ae12..621204025e 100644 --- a/libraries/shared/src/ReceivedPacketProcessor.h +++ b/libraries/shared/src/ReceivedPacketProcessor.h @@ -24,7 +24,7 @@ public: /// \param packetData pointer to received data /// \param ssize_t packetLength size of received data /// \thread network receive thread - void queueReceivedPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + void queueReceivedPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength); /// Are there received packets waiting to be processed bool hasPacketsToProcess() const { return _packets.size() > 0; } @@ -38,7 +38,7 @@ protected: /// \param packetData pointer to received data /// \param ssize_t packetLength size of received data /// \thread "this" individual processing thread - virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) = 0; + virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) = 0; /// Implements generic processing behavior for this thread. virtual bool process(); diff --git a/libraries/shared/src/UDPSocket.cpp b/libraries/shared/src/UDPSocket.cpp deleted file mode 100644 index 1318fbc4a5..0000000000 --- a/libraries/shared/src/UDPSocket.cpp +++ /dev/null @@ -1,293 +0,0 @@ -// -// UDPSocket.cpp -// interface -// -// Created by Stephen Birarda on 1/28/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#include -#include -#include -#include -#include - -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include -#include -#include -#include -#endif - -#include -#include -#include - -#include "Logging.h" -#include "UDPSocket.h" - -sockaddr_in destSockaddr, senderAddress; - -bool socketMatch(const sockaddr* first, const sockaddr* second) { - if (first != NULL && second != NULL) { - // utility function that indicates if two sockets are equivalent - - // currently only compares two IPv4 addresses - // expandable to IPv6 by adding else if for AF_INET6 - - if (first->sa_family != second->sa_family) { - // not the same family, can't be equal - return false; - } else if (first->sa_family == AF_INET) { - const sockaddr_in *firstIn = (const sockaddr_in *) first; - const sockaddr_in *secondIn = (const sockaddr_in *) second; - - return firstIn->sin_addr.s_addr == secondIn->sin_addr.s_addr - && firstIn->sin_port == secondIn->sin_port; - } else { - return false; - } - } else { - return false; - } -} - -int packSocket(unsigned char* packStore, in_addr_t inAddress, in_port_t networkOrderPort) { - packStore[0] = inAddress >> 24; - packStore[1] = inAddress >> 16; - packStore[2] = inAddress >> 8; - packStore[3] = inAddress; - - packStore[4] = networkOrderPort >> 8; - packStore[5] = networkOrderPort; - - return 6; // could be dynamically more if we need IPv6 -} - -int packSocket(unsigned char* packStore, sockaddr* socketToPack) { - return packSocket(packStore, ((sockaddr_in*) socketToPack)->sin_addr.s_addr, ((sockaddr_in*) socketToPack)->sin_port); -} - -int unpackSocket(const unsigned char* packedData, sockaddr* unpackDestSocket) { - sockaddr_in* destinationSocket = (sockaddr_in*) unpackDestSocket; - destinationSocket->sin_family = AF_INET; - destinationSocket->sin_addr.s_addr = (packedData[0] << 24) + (packedData[1] << 16) + (packedData[2] << 8) + packedData[3]; - destinationSocket->sin_port = (packedData[4] << 8) + packedData[5]; - return 6; // this could be more if we ever need IPv6 -} - -void copySocketToEmptySocketPointer(sockaddr** destination, const sockaddr* source) { - // create a new sockaddr or sockaddr_in depending on what type of address this is - if (source->sa_family == AF_INET) { - *destination = (sockaddr*) new sockaddr_in; - memcpy(*destination, source, sizeof(sockaddr_in)); - } else { - *destination = (sockaddr*) new sockaddr_in6; - memcpy(*destination, source, sizeof(sockaddr_in6)); - } -} - -int getLocalAddress() { - - static int localAddress = 0; - - if (localAddress == 0) { - foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()) { - if (interface.flags() & QNetworkInterface::IsUp - && interface.flags() & QNetworkInterface::IsRunning - && interface.flags() & ~QNetworkInterface::IsLoopBack) { - // we've decided that this is the active NIC - // enumerate it's addresses to grab the IPv4 address - foreach(const QNetworkAddressEntry &entry, interface.addressEntries()) { - // make sure it's an IPv4 address that isn't the loopback - if (entry.ip().protocol() == QAbstractSocket::IPv4Protocol && !entry.ip().isLoopback()) { - qDebug("Node's local address is %s\n", entry.ip().toString().toLocal8Bit().constData()); - - // set our localAddress and break out - localAddress = htonl(entry.ip().toIPv4Address()); - break; - } - } - } - - if (localAddress != 0) { - break; - } - } - } - - // return the looked up local address - return localAddress; -} - -unsigned short loadBufferWithSocketInfo(char* addressBuffer, sockaddr* socket) { - if (socket != NULL) { - char* copyBuffer = inet_ntoa(((sockaddr_in*) socket)->sin_addr); - memcpy(addressBuffer, copyBuffer, strlen(copyBuffer)); - return htons(((sockaddr_in*) socket)->sin_port); - } else { - const char* unknownAddress = "Unknown"; - memcpy(addressBuffer, unknownAddress, strlen(unknownAddress)); - return 0; - } -} - -sockaddr_in socketForHostnameAndHostOrderPort(const char* hostname, unsigned short port) { - struct hostent* pHostInfo; - sockaddr_in newSocket = {}; - - if ((pHostInfo = gethostbyname(hostname))) { - memcpy(&newSocket.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length); - } - - if (port != 0) { - newSocket.sin_port = htons(port); - } - - return newSocket; -} - -UDPSocket::UDPSocket(unsigned short int listeningPort) : - _listeningPort(listeningPort), - blocking(true) -{ - init(); - // create the socket - handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - - if (handle <= 0) { - qDebug("Failed to create socket.\n"); - return; - } - - destSockaddr.sin_family = AF_INET; - - // bind the socket to the passed listeningPort - sockaddr_in bind_address; - bind_address.sin_family = AF_INET; - bind_address.sin_addr.s_addr = INADDR_ANY; - bind_address.sin_port = htons((uint16_t) _listeningPort); - - if (bind(handle, (const sockaddr*) &bind_address, sizeof(sockaddr_in)) < 0) { - qDebug("Failed to bind socket to port %hu.\n", _listeningPort); - return; - } - - // if we requested an ephemeral port, get the actual port - if (listeningPort == 0) { - socklen_t addressLength = sizeof(sockaddr_in); - getsockname(handle, (sockaddr*) &bind_address, &addressLength); - _listeningPort = ntohs(bind_address.sin_port); - } - - const int DEFAULT_BLOCKING_SOCKET_TIMEOUT_USECS = 0.5 * 1000000; - setBlockingReceiveTimeoutInUsecs(DEFAULT_BLOCKING_SOCKET_TIMEOUT_USECS); - - qDebug("Created UDP Socket listening on %hd\n", _listeningPort); -} - -UDPSocket::~UDPSocket() { -#ifdef _WIN32 - closesocket(handle); -#else - close(handle); -#endif -} - -bool UDPSocket::init() { -#ifdef _WIN32 - WORD wVersionRequested; - WSADATA wsaData; - int err; - - wVersionRequested = MAKEWORD( 2, 2 ); - - err = WSAStartup( wVersionRequested, &wsaData ); - if ( err != 0 ) { - /* Tell the user that we could not find a usable */ - /* WinSock DLL. */ - return false; - } - - /* Confirm that the WinSock DLL supports 2.2.*/ - /* Note that if the DLL supports versions later */ - /* than 2.2 in addition to 2.2, it will still return */ - /* 2.2 in wVersion since that is the version we */ - /* requested. */ - - if ( LOBYTE( wsaData.wVersion ) != 2 || - HIBYTE( wsaData.wVersion ) != 2 ) { - /* Tell the user that we could not find a usable */ - /* WinSock DLL. */ - WSACleanup(); - return false; - } -#endif - return true; -} - -void UDPSocket::setBlocking(bool blocking) { - this->blocking = blocking; - -#ifdef _WIN32 - u_long mode = blocking ? 0 : 1; - ioctlsocket(handle, FIONBIO, &mode); -#else - int flags = fcntl(handle, F_GETFL, 0); - fcntl(handle, F_SETFL, blocking ? (flags & ~O_NONBLOCK) : (flags | O_NONBLOCK)); -#endif -} - -void UDPSocket::setBlockingReceiveTimeoutInUsecs(int timeoutUsecs) { - struct timeval tv = {timeoutUsecs / 1000000, timeoutUsecs % 1000000}; - setsockopt(handle, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv)); -} - -// Receive data on this socket with retrieving address of sender -bool UDPSocket::receive(void* receivedData, ssize_t* receivedBytes) const { - return receive((sockaddr*) &senderAddress, receivedData, receivedBytes); -} - -// Receive data on this socket with the address of the sender -bool UDPSocket::receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const { - -#ifdef _WIN32 - int addressSize = sizeof(*recvAddress); -#else - socklen_t addressSize = sizeof(*recvAddress); -#endif - *receivedBytes = recvfrom(handle, static_cast(receivedData), MAX_BUFFER_LENGTH_BYTES, - 0, recvAddress, &addressSize); - - return (*receivedBytes > 0); -} - -int UDPSocket::send(sockaddr* destAddress, const void* data, size_t byteLength) const { - if (destAddress) { - // send data via UDP - int sent_bytes = sendto(handle, (const char*)data, byteLength, - 0, (sockaddr *) destAddress, sizeof(sockaddr_in)); - - if (sent_bytes != byteLength) { - qDebug("Failed to send packet: %s\n", strerror(errno)); - return false; - } - - return sent_bytes; - } else { - qDebug("UDPSocket send called with NULL destination address - Likely a node with no active socket.\n"); - return 0; - } - -} - -int UDPSocket::send(const char* destAddress, int destPort, const void* data, size_t byteLength) const { - - // change address and port on reusable global to passed variables - destSockaddr.sin_addr.s_addr = inet_addr(destAddress); - destSockaddr.sin_port = htons((uint16_t)destPort); - - return send((sockaddr *)&destSockaddr, data, byteLength); -} diff --git a/libraries/shared/src/UDPSocket.h b/libraries/shared/src/UDPSocket.h deleted file mode 100644 index b177fd4e30..0000000000 --- a/libraries/shared/src/UDPSocket.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// UDPSocket.h -// interface -// -// Created by Stephen Birarda on 1/28/13. -// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. -// - -#ifndef __interface__UDPSocket__ -#define __interface__UDPSocket__ - -#ifdef _WIN32 -#include "Syssocket.h" -#else -#include -#include -#endif - -#define MAX_BUFFER_LENGTH_BYTES 1500 - -class UDPSocket { -public: - UDPSocket(unsigned short int listeningPort); - ~UDPSocket(); - - bool init(); - unsigned short int getListeningPort() const { return _listeningPort; } - - void setBlocking(bool blocking); - bool isBlocking() const { return blocking; } - void setBlockingReceiveTimeoutInUsecs(int timeoutUsecs); - - int send(sockaddr* destAddress, const void* data, size_t byteLength) const; - int send(const char* destAddress, int destPort, const void* data, size_t byteLength) const; - - bool receive(void* receivedData, ssize_t* receivedBytes) const; - bool receive(sockaddr* recvAddress, void* receivedData, ssize_t* receivedBytes) const; -private: - int handle; - unsigned short int _listeningPort; - bool blocking; -}; - -bool socketMatch(const sockaddr* first, const sockaddr* second); -int packSocket(unsigned char* packStore, in_addr_t inAddress, in_port_t networkOrderPort); -int packSocket(unsigned char* packStore, sockaddr* socketToPack); -int unpackSocket(const unsigned char* packedData, sockaddr* unpackDestSocket); -void copySocketToEmptySocketPointer(sockaddr** destination, const sockaddr* source); -int getLocalAddress(); -unsigned short loadBufferWithSocketInfo(char* addressBuffer, sockaddr* socket); -sockaddr_in socketForHostnameAndHostOrderPort(const char* hostname, unsigned short port = 0); - -#endif /* defined(__interface__UDPSocket__) */ diff --git a/libraries/voxel-server-library/src/VoxelSendThread.cpp b/libraries/voxel-server-library/src/VoxelSendThread.cpp index fe2842d6d7..7e0e9551b9 100644 --- a/libraries/voxel-server-library/src/VoxelSendThread.cpp +++ b/libraries/voxel-server-library/src/VoxelSendThread.cpp @@ -103,22 +103,28 @@ int VoxelSendThread::handlePacketSend(Node* node, VoxelNodeData* nodeData, int& statsMessageLength += nodeData->getPacketLength(); // actually send it - NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) statsMessage, statsMessageLength, + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); } else { // not enough room in the packet, send two packets - NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), statsMessage, statsMessageLength); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) statsMessage, statsMessageLength, + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); trueBytesSent += statsMessageLength; truePacketsSent++; packetsSent++; - NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), - nodeData->getPacket(), nodeData->getPacketLength()); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(), + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); } nodeData->stats.markAsSent(); } else { // just send the voxel packet - NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), - nodeData->getPacket(), nodeData->getPacketLength()); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) nodeData->getPacket(), nodeData->getPacketLength(), + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); } // remember to track our stats nodeData->stats.packetSent(nodeData->getPacketLength()); @@ -335,7 +341,9 @@ int VoxelSendThread::deepestLevelVoxelDistributor(Node* node, VoxelNodeData* nod envPacketLength += _myServer->getEnvironmentData(i)->getBroadcastData(_tempOutputBuffer + envPacketLength); } - NodeList::getInstance()->getNodeSocket()->send(node->getActiveSocket(), _tempOutputBuffer, envPacketLength); + NodeList::getInstance()->getNodeSocket().writeDatagram((char*) _tempOutputBuffer, envPacketLength, + node->getActiveSocket()->getAddress(), + node->getActiveSocket()->getPort()); trueBytesSent += envPacketLength; truePacketsSent++; packetsSentThisInterval++; diff --git a/libraries/voxel-server-library/src/VoxelServer.cpp b/libraries/voxel-server-library/src/VoxelServer.cpp index cf650117f2..4be9183cb9 100644 --- a/libraries/voxel-server-library/src/VoxelServer.cpp +++ b/libraries/voxel-server-library/src/VoxelServer.cpp @@ -618,7 +618,7 @@ void VoxelServer::run() { qDebug("packetsPerSecond=%s PACKETS_PER_CLIENT_PER_INTERVAL=%d\n", packetsPerSecond, _packetsPerClientPerInterval); } - sockaddr senderAddress; + HifiSockAddr senderSockAddr; unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; ssize_t packetLength; @@ -668,7 +668,9 @@ void VoxelServer::run() { // ping our inactive nodes to punch holes with them nodeList->possiblyPingInactiveNodes(); - if (nodeList->getNodeSocket()->receive(&senderAddress, packetData, &packetLength) && + if ((packetLength = nodeList->getNodeSocket().readDatagram((char*) packetData, MAX_PACKET_SIZE, + senderSockAddr.getAddressPointer(), + senderSockAddr.getPortPointer())) && packetVersionMatch(packetData)) { int numBytesPacketHeader = numBytesForPacketHeader(packetData); @@ -682,7 +684,7 @@ void VoxelServer::run() { Node* node = nodeList->nodeWithUUID(nodeUUID); if (node) { - nodeList->updateNodeWithData(node, &senderAddress, packetData, packetLength); + nodeList->updateNodeWithData(node, senderSockAddr, packetData, packetLength); if (!node->getActiveSocket()) { // we don't have an active socket for this node, but they're talking to us // this means they've heard from us and can reply, let's assume public is active @@ -695,7 +697,7 @@ void VoxelServer::run() { } } else if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { if (_jurisdictionSender) { - _jurisdictionSender->queueReceivedPacket(senderAddress, packetData, packetLength); + _jurisdictionSender->queueReceivedPacket(senderSockAddr, packetData, packetLength); } } else if (_voxelServerPacketProcessor && (packetData[0] == PACKET_TYPE_SET_VOXEL @@ -730,10 +732,10 @@ void VoxelServer::run() { } } - _voxelServerPacketProcessor->queueReceivedPacket(senderAddress, packetData, packetLength); + _voxelServerPacketProcessor->queueReceivedPacket(senderSockAddr, packetData, packetLength); } else { // let processNodeData handle it. - NodeList::getInstance()->processNodeData(&senderAddress, packetData, packetLength); + NodeList::getInstance()->processNodeData(senderSockAddr, packetData, packetLength); } } } diff --git a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp index 2581c923f5..46cea75212 100644 --- a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp +++ b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.cpp @@ -39,7 +39,8 @@ void VoxelServerPacketProcessor::resetStats() { } -void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { +void VoxelServerPacketProcessor::processPacket(const HifiSockAddr& senderSockAddr, + unsigned char* packetData, ssize_t packetLength) { bool debugProcessPacket = _myServer->wantsVerboseDebug(); @@ -135,7 +136,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned } // Make sure our Node and NodeList knows we've heard from this node. - Node* senderNode = NodeList::getInstance()->nodeWithAddress(&senderAddress); + Node* senderNode = NodeList::getInstance()->nodeWithAddress(senderSockAddr); QUuid& nodeUUID = DEFAULT_NODE_ID_REF; if (senderNode) { senderNode->setLastHeardMicrostamp(usecTimestampNow()); @@ -170,7 +171,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned _myServer->getServerTree().unlock(); // Make sure our Node and NodeList knows we've heard from this node. - Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + Node* node = NodeList::getInstance()->nodeWithAddress(senderSockAddr); if (node) { node->setLastHeardMicrostamp(usecTimestampNow()); } @@ -199,7 +200,7 @@ void VoxelServerPacketProcessor::processPacket(sockaddr& senderAddress, unsigned } // Make sure our Node and NodeList knows we've heard from this node. - Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + Node* node = NodeList::getInstance()->nodeWithAddress(senderSockAddr); if (node) { node->setLastHeardMicrostamp(usecTimestampNow()); } diff --git a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h index 2408e0dd60..4abdbad284 100644 --- a/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h +++ b/libraries/voxel-server-library/src/VoxelServerPacketProcessor.h @@ -63,7 +63,7 @@ public: NodeToSenderStatsMap& getSingleSenderStats() { return _singleSenderStats; } protected: - virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + virtual void processPacket(const HifiSockAddr& senderSockAddr, unsigned char* packetData, ssize_t packetLength); private: void trackInboundPackets(const QUuid& nodeUUID, int sequence, uint64_t transitTime, diff --git a/libraries/voxels/src/JurisdictionListener.cpp b/libraries/voxels/src/JurisdictionListener.cpp index 223b602dfa..3213e11940 100644 --- a/libraries/voxels/src/JurisdictionListener.cpp +++ b/libraries/voxels/src/JurisdictionListener.cpp @@ -48,7 +48,7 @@ bool JurisdictionListener::queueJurisdictionRequest() { NodeList* nodeList = NodeList::getInstance(); for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { if (nodeList->getNodeActiveSocketOrPing(&(*node)) && node->getType() == NODE_TYPE_VOXEL_SERVER) { - sockaddr* nodeAddress = node->getActiveSocket(); + const HifiSockAddr* nodeAddress = node->getActiveSocket(); PacketSender::queuePacketForSending(*nodeAddress, bufferOut, sizeOut); nodeCount++; } @@ -64,9 +64,9 @@ bool JurisdictionListener::queueJurisdictionRequest() { return isStillRunning(); } -void JurisdictionListener::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { +void JurisdictionListener::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION) { - Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress); if (node) { QUuid nodeUUID = node->getUUID(); JurisdictionMap map; diff --git a/libraries/voxels/src/JurisdictionListener.h b/libraries/voxels/src/JurisdictionListener.h index 7376c9196f..a05601169b 100644 --- a/libraries/voxels/src/JurisdictionListener.h +++ b/libraries/voxels/src/JurisdictionListener.h @@ -45,7 +45,7 @@ protected: /// \param packetData pointer to received data /// \param ssize_t packetLength size of received data /// \thread "this" individual processing thread - virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength); private: NodeToJurisdictionMap _jurisdictions; diff --git a/libraries/voxels/src/JurisdictionSender.cpp b/libraries/voxels/src/JurisdictionSender.cpp index 3d3a3bec6f..9bb729f66a 100644 --- a/libraries/voxels/src/JurisdictionSender.cpp +++ b/libraries/voxels/src/JurisdictionSender.cpp @@ -29,9 +29,9 @@ JurisdictionSender::~JurisdictionSender() { } -void JurisdictionSender::processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { +void JurisdictionSender::processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength) { if (packetData[0] == PACKET_TYPE_VOXEL_JURISDICTION_REQUEST) { - Node* node = NodeList::getInstance()->nodeWithAddress(&senderAddress); + Node* node = NodeList::getInstance()->nodeWithAddress(senderAddress); if (node) { QUuid nodeUUID = node->getUUID(); lockRequestingNodes(); @@ -66,7 +66,7 @@ bool JurisdictionSender::process() { Node* node = NodeList::getInstance()->nodeWithUUID(nodeUUID); if (node->getActiveSocket() != NULL) { - sockaddr* nodeAddress = node->getActiveSocket(); + const HifiSockAddr* nodeAddress = node->getActiveSocket(); queuePacketForSending(*nodeAddress, bufferOut, sizeOut); nodeCount++; } diff --git a/libraries/voxels/src/JurisdictionSender.h b/libraries/voxels/src/JurisdictionSender.h index f223621b87..9a7ea3c760 100644 --- a/libraries/voxels/src/JurisdictionSender.h +++ b/libraries/voxels/src/JurisdictionSender.h @@ -32,7 +32,7 @@ public: virtual bool process(); protected: - virtual void processPacket(sockaddr& senderAddress, unsigned char* packetData, ssize_t packetLength); + virtual void processPacket(const HifiSockAddr& senderAddress, unsigned char* packetData, ssize_t packetLength); /// Locks all the resources of the thread. void lockRequestingNodes() { pthread_mutex_lock(&_requestingNodeMutex); } diff --git a/libraries/voxels/src/VoxelEditPacketSender.cpp b/libraries/voxels/src/VoxelEditPacketSender.cpp index ec7ea3810b..bfc42da63f 100644 --- a/libraries/voxels/src/VoxelEditPacketSender.cpp +++ b/libraries/voxels/src/VoxelEditPacketSender.cpp @@ -123,7 +123,7 @@ void VoxelEditPacketSender::queuePacketToNode(const QUuid& nodeUUID, unsigned ch if (node->getType() == NODE_TYPE_VOXEL_SERVER && ((node->getUUID() == nodeUUID) || (nodeUUID.isNull()))) { if (nodeList->getNodeActiveSocketOrPing(&(*node))) { - sockaddr* nodeAddress = node->getActiveSocket(); + const HifiSockAddr* nodeAddress = node->getActiveSocket(); queuePacketForSending(*nodeAddress, buffer, length); // debugging output... diff --git a/pairing-server/CMakeLists.txt b/pairing-server/CMakeLists.txt index 5e0adcb378..b1fbdf82dc 100644 --- a/pairing-server/CMakeLists.txt +++ b/pairing-server/CMakeLists.txt @@ -5,9 +5,13 @@ set(MACRO_DIR ${ROOT_DIR}/cmake/macros) set(TARGET_NAME pairing-server) +find_package(Qt5Network REQUIRED) + include(${MACRO_DIR}/SetupHifiProject.cmake) setup_hifi_project(${TARGET_NAME} TRUE) +qt5_use_modules(${TARGET_NAME} Network) + # link the shared hifi library include(${MACRO_DIR}/LinkHifiLibrary.cmake) link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/pairing-server/src/main.cpp b/pairing-server/src/main.cpp index 0422251403..4efff8f588 100644 --- a/pairing-server/src/main.cpp +++ b/pairing-server/src/main.cpp @@ -11,17 +11,20 @@ #include #include -#include #include +#include + +#include + const int PAIRING_SERVER_LISTEN_PORT = 7247; const int MAX_PACKET_SIZE_BYTES = 1400; struct PairableDevice { char identifier[64]; char name[64]; - sockaddr_in sendingSocket; - sockaddr_in localSocket; + HifiSockAddr sendingSocket; + HifiSockAddr localSocket; }; struct RequestingClient { @@ -29,7 +32,7 @@ struct RequestingClient { int port; }; -UDPSocket serverSocket(PAIRING_SERVER_LISTEN_PORT); +QUdpSocket serverSocket; PairableDevice* lastDevice = NULL; RequestingClient* lastClient = NULL; @@ -47,17 +50,20 @@ void sendLastClientToLastDevice() { char pairData[INET_ADDRSTRLEN + 6] = {}; int bytesWritten = sprintf(pairData, "%s:%d", ::lastClient->address, ::lastClient->port); - ::serverSocket.send((sockaddr*) &::lastDevice->sendingSocket, pairData, bytesWritten); + ::serverSocket.writeDatagram(pairData, bytesWritten, + ::lastDevice->sendingSocket.getAddress(), ::lastDevice->sendingSocket.getPort()); } int main(int argc, const char* argv[]) { - sockaddr_in senderSocket; + serverSocket.bind(QHostAddress::LocalHost, PAIRING_SERVER_LISTEN_PORT); + + HifiSockAddr senderSockAddr; char senderData[MAX_PACKET_SIZE_BYTES] = {}; - ssize_t receivedBytes = 0; while (true) { - if (::serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) { + if (::serverSocket.readDatagram(senderData, MAX_PACKET_SIZE_BYTES, + senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer())) { if (senderData[0] == 'A') { // this is a device reporting itself as available @@ -76,12 +82,11 @@ int main(int argc, const char* argv[]) { // if we have fewer than 3 matches the packet wasn't properly formatted // setup the localSocket for the pairing device - tempDevice.localSocket.sin_family = AF_INET; - inet_pton(AF_INET, deviceAddress, &::lastDevice); - tempDevice.localSocket.sin_port = socketPort; + tempDevice.localSocket.setAddress(QHostAddress(deviceAddress)); + tempDevice.localSocket.setPort(socketPort); // store this device's sending socket so we can talk back to it - tempDevice.sendingSocket = senderSocket; + tempDevice.sendingSocket = senderSockAddr; // push this new device into the vector printf("New last device is %s (%s) at %s:%d\n", diff --git a/space-server/CMakeLists.txt b/space-server/CMakeLists.txt deleted file mode 100644 index c821992378..0000000000 --- a/space-server/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -cmake_minimum_required(VERSION 2.8) - -set(ROOT_DIR ..) -set(MACRO_DIR ${ROOT_DIR}/cmake/macros) - -set(TARGET_NAME space-server) - -include(${MACRO_DIR}/SetupHifiProject.cmake) - -setup_hifi_project(${TARGET_NAME} TRUE) - -include(${MACRO_DIR}/LinkHifiLibrary.cmake) -link_hifi_library(shared ${TARGET_NAME} ${ROOT_DIR}) \ No newline at end of file diff --git a/space-server/example.data.txt b/space-server/example.data.txt deleted file mode 100644 index 065017c308..0000000000 --- a/space-server/example.data.txt +++ /dev/null @@ -1,2 +0,0 @@ -0 00000100001011101110 domain4.highfidelity.co domain4 -0 00000100110100010001 domain3.highfidelity.co domain3 diff --git a/space-server/src/TreeNode.cpp b/space-server/src/TreeNode.cpp deleted file mode 100644 index 7326b2db0d..0000000000 --- a/space-server/src/TreeNode.cpp +++ /dev/null @@ -1,20 +0,0 @@ -// -// TreeNode.cpp -// hifi -// -// Created by Stephen Birarda on 2/13/13. -// -// - -#include "TreeNode.h" - -std::string EMPTY_STRING = ""; - -TreeNode::TreeNode() { - for (int i = 0; i < CHILDREN_PER_NODE; ++i) { - child[i] = NULL; - } - - hostname = NULL; - nickname = NULL; -} \ No newline at end of file diff --git a/space-server/src/TreeNode.h b/space-server/src/TreeNode.h deleted file mode 100644 index ad766d953f..0000000000 --- a/space-server/src/TreeNode.h +++ /dev/null @@ -1,26 +0,0 @@ -// -// TreeNode.h -// hifi -// -// Created by Stephen Birarda on 2/13/13. -// -// - -#ifndef __hifi__TreeNode__ -#define __hifi__TreeNode__ - -#include - -const int CHILDREN_PER_NODE = 8; - -class TreeNode { -public: - TreeNode(); - - TreeNode *child[CHILDREN_PER_NODE]; - char *hostname; - char *nickname; - int domain_id; -}; - -#endif /* defined(__hifi__TreeNode__) */ diff --git a/space-server/src/main.cpp b/space-server/src/main.cpp deleted file mode 100644 index 24d73da9c1..0000000000 --- a/space-server/src/main.cpp +++ /dev/null @@ -1,160 +0,0 @@ -// -// main.cpp -// space -// -// Created by Leonardo Murillo on 2/6/13. -// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. -// - -#include -#include -#include -#include - -#include "TreeNode.h" -#include "UDPSocket.h" - -const char *CONFIG_FILE = "/Users/birarda/code/worklist/checkouts/hifi/space/example.data.txt"; -const unsigned short SPACE_LISTENING_PORT = 55551; -const short MAX_NAME_LENGTH = 255; - -const char ROOT_HOSTNAME[] = "root.highfidelity.co"; -const char ROOT_NICKNAME[] = "root"; - -const size_t PACKET_LENGTH_BYTES = 1024; - -sockaddr_in destAddress; -socklen_t destLength = sizeof(destAddress); - -char *lastKnownHostname; - -TreeNode rootNode; -UDPSocket spaceSocket(SPACE_LISTENING_PORT); - -TreeNode *findOrCreateNode(int lengthInBits, - unsigned char *addressBytes, - char *hostname, - char *nickname, - int domainID) { - - TreeNode *currentNode = &rootNode; - - for (int i = 0; i < lengthInBits; i += 3) { - unsigned char octet; - - if (i%8 < 6) { - octet = addressBytes[i/8] << i%8 >> (5); - } else { - octet = (addressBytes[i/8] << i >> (11 - i)) | (addressBytes[i/8 + 1] >> (11 - i + 2)); - } - - if (currentNode->child[octet] == NULL) { - currentNode->child[octet] = new TreeNode; - } else if (currentNode->child[octet]->hostname != NULL) { - lastKnownHostname = currentNode->child[octet]->hostname; - } - - currentNode = currentNode->child[octet]; - } - - if (currentNode->hostname == NULL) { - currentNode->hostname = hostname; - currentNode->nickname = nickname; - } - - return currentNode; -}; - -bool loadSpaceData(void) { - FILE *configFile = std::fopen(CONFIG_FILE, "r"); - char formatString[10]; - - if (configFile == NULL) { - std::cout << "Unable to load config file!\n"; - return false; - } else { - char *lengthBitString = new char[8]; - int itemsRead = 0; - - while ((itemsRead = fscanf(configFile, "0 %8c", lengthBitString)) > 0) { - - // calculate the number of bits in the address and bits required for padding - unsigned long threeBitCodes = strtoul(lengthBitString, NULL, 2); - int bitsInAddress = threeBitCodes * 3; - int paddingBits = 8 - (bitsInAddress % 8); - int addressByteLength = (bitsInAddress + paddingBits) / 8; - - // create an unsigned char * to hold the padded address - unsigned char *paddedAddress = new unsigned char[addressByteLength]; - - char *fullByteBitString = new char[8]; - - for (int c = 0; c < addressByteLength; c++) { - if (c + 1 == addressByteLength && paddingBits > 0) { - // this is the last byte, and we need some padding bits - // pull as many bits as are left - int goodBits = 8 - paddingBits; - sprintf(formatString, "%%%dc", goodBits); - itemsRead = fscanf(configFile, formatString, fullByteBitString); - - // fill out the rest with zeros - memset(fullByteBitString + goodBits, '0', paddingBits); - } else { - // pull 8 bits (which will be one byte) from the file - itemsRead = fscanf(configFile, "%8c", fullByteBitString); - } - - // set the corresponding value in the unsigned char array - *(paddedAddress + c) = strtoul(fullByteBitString, NULL, 2); - } - - char *nodeHostname = new char[MAX_NAME_LENGTH]; - char *nodeNickname = new char[MAX_NAME_LENGTH]; - itemsRead = fscanf(configFile, "%s %s\n", nodeHostname, nodeNickname); - - findOrCreateNode(bitsInAddress, paddedAddress, nodeHostname, nodeNickname, 0); - } - - std::fclose(configFile); - - return true; - } -} - -int main (int argc, const char *argv[]) { - - setvbuf(stdout, NULL, _IOLBF, 0); - - unsigned char packetData[PACKET_LENGTH_BYTES]; - ssize_t receivedBytes = 0; - - rootNode.hostname = new char[MAX_NAME_LENGTH]; - rootNode.nickname = new char[MAX_NAME_LENGTH]; - - strcpy(rootNode.hostname, ROOT_HOSTNAME); - strcpy(rootNode.nickname, ROOT_NICKNAME); - - loadSpaceData(); - - std::cout << "[DEBUG] Listening for Datagrams" << std::endl; - - while (true) { - if (spaceSocket.receive((sockaddr *)&destAddress, &packetData, &receivedBytes)) { - unsigned long lengthInBits; - lengthInBits = packetData[0] * 3; - - unsigned char addressData[sizeof(packetData)-1]; - for (int i = 0; i < sizeof(packetData)-1; ++i) { - addressData[i] = packetData[i+1]; - } - - TreeNode *thisNode = findOrCreateNode(lengthInBits, addressData, NULL, NULL, 0); - char *hostnameToSend = (thisNode->hostname == NULL) - ? lastKnownHostname - : thisNode->hostname; - - spaceSocket.send((sockaddr *)&destAddress, &hostnameToSend, sizeof(hostnameToSend)); - } - } -} -