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.
//
#include <arpa/inet.h>
#include <sys/time.h>
#include <Assignment.h>
@ -56,14 +57,23 @@ int main(int argc, char* const argv[]) {
}
while (nodeList->getNodeSocket()->receive(packetData, &receivedBytes)) {
if (packetData[0] == PACKET_TYPE_CREATE_ASSIGNMENT && packetVersionMatch(packetData)) {
Assignment::Type assignmentType = (Assignment::Type) *(packetData + numBytesForPacketHeader(packetData));
if (packetData[0] == PACKET_TYPE_DEPLOY_ASSIGNMENT && packetVersionMatch(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
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 (senderData[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
// construct the requested assignment from the packet data
int numHeaderBytes = numBytesForPacketHeader(senderData);
Assignment requestAssignment(senderData + numHeaderBytes, receivedBytes - numHeaderBytes);
Assignment requestAssignment(senderData, receivedBytes);
// grab the first assignment in the queue, if it exists
if (assignmentQueue.size() > 0) {
Assignment firstAssignment = assignmentQueue.front();
bool eitherHasPool = (firstAssignment.getPool() || requestAssignment.getPool());
// make sure there is a pool match for the created and requested assignment
if (firstAssignment.getPool() && requestAssignment.getPool()
&& strcmp(firstAssignment.getPool(), requestAssignment.getPool())) {
// or that neither has a designated pool
if ((eitherHasPool && strcmp(firstAssignment.getPool(), requestAssignment.getPool()))
|| !eitherHasPool) {
assignmentQueue.pop();
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)) {
// construct the create assignment from the packet data
int numHeaderBytes = numBytesForPacketHeader(senderData);
Assignment createdAssignment(senderData + numHeaderBytes, receivedBytes - numHeaderBytes);
Assignment createdAssignment(senderData, receivedBytes);
qDebug() << "Received an assignment:" << createdAssignment;

View file

@ -6,6 +6,8 @@
// Copyright (c) 2013 HighFidelity, Inc. All rights reserved.
//
#include "PacketHeaders.h"
#include "Assignment.h"
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;
memcpy(&_direction, dataBuffer, sizeof(Assignment::Direction));
numBytesRead += sizeof(Assignment::Direction);
if (dataBuffer[0] == PACKET_TYPE_REQUEST_ASSIGNMENT) {
_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));
numBytesRead += sizeof(Assignment::Type);
int poolLength = strlen((const char*) dataBuffer + numBytesRead);
if (poolLength) {
if (dataBuffer[numBytesRead] != 0) {
int poolLength = strlen((const char*) dataBuffer + numBytesRead);
_pool = new char[poolLength + sizeof(char)];
strcpy(_pool, (char*) dataBuffer + numBytesRead);
numBytesRead += poolLength + sizeof(char);
@ -46,18 +54,24 @@ Assignment::Assignment(const unsigned char* dataBuffer, int numBytes) :
numBytesRead += sizeof(char);
}
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 numPackedBytes = 0;
memcpy(buffer, &_direction, sizeof(_direction));
numPackedBytes += sizeof(_direction);
memcpy(buffer + numPackedBytes, &_type, sizeof(_type));
numPackedBytes += sizeof(_type);
@ -72,8 +86,12 @@ int Assignment::packToBuffer(unsigned char* buffer) {
}
if (_domainSocket) {
memcpy(buffer + numPackedBytes, _domainSocket, sizeof(sockaddr));
numPackedBytes += sizeof(sockaddr);
buffer[numPackedBytes++] = (_domainSocket->sa_family == AF_INET) ? 4 : 6;
int numSocketBytes = (_domainSocket->sa_family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_in6);
memcpy(buffer + numPackedBytes, _domainSocket, numSocketBytes);
numPackedBytes += numSocketBytes;
}
return numPackedBytes;
@ -87,17 +105,15 @@ void Assignment::setDomainSocket(const sockaddr* domainSocket) {
_domainSocket = NULL;
}
if (!_domainSocket) {
// create a new sockaddr or sockaddr_in depending on what type of address this is
if (domainSocket->sa_family == AF_INET) {
sockaddr_in* newSocket = new sockaddr_in;
memcpy(newSocket, domainSocket, sizeof(sockaddr_in));
_domainSocket = (sockaddr*) newSocket;
} else {
sockaddr_in6* newSocket = new sockaddr_in6;
memcpy(newSocket, domainSocket, sizeof(sockaddr_in6));
_domainSocket = (sockaddr*) newSocket;
}
// create a new sockaddr or sockaddr_in depending on what type of address this is
if (domainSocket->sa_family == AF_INET) {
sockaddr_in* newSocket = new sockaddr_in;
memcpy(newSocket, domainSocket, sizeof(sockaddr_in));
_domainSocket = (sockaddr*) newSocket;
} else {
sockaddr_in6* newSocket = new sockaddr_in6;
memcpy(newSocket, domainSocket, sizeof(sockaddr_in6));
_domainSocket = (sockaddr*) newSocket;
}
}

View file

@ -21,6 +21,7 @@ public:
enum Direction {
Create,
Deploy,
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);
// return numBytesType + numBytesForPacketVersion(packetHeader + numBytesType);

View file

@ -49,7 +49,7 @@ PACKET_VERSION versionForPacketType(PACKET_TYPE type);
bool packetVersionMatch(unsigned char* packetHeader);
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);