replace UDPSocket with QUDPSocket

This commit is contained in:
Stephen Birarda 2013-12-02 13:34:29 -08:00
parent d21583d9c5
commit 141394a664
61 changed files with 521 additions and 1386 deletions

View file

@ -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)

View file

@ -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);
}
}

View file

@ -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);
}
}
}

View file

@ -15,7 +15,6 @@
#include <QtCore/QObject>
#include <QtCore/QUrl>
#include <AudioInjector.h>
#include <Assignment.h>
class Agent : public Assignment {
@ -33,7 +32,6 @@ private:
static QScriptValue AudioInjectorConstructor(QScriptContext *context, QScriptEngine *engine);
bool volatile _shouldStop;
std::vector<AudioInjector*> _audioInjectors;
};
#endif /* defined(__hifi__Agent__) */

View file

@ -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

View file

@ -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();

View file

@ -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);
}
}

View file

@ -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;
}
}

View file

@ -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";

View file

@ -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) {

View file

@ -13,6 +13,7 @@
#include <JurisdictionListener.h>
#include <VoxelEditPacketSender.h>
#include <VoxelTree.h>
/// 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);
};

View file

@ -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;
}
}
}
}

View file

@ -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);

View file

@ -19,6 +19,7 @@
#include <ifaddrs.h>
#endif
#include <glm/gtx/component_wise.hpp>
#include <glm/gtx/quaternion.hpp>
#include <glm/gtx/vector_angle.hpp>
@ -47,8 +48,6 @@
#include <QDesktopServices>
#include <NodeTypes.h>
#include <AudioInjectionManager.h>
#include <AudioInjector.h>
#include <Logging.h>
#include <OctalCode.h>
#include <PacketHeaders.h>
@ -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;
}
}

View file

@ -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;

View file

@ -19,7 +19,6 @@
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <StdDev.h>
#include <UDPSocket.h>
#include <QSvgRenderer>
#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);

View file

@ -7,10 +7,10 @@
//
#include <QtCore/QUrl>
#include <QtNetwork/QUdpSocket>
#include <NodeList.h>
#include <PacketHeaders.h>
#include <UDPSocket.h>
#include <UUID.h>
#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<unsigned char*, int>(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<unsigned char*, int>(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());
}
}

View file

@ -18,24 +18,13 @@
#include "renderer/ProgramObject.h"
#include "world.h"
uint qHash(const sockaddr& address) {
const sockaddr_in* inetAddress = reinterpret_cast<const sockaddr_in*>(&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<const char*>(&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;
}

View file

@ -12,7 +12,7 @@
#include <QHash>
#include <QMutex>
#include <UDPSocket.h>
#include <HifiSockAddr.h>
#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<int, EnvironmentData> ServerData;
QHash<sockaddr, ServerData> _data;
QHash<HifiSockAddr, ServerData> _data;
QMutex _mutex;
};

View file

@ -10,6 +10,9 @@
#include <string.h>
#include <stdio.h>
#include <QtNetwork/QHostInfo>
#include <HifiSockAddr.h>
#include <NodeList.h>
#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());
}

View file

@ -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);

View file

@ -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__

View file

@ -13,7 +13,6 @@
#include <glm/glm.hpp>
#include <SharedUtil.h>
#include <UDPSocket.h>
#include <CoverageMapV2.h>
#include <NodeData.h>

View file

@ -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 <sys/time.h>
#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);
}

View file

@ -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 <iostream>
#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__) */

View file

@ -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 <cstring>
#include <fstream>
#include <limits>
#include <NodeList.h>
#include <PacketHeaders.h>
#include <SharedUtil.h>
#include <UUID.h>
#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;
}

View file

@ -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 <glm/gtc/quaternion.hpp>
#include <glm/gtx/component_wise.hpp>
#include <QtCore/QObject>
#include <QtCore/QUuid>
#include <RegisteredMetaTypes.h>
#include <UDPSocket.h>
#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__) */

View file

@ -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);

View file

@ -11,8 +11,6 @@
#include <QtCore/QUuid>
#include "AudioInjector.h"
#include "PositionalAudioRingBuffer.h"
class InjectedAudioRingBuffer : public PositionalAudioRingBuffer {

View file

@ -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 <QtNetwork/QHostInfo>
#include <QtNetwork/QNetworkInterface>
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;
}

View file

@ -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 <QtNetwork/QHostAddress>
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__) */

View file

@ -11,35 +11,35 @@
#include <iostream>
#include <netdb.h>
#include <QtNetwork/QHostInfo>
#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());
}
}

View file

@ -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;
};

View file

@ -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;
}

View file

@ -15,6 +15,8 @@
#include <arpa/inet.h>
#include <ifaddrs.h>
#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];
};

View file

@ -19,30 +19,25 @@
#include "Node.h"
#include "NodeTypes.h"
#include "SharedUtil.h"
#include "UDPSocket.h"
#include <QtCore/QDebug>
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();
}

View file

@ -21,19 +21,18 @@
#include <QtCore/QDebug>
#include <QtCore/QUuid>
#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;

View file

@ -15,6 +15,7 @@
#include <QtNetwork/QHostInfo>
#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, &currentTime, 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);
}

View file

@ -15,11 +15,11 @@
#include <unistd.h>
#include <QtNetwork/QHostAddress>
#include <QtNetwork/QUdpSocket>
#include <QtCore/QSettings>
#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<NodeListHook*> _hooks;
std::vector<DomainChangeListener*> _domainListeners;

View file

@ -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++;

View file

@ -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); }

View file

@ -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
}

View file

@ -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();

View file

@ -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 <arpa/inet.h>
#include <cstdio>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#ifdef _WIN32
#include "Syssocket.h"
#else
#include <sys/socket.h>
#include <arpa/inet.h>
#include <ifaddrs.h>
#include <unistd.h>
#endif
#include <QtCore/QDebug>
#include <QtNetwork/QNetworkInterface>
#include <QtNetwork/QHostAddress>
#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<char*>(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);
}

View file

@ -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 <netinet/in.h>
#include <netdb.h>
#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__) */

View file

@ -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++;

View file

@ -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);
}
}
}

View file

@ -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());
}

View file

@ -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,

View file

@ -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;

View file

@ -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;

View file

@ -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++;
}

View file

@ -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); }

View file

@ -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...

View file

@ -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})

View file

@ -11,17 +11,20 @@
#include <cstdio>
#include <cstring>
#include <UDPSocket.h>
#include <arpa/inet.h>
#include <QtNetwork/QUdpSocket>
#include <HifiSockAddr.h>
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",

View file

@ -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})

View file

@ -1,2 +0,0 @@
0 00000100001011101110 domain4.highfidelity.co domain4
0 00000100110100010001 domain3.highfidelity.co domain3

View file

@ -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;
}

View file

@ -1,26 +0,0 @@
//
// TreeNode.h
// hifi
//
// Created by Stephen Birarda on 2/13/13.
//
//
#ifndef __hifi__TreeNode__
#define __hifi__TreeNode__
#include <iostream>
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__) */

View file

@ -1,160 +0,0 @@
//
// main.cpp
// space
//
// Created by Leonardo Murillo on 2/6/13.
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#include <iostream>
#include <cstdio>
#include <stdlib.h>
#include <string.h>
#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));
}
}
}