correct handling of IPv6, fix offsets for packet reading

This commit is contained in:
Stephen Birarda 2013-09-04 15:21:20 -07:00
parent a7f7dbcb31
commit 2c32a1a048
6 changed files with 64 additions and 36 deletions

View file

@ -6,6 +6,7 @@
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved. // Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
// //
#include <arpa/inet.h>
#include <sys/time.h> #include <sys/time.h>
#include <Assignment.h> #include <Assignment.h>
@ -56,14 +57,23 @@ int main(int argc, char* const argv[]) {
} }
while (nodeList->getNodeSocket()->receive(packetData, &receivedBytes)) { while (nodeList->getNodeSocket()->receive(packetData, &receivedBytes)) {
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT && packetVersionMatch(packetData)) { if (packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT && packetVersionMatch(packetData)) {
Assignment::Type assignmentType = (Assignment::Type) *(packetData + numBytesForPacketHeader(packetData));
qDebug() << "Received an assignment - " << assignmentType << "\n"; // construct the deployed assignment from the packet data
Assignment deployedAssignment(packetData, receivedBytes);
// pull the creator sockaddr_in from the assignment and change our domain IP to that qDebug() << "Received an assignment - " << deployedAssignment << "\n";
// AudioMixer::run(); // switch our nodelist DOMAIN_IP to the ip receieved in the assignment
if (deployedAssignment.getDomainSocket()->sa_family == AF_INET) {
in_addr domainSocketAddr = ((sockaddr_in*) deployedAssignment.getDomainSocket())->sin_addr;
nodeList->setDomainIP(inet_ntoa(domainSocketAddr));
qDebug() << "Changed domain IP to " << inet_ntoa(domainSocketAddr);
}
// run the AudioMixer, it's the only possible assignment for now
AudioMixer::run();
// reset our NodeList by switching back to unassigned and clearing the list // reset our NodeList by switching back to unassigned and clearing the list
nodeList->setOwnerType(NODE_TYPE_UNASSIGNED); nodeList->setOwnerType(NODE_TYPE_UNASSIGNED);

View file

@ -36,17 +36,19 @@ int main(int argc, const char* argv[]) {
if (serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) { if (serverSocket.receive((sockaddr*) &senderSocket, &senderData, &receivedBytes)) {
if (senderData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) { if (senderData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
// construct the requested assignment from the packet data // construct the requested assignment from the packet data
int numHeaderBytes = numBytesForPacketHeader(senderData); Assignment requestAssignment(senderData, receivedBytes);
Assignment requestAssignment(senderData + numHeaderBytes, receivedBytes - numHeaderBytes);
// grab the first assignment in the queue, if it exists // grab the first assignment in the queue, if it exists
if (assignmentQueue.size() > 0) { if (assignmentQueue.size() > 0) {
Assignment firstAssignment = assignmentQueue.front(); Assignment firstAssignment = assignmentQueue.front();
bool eitherHasPool = (firstAssignment.getPool() || requestAssignment.getPool());
// make sure there is a pool match for the created and requested assignment // make sure there is a pool match for the created and requested assignment
if (firstAssignment.getPool() && requestAssignment.getPool() // or that neither has a designated pool
&& strcmp(firstAssignment.getPool(), requestAssignment.getPool())) { if ((eitherHasPool && strcmp(firstAssignment.getPool(), requestAssignment.getPool()))
|| !eitherHasPool) {
assignmentQueue.pop(); assignmentQueue.pop();
int numAssignmentBytes = firstAssignment.packToBuffer(assignmentPacket + numSendHeaderBytes); int numAssignmentBytes = firstAssignment.packToBuffer(assignmentPacket + numSendHeaderBytes);
@ -57,8 +59,7 @@ int main(int argc, const char* argv[]) {
} }
} else if (senderData[0] == PACKET_TYPE_CREATE_ASSIGNMENT && packetVersionMatch(senderData)) { } else if (senderData[0] == PACKET_TYPE_CREATE_ASSIGNMENT && packetVersionMatch(senderData)) {
// construct the create assignment from the packet data // construct the create assignment from the packet data
int numHeaderBytes = numBytesForPacketHeader(senderData); Assignment createdAssignment(senderData, receivedBytes);
Assignment createdAssignment(senderData + numHeaderBytes, receivedBytes - numHeaderBytes);
qDebug() << "Received an assignment:" << createdAssignment; qDebug() << "Received an assignment:" << createdAssignment;

View file

@ -6,6 +6,8 @@
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
// //
#include "PacketHeaders.h"
#include "Assignment.h" #include "Assignment.h"
Assignment::Assignment(Assignment::Direction direction, Assignment::Type type, const char* pool) : Assignment::Assignment(Assignment::Direction direction, Assignment::Type type, const char* pool) :
@ -30,15 +32,21 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
{ {
int numBytesRead = 0; int numBytesRead = 0;
memcpy(&_direction, dataBuffer, sizeof(Assignment::Direction)); if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
numBytesRead += sizeof(Assignment::Direction); _direction = Assignment::Request;
} else if (dataBuffer[0] == PACKET_TYPE_CREATE_ASSIGNMENT) {
_direction = Assignment::Create;
} else if (dataBuffer[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT) {
_direction = Assignment::Deploy;
}
numBytesRead += numBytesForPacketHeader(dataBuffer);
memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type)); memcpy(&_type, dataBuffer + numBytesRead, sizeof(Assignment::Type));
numBytesRead += sizeof(Assignment::Type); numBytesRead += sizeof(Assignment::Type);
if (dataBuffer[numBytesRead] != 0) {
int poolLength = strlen((const char*) dataBuffer + numBytesRead); int poolLength = strlen((const char*) dataBuffer + numBytesRead);
if (poolLength) {
_pool = new char[poolLength + sizeof(char)]; _pool = new char[poolLength + sizeof(char)];
strcpy(_pool, (char*) dataBuffer + numBytesRead); strcpy(_pool, (char*) dataBuffer + numBytesRead);
numBytesRead += poolLength + sizeof(char); numBytesRead += poolLength + sizeof(char);
@ -46,18 +54,24 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
numBytesRead += sizeof(char); numBytesRead += sizeof(char);
} }
if (numBytes > numBytesRead) { if (numBytes > numBytesRead) {
memcpy(_domainSocket, dataBuffer + numBytesRead, sizeof(sockaddr)); if (dataBuffer[numBytesRead++] == 4) {
// IPv4 address
sockaddr_in destinationSocket = {};
memcpy(&destinationSocket, dataBuffer + numBytesRead, sizeof(sockaddr_in));
setDomainSocket((sockaddr*) &destinationSocket);
} else {
// IPv6 address
sockaddr_in6 destinationSocket = {};
memcpy(&destinationSocket, dataBuffer + numBytesRead, sizeof(sockaddr_in6));
setDomainSocket((sockaddr*) &destinationSocket);
}
} }
} }
int Assignment::packToBuffer(unsigned char* buffer) { int Assignment::packToBuffer(unsigned char* buffer) {
int numPackedBytes = 0; int numPackedBytes = 0;
memcpy(buffer, &_direction, sizeof(_direction));
numPackedBytes += sizeof(_direction);
memcpy(buffer + numPackedBytes, &_type, sizeof(_type)); memcpy(buffer + numPackedBytes, &_type, sizeof(_type));
numPackedBytes += sizeof(_type); numPackedBytes += sizeof(_type);
@ -72,8 +86,12 @@ int Assignment::packToBuffer(unsigned char* buffer) {
} }
if (_domainSocket) { if (_domainSocket) {
memcpy(buffer + numPackedBytes, _domainSocket, sizeof(sockaddr)); buffer[numPackedBytes++] = (_domainSocket->sa_family == AF_INET) ? 4 : 6;
numPackedBytes += sizeof(sockaddr);
int numSocketBytes = (_domainSocket->sa_family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
memcpy(buffer + numPackedBytes, _domainSocket, numSocketBytes);
numPackedBytes += numSocketBytes;
} }
return numPackedBytes; return numPackedBytes;
@ -87,7 +105,6 @@ void Assignment::setDomainSocket(const sockaddr* domainSocket) {
_domainSocket = NULL; _domainSocket = NULL;
} }
if (!_domainSocket) {
// create a new sockaddr or sockaddr_in depending on what type of address this is // create a new sockaddr or sockaddr_in depending on what type of address this is
if (domainSocket->sa_family == AF_INET) { if (domainSocket->sa_family == AF_INET) {
sockaddr_in* newSocket = new sockaddr_in; sockaddr_in* newSocket = new sockaddr_in;
@ -99,7 +116,6 @@ void Assignment::setDomainSocket(const sockaddr* domainSocket) {
_domainSocket = (sockaddr*) newSocket; _domainSocket = (sockaddr*) newSocket;
} }
} }
}
QDebug operator<<(QDebug debug, const Assignment &assignment) { QDebug operator<<(QDebug debug, const Assignment &assignment) {
debug << "T:" << assignment.getType() << "P:" << assignment.getPool(); debug << "T:" << assignment.getType() << "P:" << assignment.getPool();

View file

@ -21,6 +21,7 @@ public:
enum Direction { enum Direction {
Create, Create,
Deploy,
Request Request
}; };

View file

@ -67,7 +67,7 @@ int numBytesForPacketVersion(const unsigned char* packetVersion) {
} }
} }
int numBytesForPacketHeader(unsigned char* packetHeader) { int numBytesForPacketHeader(const unsigned char* packetHeader) {
// int numBytesType = numBytesForPacketType(packetHeader); // int numBytesType = numBytesForPacketType(packetHeader);
// return numBytesType + numBytesForPacketVersion(packetHeader + numBytesType); // return numBytesType + numBytesForPacketVersion(packetHeader + numBytesType);

View file

@ -49,7 +49,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type);
bool packetVersionMatch(unsigned char* packetHeader); bool packetVersionMatch(unsigned char* packetHeader);
int populateTypeAndVersion(unsigned char* destinationHeader, PACKET_TYPE type); int populateTypeAndVersion(unsigned char* destinationHeader, PACKET_TYPE type);
int numBytesForPacketHeader(unsigned char* packetHeader); int numBytesForPacketHeader(const unsigned char* packetHeader);
const int MAX_PACKET_HEADER_BYTES = sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION); const int MAX_PACKET_HEADER_BYTES = sizeof(PACKET_TYPE) + sizeof(PACKET_VERSION);