From f18a40dc89f6933e801aff4510a9845e045b26e7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 6 Sep 2013 15:12:53 -0700 Subject: [PATCH 1/9] correct timing for assignment-client check in --- assignment-client/src/main.cpp | 65 +++++++++++++++++-------------- libraries/shared/src/NodeList.cpp | 1 + 2 files changed, 36 insertions(+), 30 deletions(-) diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index f3d6b8c0cd..ac34fb0723 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -16,7 +16,7 @@ #include #include -const int ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000; +const long long ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000; int main(int argc, char* const argv[]) { @@ -28,6 +28,8 @@ int main(int argc, char* const argv[]) { // change the timeout on the nodelist socket to be as often as we want to re-request nodeList->getNodeSocket()->setBlockingReceiveTimeoutInUsecs(ASSIGNMENT_REQUEST_INTERVAL_USECS); + timeval lastRequest = {}; + unsigned char packetData[MAX_PACKET_SIZE]; ssize_t receivedBytes = 0; @@ -51,38 +53,41 @@ int main(int argc, char* const argv[]) { Assignment requestAssignment(Assignment::Request, Assignment::All, assignmentPool); while (true) { - // if we're here we have no assignment, so send a request - qDebug() << "Sending an assignment request -" << requestAssignment; - nodeList->sendAssignment(requestAssignment); + if (usecTimestampNow() - usecTimestamp(&lastRequest) >= ASSIGNMENT_REQUEST_INTERVAL_USECS) { + gettimeofday(&lastRequest, NULL); + // if we're here we have no assignment, so send a request + qDebug() << "Sending an assignment request -" << requestAssignment; + nodeList->sendAssignment(requestAssignment); + } - while (nodeList->getNodeSocket()->receive(packetData, &receivedBytes)) { - if (packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT && packetVersionMatch(packetData)) { + if (nodeList->getNodeSocket()->receive(packetData, &receivedBytes) && + packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT && packetVersionMatch(packetData)) { + + // construct the deployed assignment from the packet data + Assignment deployedAssignment(packetData, receivedBytes); + + qDebug() << "Received an assignment - " << deployedAssignment << "\n"; + + // switch our nodelist DOMAIN_IP to the ip receieved in the assignment + if (deployedAssignment.getDomainSocket()->sa_family == AF_INET) { + in_addr domainSocketAddr = ((sockaddr_in*) deployedAssignment.getDomainSocket())->sin_addr; + nodeList->setDomainIP(inet_ntoa(domainSocketAddr)); - // construct the deployed assignment from the packet data - Assignment deployedAssignment(packetData, receivedBytes); - - qDebug() << "Received an assignment - " << deployedAssignment << "\n"; - - // switch our nodelist DOMAIN_IP to the ip receieved in the assignment - if (deployedAssignment.getDomainSocket()->sa_family == AF_INET) { - in_addr domainSocketAddr = ((sockaddr_in*) deployedAssignment.getDomainSocket())->sin_addr; - nodeList->setDomainIP(inet_ntoa(domainSocketAddr)); - - qDebug() << "Changed domain IP to " << inet_ntoa(domainSocketAddr); - } - - if (deployedAssignment.getType() == Assignment::AudioMixer) { - AudioMixer::run(); - } else { - AvatarMixer::run(); - } - - qDebug() << "Assignment finished or never started - waiting for new assignment"; - - // reset our NodeList by switching back to unassigned and clearing the list - nodeList->setOwnerType(NODE_TYPE_UNASSIGNED); - nodeList->clear(); + qDebug() << "Changed domain IP to " << inet_ntoa(domainSocketAddr); } + + if (deployedAssignment.getType() == Assignment::AudioMixer) { + AudioMixer::run(); + } else { + qDebug() << "Running as an avatar mixer!"; + AvatarMixer::run(); + } + + qDebug() << "Assignment finished or never started - waiting for new assignment"; + + // reset our NodeList by switching back to unassigned and clearing the list + nodeList->setOwnerType(NODE_TYPE_UNASSIGNED); + nodeList->clear(); } } } \ No newline at end of file diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index c650190a4a..db90856251 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -255,6 +255,7 @@ void NodeList::clear() { } _numNodes = 0; + _numNoReplyDomainCheckIns = 0; } void NodeList::setNodeTypesOfInterest(const char* nodeTypesOfInterest, int numNodeTypesOfInterest) { From 3b78678a7686393e2f7165fa87cab78a094bb1b0 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 6 Sep 2013 15:21:55 -0700 Subject: [PATCH 2/9] cleanup pool grabbing for DS and AC --- assignment-client/src/main.cpp | 19 +++---------------- domain-server/src/main.cpp | 20 +++++--------------- libraries/shared/src/NodeList.cpp | 2 +- 3 files changed, 9 insertions(+), 32 deletions(-) diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index ac34fb0723..d33bf10e2e 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -18,7 +18,7 @@ const long long ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000; -int main(int argc, char* const argv[]) { +int main(int argc, const char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); @@ -33,21 +33,8 @@ int main(int argc, char* const argv[]) { unsigned char packetData[MAX_PACKET_SIZE]; ssize_t receivedBytes = 0; - // loop the parameters to see if we were passed a pool - int parameter = -1; - const char ALLOWED_PARAMETERS[] = "p::"; - const char POOL_PARAMETER_CHAR = 'p'; - - char* assignmentPool = NULL; - - while ((parameter = getopt(argc, argv, ALLOWED_PARAMETERS)) != -1) { - if (parameter == POOL_PARAMETER_CHAR) { - // copy the passed assignment pool - int poolLength = strlen(optarg); - assignmentPool = new char[poolLength + sizeof(char)]; - strcpy(assignmentPool, optarg); - } - } + // grab the assignment pool from argv, if it was passed + const char* assignmentPool = getCmdOption(argc, argv, "-p"); // create a request assignment, accept all assignments, pass the desired pool (if it exists) Assignment requestAssignment(Assignment::Request, Assignment::All, assignmentPool); diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 882fa85098..4bb554ab53 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -48,7 +48,7 @@ unsigned char* addNodeToBroadcastPacket(unsigned char* currentPosition, Node* no return currentPosition; } -int main(int argc, char* const argv[]) { +int main(int argc, const char* argv[]) { NodeList* nodeList = NodeList::createInstance(NODE_TYPE_DOMAIN, DOMAIN_LISTEN_PORT); // If user asks to run in "local" mode then we do NOT replace the IP // with the EC2 IP. Otherwise, we will replace the IP like we used to @@ -85,21 +85,11 @@ int main(int argc, char* const argv[]) { timeval lastStatSendTime = {}; - // loop the parameters to see if we were passed a pool for assignment - int parameter = -1; - const char ALLOWED_PARAMETERS[] = "p::-local::"; - const char POOL_PARAMETER_CHAR = 'p'; + // set our assignment pool from argv, if it exists + const char* assignmentPool = getCmdOption(argc, argv, "-p"); - char* assignmentPool = NULL; - - while ((parameter = getopt(argc, argv, ALLOWED_PARAMETERS)) != -1) { - if (parameter == POOL_PARAMETER_CHAR) { - // copy the passed assignment pool - int poolLength = strlen(optarg); - assignmentPool = new char[poolLength + sizeof(char)]; - strcpy(assignmentPool, optarg); - } - } + // grab the overriden assignment-server hostname from argv, if it exists + const char* assignmentServer = getCmdOption(argc, argv, "-a"); // use a map to keep track of iterations of silence for assignment creation requests const int ASSIGNMENT_SILENCE_MAX_ITERATIONS = 5; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index db90856251..cd52ff8ded 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -375,7 +375,7 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte return readNodes; } -const char ASSIGNMENT_SERVER_HOSTNAME[] = "assignment.highfidelity.io"; +const char ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; const sockaddr_in assignmentServerSocket = socketForHostnameAndHostOrderPort(ASSIGNMENT_SERVER_HOSTNAME, ASSIGNMENT_SERVER_PORT); From 65ef778efd6482007a8fd5b55b7e92a9977677d8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 6 Sep 2013 15:31:21 -0700 Subject: [PATCH 3/9] allow passing of custom assignment-server to DS and AC --- assignment-client/src/main.cpp | 3 +++ domain-server/src/main.cpp | 2 +- libraries/shared/src/NodeList.cpp | 10 +++++++--- libraries/shared/src/NodeList.h | 2 ++ 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index d33bf10e2e..1da0a0215a 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -36,6 +36,9 @@ int main(int argc, const char* argv[]) { // grab the assignment pool from argv, if it was passed const char* assignmentPool = getCmdOption(argc, argv, "-p"); + // set the overriden assignment-server hostname from argv, if it exists + nodeList->setAssignmentServerHostname(getCmdOption(argc, argv, "-a")); + // create a request assignment, accept all assignments, pass the desired pool (if it exists) Assignment requestAssignment(Assignment::Request, Assignment::All, assignmentPool); diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 4bb554ab53..5fcef77a8c 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -89,7 +89,7 @@ int main(int argc, const char* argv[]) { const char* assignmentPool = getCmdOption(argc, argv, "-p"); // grab the overriden assignment-server hostname from argv, if it exists - const char* assignmentServer = getCmdOption(argc, argv, "-a"); + nodeList->setAssignmentServerHostname(getCmdOption(argc, argv, "-a")); // use a map to keep track of iterations of silence for assignment creation requests const int ASSIGNMENT_SILENCE_MAX_ITERATIONS = 5; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index cd52ff8ded..ad5876f622 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -375,9 +375,7 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte return readNodes; } -const char ASSIGNMENT_SERVER_HOSTNAME[] = "localhost"; -const sockaddr_in assignmentServerSocket = socketForHostnameAndHostOrderPort(ASSIGNMENT_SERVER_HOSTNAME, - ASSIGNMENT_SERVER_PORT); +const char GLOBAL_ASSIGNMENT_SERVER_HOSTNAME[] = "assignment.highfidelity.io"; void NodeList::sendAssignment(Assignment& assignment) { unsigned char assignmentPacket[MAX_PACKET_SIZE]; @@ -388,6 +386,12 @@ void NodeList::sendAssignment(Assignment& assignment) { int numHeaderBytes = populateTypeAndVersion(assignmentPacket, assignmentPacketType); int numAssignmentBytes = assignment.packToBuffer(assignmentPacket + numHeaderBytes); + + // setup the assignmentServerSocket once, use a custom assignmentServerHostname if it is present + static sockaddr_in assignmentServerSocket = socketForHostnameAndHostOrderPort((_assignmentServerHostname != NULL + ? (const char*) _assignmentServerHostname + : GLOBAL_ASSIGNMENT_SERVER_HOSTNAME), + ASSIGNMENT_SERVER_PORT); _nodeSocket.send((sockaddr*) &assignmentServerSocket, assignmentPacket, numHeaderBytes + numAssignmentBytes); } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 8afe8e38d3..dad422a29b 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -99,6 +99,7 @@ public: void sendDomainServerCheckIn(); int processDomainServerList(unsigned char *packetData, size_t dataBytes); + void setAssignmentServerHostname(const char* serverHostname) { _assignmentServerHostname = serverHostname; } void sendAssignment(Assignment& assignment); Node* nodeWithAddress(sockaddr *senderAddress); @@ -151,6 +152,7 @@ private: pthread_t removeSilentNodesThread; pthread_t checkInWithDomainServerThread; int _numNoReplyDomainCheckIns; + const char* _assignmentServerHostname; void handlePingReply(sockaddr *nodeAddress); void timePingReply(sockaddr *nodeAddress, unsigned char *packetData); From 8424c4e38b47de0bf968b982bc53e8f96dd9a41f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 6 Sep 2013 15:44:24 -0700 Subject: [PATCH 4/9] make DS immediately request assignments instead of waiting one silent loop --- domain-server/src/main.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 5fcef77a8c..6de926a7a7 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -101,9 +101,9 @@ int main(int argc, const char* argv[]) { Assignment avatarAssignment(Assignment::Create, Assignment::AvatarMixer, assignmentPool); while (true) { - if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER)) { - if (assignmentSilenceCount[&audioAssignment] == ASSIGNMENT_SILENCE_MAX_ITERATIONS) { + std::map::iterator countIt = assignmentSilenceCount.find(&audioAssignment); + if (countIt == assignmentSilenceCount.end() || countIt->second == ASSIGNMENT_SILENCE_MAX_ITERATIONS) { nodeList->sendAssignment(audioAssignment); assignmentSilenceCount[&audioAssignment] = 0; } else { @@ -114,7 +114,8 @@ int main(int argc, const char* argv[]) { } if (!nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER)) { - if (assignmentSilenceCount[&avatarAssignment] == ASSIGNMENT_SILENCE_MAX_ITERATIONS) { + std::map::iterator countIt = assignmentSilenceCount.find(&avatarAssignment); + if (countIt == assignmentSilenceCount.end() || countIt->second == ASSIGNMENT_SILENCE_MAX_ITERATIONS) { nodeList->sendAssignment(avatarAssignment); assignmentSilenceCount[&avatarAssignment] = 0; } else { From cbf8a2c202c7b5e487c80bc758ffcf16a8c8aa30 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 6 Sep 2013 16:03:54 -0700 Subject: [PATCH 5/9] use create time already being stored with assignment to decide on re-send --- domain-server/src/main.cpp | 49 ++++++++++++++++------------- libraries/shared/src/Assignment.cpp | 38 +++++++++++----------- libraries/shared/src/Assignment.h | 5 +++ 3 files changed, 50 insertions(+), 42 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 6de926a7a7..32a88e8e08 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -92,40 +92,42 @@ int main(int argc, const char* argv[]) { nodeList->setAssignmentServerHostname(getCmdOption(argc, argv, "-a")); // use a map to keep track of iterations of silence for assignment creation requests - const int ASSIGNMENT_SILENCE_MAX_ITERATIONS = 5; - std::map assignmentSilenceCount; + const long long ASSIGNMENT_SILENCE_MAX_USECS = 5 * 1000 * 1000; // as a domain-server we will always want an audio mixer and avatar mixer - // setup the create assignments for those - Assignment audioAssignment(Assignment::Create, Assignment::AudioMixer, assignmentPool); - Assignment avatarAssignment(Assignment::Create, Assignment::AvatarMixer, assignmentPool); + // setup the create assignment pointers for those + Assignment *audioAssignment = NULL; + Assignment *avatarAssignment = NULL; while (true) { if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER)) { - std::map::iterator countIt = assignmentSilenceCount.find(&audioAssignment); - if (countIt == assignmentSilenceCount.end() || countIt->second == ASSIGNMENT_SILENCE_MAX_ITERATIONS) { - nodeList->sendAssignment(audioAssignment); - assignmentSilenceCount[&audioAssignment] = 0; - } else { - assignmentSilenceCount[&audioAssignment]++; + if (!audioAssignment + || usecTimestampNow() - usecTimestamp(&audioAssignment->getTime()) >= ASSIGNMENT_SILENCE_MAX_USECS) { + + if (!audioAssignment) { + audioAssignment = new Assignment(Assignment::Create, Assignment::AudioMixer, assignmentPool); + } + + nodeList->sendAssignment(*audioAssignment); + audioAssignment->setCreateTimeToNow(); } - } else { - assignmentSilenceCount[&audioAssignment] = 0; } if (!nodeList->soloNodeOfType(NODE_TYPE_AVATAR_MIXER)) { - std::map::iterator countIt = assignmentSilenceCount.find(&avatarAssignment); - if (countIt == assignmentSilenceCount.end() || countIt->second == ASSIGNMENT_SILENCE_MAX_ITERATIONS) { - nodeList->sendAssignment(avatarAssignment); - assignmentSilenceCount[&avatarAssignment] = 0; - } else { - assignmentSilenceCount[&avatarAssignment]++; + if (!avatarAssignment + || usecTimestampNow() - usecTimestamp(&avatarAssignment->getTime()) >= ASSIGNMENT_SILENCE_MAX_USECS) { + if (!avatarAssignment) { + avatarAssignment = new Assignment(Assignment::Create, Assignment::AvatarMixer, assignmentPool); + } + + nodeList->sendAssignment(*avatarAssignment); + + // reset the create time on the assignment so re-request is in ASSIGNMENT_SILENCE_MAX_USECS + avatarAssignment->setCreateTimeToNow(); } - } else { - assignmentSilenceCount[&avatarAssignment] = 0; + } - if (nodeList->getNodeSocket()->receive((sockaddr *)&nodePublicAddress, packetData, &receivedBytes) && (packetData[0] == PACKET_TYPE_DOMAIN_REPORT_FOR_DUTY || packetData[0] == PACKET_TYPE_DOMAIN_LIST_REQUEST) && packetVersionMatch(packetData)) { @@ -236,6 +238,9 @@ int main(int argc, const char* argv[]) { } } } + + delete audioAssignment; + delete avatarAssignment; return 0; } diff --git a/libraries/shared/src/Assignment.cpp b/libraries/shared/src/Assignment.cpp index 3c6e432f2c..850922396f 100644 --- a/libraries/shared/src/Assignment.cpp +++ b/libraries/shared/src/Assignment.cpp @@ -6,8 +6,6 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // -#include - #include "PacketHeaders.h" #include "Assignment.h" @@ -86,6 +84,24 @@ Assignment::~Assignment() { delete _pool; } +void Assignment::setDomainSocket(const sockaddr* domainSocket) { + + if (_domainSocket) { + // delete the old _domainSocket if it exists + delete _domainSocket; + _domainSocket = NULL; + } + + // create a new sockaddr or sockaddr_in depending on what type of address this is + if (domainSocket->sa_family == AF_INET) { + _domainSocket = (sockaddr*) new sockaddr_in; + memcpy(_domainSocket, domainSocket, sizeof(sockaddr_in)); + } else { + _domainSocket = (sockaddr*) new sockaddr_in6; + memcpy(_domainSocket, domainSocket, sizeof(sockaddr_in6)); + } +} + int Assignment::packToBuffer(unsigned char* buffer) { int numPackedBytes = 0; @@ -114,24 +130,6 @@ int Assignment::packToBuffer(unsigned char* buffer) { return numPackedBytes; } -void Assignment::setDomainSocket(const sockaddr* domainSocket) { - - if (_domainSocket) { - // delete the old _domainSocket if it exists - delete _domainSocket; - _domainSocket = NULL; - } - - // create a new sockaddr or sockaddr_in depending on what type of address this is - if (domainSocket->sa_family == AF_INET) { - _domainSocket = (sockaddr*) new sockaddr_in; - memcpy(_domainSocket, domainSocket, sizeof(sockaddr_in)); - } else { - _domainSocket = (sockaddr*) new sockaddr_in6; - memcpy(_domainSocket, domainSocket, sizeof(sockaddr_in6)); - } -} - QDebug operator<<(QDebug debug, const Assignment &assignment) { debug << "T:" << assignment.getType() << "P:" << assignment.getPool(); return debug.nospace(); diff --git a/libraries/shared/src/Assignment.h b/libraries/shared/src/Assignment.h index 2c2673f351..693cc42577 100644 --- a/libraries/shared/src/Assignment.h +++ b/libraries/shared/src/Assignment.h @@ -9,6 +9,8 @@ #ifndef __hifi__Assignment__ #define __hifi__Assignment__ +#include + #include "NodeList.h" /// Holds information used for request, creation, and deployment of assignments @@ -49,6 +51,9 @@ public: /// \return number of bytes packed into buffer int packToBuffer(unsigned char* buffer); + /// Sets _time to the current time given by gettimeofday + void setCreateTimeToNow() { gettimeofday(&_time, NULL); } + private: Assignment::Direction _direction; /// the direction of the assignment (Create, Deploy, Request) Assignment::Type _type; /// the type of the assignment, defines what the assignee will do From 49050320901cf755937d7659cdc65d0e86943b04 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 9 Sep 2013 09:44:43 -0700 Subject: [PATCH 6/9] allow forking of multiple assignment-clients from the main target --- assignment-client/src/main.cpp | 42 ++++++++++++++++++++++++++----- domain-server/src/main.cpp | 6 ++++- libraries/shared/src/NodeList.cpp | 18 ++++++------- libraries/shared/src/NodeList.h | 4 +-- 4 files changed, 52 insertions(+), 18 deletions(-) diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 1da0a0215a..67d2a1e021 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -18,13 +18,47 @@ const long long ASSIGNMENT_REQUEST_INTERVAL_USECS = 1 * 1000 * 1000; + int main(int argc, const char* argv[]) { setvbuf(stdout, NULL, _IOLBF, 0); + sockaddr_in customAssignmentSocket = {}; + + // grab the overriden assignment-server hostname from argv, if it exists + const char* customAssignmentServer = getCmdOption(argc, argv, "-a"); + if (customAssignmentServer) { + customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServer, ASSIGNMENT_SERVER_PORT); + } + + const char* NUM_FORKS_PARAMETER = "-n"; + const char* numForksIncludingParentString = getCmdOption(argc, argv, NUM_FORKS_PARAMETER); + + if (numForksIncludingParentString) { + int numForksIncludingParent = atoi(numForksIncludingParentString); + qDebug() << "Starting" << numForksIncludingParent << "assignment clients."; + + int processID = 0; + + // fire off as many children as we need (this is one less than the parent since the parent will run as well) + for (int i = 0; i < numForksIncludingParent - 1; i++) { + processID = fork(); + + if (processID == 0) { + // this is one of the children, break so we don't start a fork bomb + break; + } + } + } + // create a NodeList as an unassigned client NodeList* nodeList = NodeList::createInstance(NODE_TYPE_UNASSIGNED); + // set the custom assignment socket if we have it + if (customAssignmentSocket.sin_addr.s_addr != 0) { + nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentSocket); + } + // change the timeout on the nodelist socket to be as often as we want to re-request nodeList->getNodeSocket()->setBlockingReceiveTimeoutInUsecs(ASSIGNMENT_REQUEST_INTERVAL_USECS); @@ -34,10 +68,8 @@ int main(int argc, const char* argv[]) { ssize_t receivedBytes = 0; // grab the assignment pool from argv, if it was passed - const char* assignmentPool = getCmdOption(argc, argv, "-p"); - - // set the overriden assignment-server hostname from argv, if it exists - nodeList->setAssignmentServerHostname(getCmdOption(argc, argv, "-a")); + const char* ASSIGNMENT_POOL_PARAMETER = "-p"; + const char* assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_PARAMETER); // create a request assignment, accept all assignments, pass the desired pool (if it exists) Assignment requestAssignment(Assignment::Request, Assignment::All, assignmentPool); @@ -46,7 +78,6 @@ int main(int argc, const char* argv[]) { if (usecTimestampNow() - usecTimestamp(&lastRequest) >= ASSIGNMENT_REQUEST_INTERVAL_USECS) { gettimeofday(&lastRequest, NULL); // if we're here we have no assignment, so send a request - qDebug() << "Sending an assignment request -" << requestAssignment; nodeList->sendAssignment(requestAssignment); } @@ -69,7 +100,6 @@ int main(int argc, const char* argv[]) { if (deployedAssignment.getType() == Assignment::AudioMixer) { AudioMixer::run(); } else { - qDebug() << "Running as an avatar mixer!"; AvatarMixer::run(); } diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 32a88e8e08..c8916f1c59 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -89,7 +89,11 @@ int main(int argc, const char* argv[]) { const char* assignmentPool = getCmdOption(argc, argv, "-p"); // grab the overriden assignment-server hostname from argv, if it exists - nodeList->setAssignmentServerHostname(getCmdOption(argc, argv, "-a")); + const char* customAssignmentServer = getCmdOption(argc, argv, "-a"); + if (customAssignmentServer) { + sockaddr_in customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServer, ASSIGNMENT_SERVER_PORT); + nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentSocket); + } // use a map to keep track of iterations of silence for assignment creation requests const long long ASSIGNMENT_SILENCE_MAX_USECS = 5 * 1000 * 1000; diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index ad5876f622..4d042b0f63 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -65,7 +65,8 @@ NodeList::NodeList(char newOwnerType, unsigned short int newSocketListenPort) : _nodeTypesOfInterest(NULL), _ownerID(UNKNOWN_NODE_ID), _lastNodeID(UNKNOWN_NODE_ID + 1), - _numNoReplyDomainCheckIns(0) + _numNoReplyDomainCheckIns(0), + _assignmentServerSocket(NULL) { memcpy(_domainHostname, DEFAULT_DOMAIN_HOSTNAME, sizeof(DEFAULT_DOMAIN_HOSTNAME)); memcpy(_domainIP, DEFAULT_DOMAIN_IP, sizeof(DEFAULT_DOMAIN_IP)); @@ -376,7 +377,8 @@ int NodeList::processDomainServerList(unsigned char* packetData, size_t dataByte } const char GLOBAL_ASSIGNMENT_SERVER_HOSTNAME[] = "assignment.highfidelity.io"; - +const sockaddr_in GLOBAL_ASSIGNMENT_SOCKET = socketForHostnameAndHostOrderPort(GLOBAL_ASSIGNMENT_SERVER_HOSTNAME, + ASSIGNMENT_SERVER_PORT); void NodeList::sendAssignment(Assignment& assignment) { unsigned char assignmentPacket[MAX_PACKET_SIZE]; @@ -387,13 +389,11 @@ void NodeList::sendAssignment(Assignment& assignment) { int numHeaderBytes = populateTypeAndVersion(assignmentPacket, assignmentPacketType); int numAssignmentBytes = assignment.packToBuffer(assignmentPacket + numHeaderBytes); - // setup the assignmentServerSocket once, use a custom assignmentServerHostname if it is present - static sockaddr_in assignmentServerSocket = socketForHostnameAndHostOrderPort((_assignmentServerHostname != NULL - ? (const char*) _assignmentServerHostname - : GLOBAL_ASSIGNMENT_SERVER_HOSTNAME), - ASSIGNMENT_SERVER_PORT); - - _nodeSocket.send((sockaddr*) &assignmentServerSocket, assignmentPacket, numHeaderBytes + numAssignmentBytes); + sockaddr* assignmentServerSocket = (_assignmentServerSocket == NULL) + ? (sockaddr*) &GLOBAL_ASSIGNMENT_SOCKET + : _assignmentServerSocket; + + _nodeSocket.send((sockaddr*) assignmentServerSocket, assignmentPacket, numHeaderBytes + numAssignmentBytes); } Node* NodeList::addOrUpdateNode(sockaddr* publicSocket, sockaddr* localSocket, char nodeType, uint16_t nodeId) { diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index dad422a29b..ea94e8c080 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -99,7 +99,7 @@ public: void sendDomainServerCheckIn(); int processDomainServerList(unsigned char *packetData, size_t dataBytes); - void setAssignmentServerHostname(const char* serverHostname) { _assignmentServerHostname = serverHostname; } + void setAssignmentServerSocket(sockaddr* serverSocket) { _assignmentServerSocket = serverSocket; } void sendAssignment(Assignment& assignment); Node* nodeWithAddress(sockaddr *senderAddress); @@ -152,7 +152,7 @@ private: pthread_t removeSilentNodesThread; pthread_t checkInWithDomainServerThread; int _numNoReplyDomainCheckIns; - const char* _assignmentServerHostname; + sockaddr* _assignmentServerSocket; void handlePingReply(sockaddr *nodeAddress); void timePingReply(sockaddr *nodeAddress, unsigned char *packetData); From 2fd043b55c2588cea2b059cc4e612e4ba2a9720f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 9 Sep 2013 10:02:30 -0700 Subject: [PATCH 7/9] code review comments --- domain-server/src/main.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index c8916f1c59..4c13888ee3 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -85,11 +85,14 @@ int main(int argc, const char* argv[]) { timeval lastStatSendTime = {}; + const char ASSIGNMENT_POOL_OPTION = "-p"; + const char ASSIGNMENT_SERVER_OPTION = "-a"; + // set our assignment pool from argv, if it exists - const char* assignmentPool = getCmdOption(argc, argv, "-p"); + const char* assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_OPTION); // grab the overriden assignment-server hostname from argv, if it exists - const char* customAssignmentServer = getCmdOption(argc, argv, "-a"); + const char* customAssignmentServer = getCmdOption(argc, argv, ASSIGNMENT_SERVER_OPTION); if (customAssignmentServer) { sockaddr_in customAssignmentSocket = socketForHostnameAndHostOrderPort(customAssignmentServer, ASSIGNMENT_SERVER_PORT); nodeList->setAssignmentServerSocket((sockaddr*) &customAssignmentSocket); @@ -100,8 +103,8 @@ int main(int argc, const char* argv[]) { // as a domain-server we will always want an audio mixer and avatar mixer // setup the create assignment pointers for those - Assignment *audioAssignment = NULL; - Assignment *avatarAssignment = NULL; + Assignment* audioAssignment = NULL; + Assignment* avatarAssignment = NULL; while (true) { if (!nodeList->soloNodeOfType(NODE_TYPE_AUDIO_MIXER)) { From 64e3c19a8c789db748a0519e67ae8440d73d29c2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 9 Sep 2013 10:07:31 -0700 Subject: [PATCH 8/9] fix an incorrectly typed const --- domain-server/src/main.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 4c13888ee3..07b67db85d 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -85,8 +85,8 @@ int main(int argc, const char* argv[]) { timeval lastStatSendTime = {}; - const char ASSIGNMENT_POOL_OPTION = "-p"; - const char ASSIGNMENT_SERVER_OPTION = "-a"; + const char ASSIGNMENT_POOL_OPTION[] = "-p"; + const char ASSIGNMENT_SERVER_OPTION[]g = "-a"; // set our assignment pool from argv, if it exists const char* assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_OPTION); From d1c602df0768960ab713ba78b7e188174de822d9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 9 Sep 2013 10:10:16 -0700 Subject: [PATCH 9/9] remove an extra g --- domain-server/src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/main.cpp b/domain-server/src/main.cpp index 07b67db85d..0d51671e0c 100644 --- a/domain-server/src/main.cpp +++ b/domain-server/src/main.cpp @@ -86,7 +86,7 @@ int main(int argc, const char* argv[]) { timeval lastStatSendTime = {}; const char ASSIGNMENT_POOL_OPTION[] = "-p"; - const char ASSIGNMENT_SERVER_OPTION[]g = "-a"; + const char ASSIGNMENT_SERVER_OPTION[] = "-a"; // set our assignment pool from argv, if it exists const char* assignmentPool = getCmdOption(argc, argv, ASSIGNMENT_POOL_OPTION);