update NodeList for new packet receive code

This commit is contained in:
Stephen Birarda 2015-07-10 17:45:23 -07:00
parent 4442bb55d6
commit d85fbbfb74
8 changed files with 143 additions and 202 deletions

View file

@ -933,15 +933,17 @@ void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const Hif
// always send the node their own UUID back // always send the node their own UUID back
QDataStream domainListStream(&domainListPackets); QDataStream domainListStream(&domainListPackets);
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + 2; const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + NUM_BYTES_RFC4122_UUID + 2;
// setup the extended header for the domain list packets // setup the extended header for the domain list packets
// this data is at the beginning of each of the domain list packets // this data is at the beginning of each of the domain list packets
QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0); QByteArray extendedHeader(NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES, 0);
extendedHeader.replace(0, NUM_BYTES_RFC4122_UUID, node->getUUID().toRfc4122()); QDataStream extendedHeaderStream(&extendedHeader, &QIODevice::Append);
extendedHeader[NUM_BYTES_RFC4122_UUID] = (char) node->getCanAdjustLocks(); extendedHeaderStream << limitedNodeList->getSessionUUID().toRfc4122();
extendedHeader[NUM_BYTES_RFC4122_UUID + 1] = (char) node->getCanRez(); extendedHeaderStream << node->getUUID().toRfc4122();
extendedHeaderStream << (quint8) node->getCanAdjustLocks();
extendedHeaderStream << (quint8) node->getCanRez();
domainListPackets.setExtendedHeader(extendedHeader); domainListPackets.setExtendedHeader(extendedHeader);

View file

@ -281,12 +281,10 @@ void DomainHandler::settingsRequestFinished() {
settingsReply->deleteLater(); settingsReply->deleteLater();
} }
void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket) { void DomainHandler::processDTLSRequirementPacket(QSharedPointer<NLPacket> dtlsRequirementPacket) {
// figure out the port that the DS wants us to use for us to talk to them with DTLS // figure out the port that the DS wants us to use for us to talk to them with DTLS
int numBytesPacketHeader = numBytesForPacketHeader(dtlsRequirementPacket); unsigned short dtlsPort;
dtlsRequirementPacket->readPrimitive(&dtlsPort);
unsigned short dtlsPort = 0;
memcpy(&dtlsPort, dtlsRequirementPacket.data() + numBytesPacketHeader, sizeof(dtlsPort));
qCDebug(networking) << "domain-server DTLS port changed to" << dtlsPort << "- Enabling DTLS."; qCDebug(networking) << "domain-server DTLS port changed to" << dtlsPort << "- Enabling DTLS.";
@ -295,9 +293,13 @@ void DomainHandler::parseDTLSRequirementPacket(const QByteArray& dtlsRequirement
// initializeDTLSSession(); // initializeDTLSSession();
} }
void DomainHandler::processICEResponsePacket(const QByteArray& icePacket) { void DomainHandler::processICEResponsePacket(QSharedPointer<NLPacket> icePacket) {
QDataStream iceResponseStream(icePacket); if (!_icePeer.hasSockets()) {
iceResponseStream.skipRawData(numBytesForPacketHeader(icePacket)); // bail on processing this packet if our ice peer doesn't have sockets
return;
}
QDataStream iceResponseStream(icePacket.data());
iceResponseStream >> _icePeer; iceResponseStream >> _icePeer;

View file

@ -21,6 +21,7 @@
#include "HifiSockAddr.h" #include "HifiSockAddr.h"
#include "NetworkPeer.h" #include "NetworkPeer.h"
#include "NLPacket.h"
const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102;
const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT = 40103; const unsigned short DEFAULT_DOMAIN_SERVER_DTLS_PORT = 40103;
@ -69,8 +70,8 @@ public:
void requestDomainSettings(); void requestDomainSettings();
const QJsonObject& getSettingsObject() const { return _settingsObject; } const QJsonObject& getSettingsObject() const { return _settingsObject; }
void parseDTLSRequirementPacket(const QByteArray& dtlsRequirementPacket); void processDTLSRequirementPacket(QSharedPointer<NLPacket> dtlsRequirementPacket);
void processICEResponsePacket(const QByteArray& icePacket); void processICEResponsePacket(QSharedPointer<NLPacket> icePacket);
void setPendingPath(const QString& pendingPath) { _pendingPath = pendingPath; } void setPendingPath(const QString& pendingPath) { _pendingPath = pendingPath; }
const QString& getPendingPath() { return _pendingPath; } const QString& getPendingPath() { return _pendingPath; }

View file

@ -369,9 +369,8 @@ std::unique_ptr<NLPacket> LimitedNodeList::constructPingPacket(PingType_t pingTy
return pingPacket; return pingPacket;
} }
std::unique_ptr<NLPacket> LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacket) { std::unique_ptr<NLPacket> LimitedNodeList::constructPingReplyPacket(QSharedPointer<NLPacket> pingPacket) {
QDataStream pingPacketStream(pingPacket); QDataStream pingPacketStream(pingPacket.data());
pingPacketStream.skipRawData(numBytesForPacketHeader(pingPacket));
PingType_t typeFromOriginalPing; PingType_t typeFromOriginalPing;
pingPacketStream >> typeFromOriginalPing; pingPacketStream >> typeFromOriginalPing;
@ -400,11 +399,11 @@ std::unique_ptr<NLPacket> LimitedNodeList::constructICEPingPacket(PingType_t pin
return icePingPacket; return icePingPacket;
} }
std::unique_ptr<NLPacket> LimitedNodeList::constructICEPingReplyPacket(const QByteArray& pingPacket, const QUuid& iceID) { std::unique_ptr<NLPacket> LimitedNodeList::constructICEPingReplyPacket(QSharedPointer<NLPacket> pingPacket, const QUuid& iceID) {
// pull out the ping type so we can reply back with that // pull out the ping type so we can reply back with that
PingType_t pingType; PingType_t pingType;
memcpy(&pingType, pingPacket.data() + NUM_BYTES_RFC4122_UUID, sizeof(PingType_t)); memcpy(&pingType, pingPacket->getPayload() + NUM_BYTES_RFC4122_UUID, sizeof(PingType_t));
int packetSize = NUM_BYTES_RFC4122_UUID + sizeof(PingType_t); int packetSize = NUM_BYTES_RFC4122_UUID + sizeof(PingType_t);
auto icePingReplyPacket = NLPacket::create(PacketType::ICEPingReply, packetSize); auto icePingReplyPacket = NLPacket::create(PacketType::ICEPingReply, packetSize);
@ -514,7 +513,7 @@ void LimitedNodeList::rebindNodeSocket() {
_nodeSocket.bind(QHostAddress::AnyIPv4, oldPort); _nodeSocket.bind(QHostAddress::AnyIPv4, oldPort);
} }
bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { bool LimitedNodeList::processSTUNResponse(QSharedPointer<NLPacket> packet) {
// check the cookie to make sure this is actually a STUN response // check the cookie to make sure this is actually a STUN response
// and read the first attribute and make sure it is a XOR_MAPPED_ADDRESS // and read the first attribute and make sure it is a XOR_MAPPED_ADDRESS
const int NUM_BYTES_MESSAGE_TYPE_AND_LENGTH = 4; const int NUM_BYTES_MESSAGE_TYPE_AND_LENGTH = 4;
@ -524,13 +523,13 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) {
int attributeStartIndex = NUM_BYTES_STUN_HEADER; int attributeStartIndex = NUM_BYTES_STUN_HEADER;
if (memcmp(packet.data() + NUM_BYTES_MESSAGE_TYPE_AND_LENGTH, if (memcmp(packet->getData() + NUM_BYTES_MESSAGE_TYPE_AND_LENGTH,
&RFC_5389_MAGIC_COOKIE_NETWORK_ORDER, &RFC_5389_MAGIC_COOKIE_NETWORK_ORDER,
sizeof(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER)) == 0) { sizeof(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER)) == 0) {
// enumerate the attributes to find XOR_MAPPED_ADDRESS_TYPE // enumerate the attributes to find XOR_MAPPED_ADDRESS_TYPE
while (attributeStartIndex < packet.size()) { while (attributeStartIndex < packet->getSizeWithHeader()) {
if (memcmp(packet.data() + attributeStartIndex, &XOR_MAPPED_ADDRESS_TYPE, sizeof(XOR_MAPPED_ADDRESS_TYPE)) == 0) { if (memcmp(packet->getData() + attributeStartIndex, &XOR_MAPPED_ADDRESS_TYPE, sizeof(XOR_MAPPED_ADDRESS_TYPE)) == 0) {
const int NUM_BYTES_STUN_ATTR_TYPE_AND_LENGTH = 4; const int NUM_BYTES_STUN_ATTR_TYPE_AND_LENGTH = 4;
const int NUM_BYTES_FAMILY_ALIGN = 1; const int NUM_BYTES_FAMILY_ALIGN = 1;
const uint8_t IPV4_FAMILY_NETWORK_ORDER = htons(0x01) >> 8; const uint8_t IPV4_FAMILY_NETWORK_ORDER = htons(0x01) >> 8;
@ -538,14 +537,14 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) {
int byteIndex = attributeStartIndex + NUM_BYTES_STUN_ATTR_TYPE_AND_LENGTH + NUM_BYTES_FAMILY_ALIGN; int byteIndex = attributeStartIndex + NUM_BYTES_STUN_ATTR_TYPE_AND_LENGTH + NUM_BYTES_FAMILY_ALIGN;
uint8_t addressFamily = 0; uint8_t addressFamily = 0;
memcpy(&addressFamily, packet.data() + byteIndex, sizeof(addressFamily)); memcpy(&addressFamily, packet->getData() + byteIndex, sizeof(addressFamily));
byteIndex += sizeof(addressFamily); byteIndex += sizeof(addressFamily);
if (addressFamily == IPV4_FAMILY_NETWORK_ORDER) { if (addressFamily == IPV4_FAMILY_NETWORK_ORDER) {
// grab the X-Port // grab the X-Port
uint16_t xorMappedPort = 0; uint16_t xorMappedPort = 0;
memcpy(&xorMappedPort, packet.data() + byteIndex, sizeof(xorMappedPort)); memcpy(&xorMappedPort, packet->getData() + byteIndex, sizeof(xorMappedPort));
uint16_t newPublicPort = ntohs(xorMappedPort) ^ (ntohl(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER) >> 16); uint16_t newPublicPort = ntohs(xorMappedPort) ^ (ntohl(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER) >> 16);
@ -553,7 +552,7 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) {
// grab the X-Address // grab the X-Address
uint32_t xorMappedAddress = 0; uint32_t xorMappedAddress = 0;
memcpy(&xorMappedAddress, packet.data() + byteIndex, sizeof(xorMappedAddress)); memcpy(&xorMappedAddress, packet->getData() + byteIndex, sizeof(xorMappedAddress));
uint32_t stunAddress = ntohl(xorMappedAddress) ^ ntohl(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER); uint32_t stunAddress = ntohl(xorMappedAddress) ^ ntohl(RFC_5389_MAGIC_COOKIE_NETWORK_ORDER);
@ -583,7 +582,7 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) {
const int NUM_BYTES_ATTRIBUTE_TYPE = 2; const int NUM_BYTES_ATTRIBUTE_TYPE = 2;
uint16_t attributeLength = 0; uint16_t attributeLength = 0;
memcpy(&attributeLength, packet.data() + attributeStartIndex + NUM_BYTES_ATTRIBUTE_TYPE, memcpy(&attributeLength, packet->getData() + attributeStartIndex + NUM_BYTES_ATTRIBUTE_TYPE,
sizeof(attributeLength)); sizeof(attributeLength));
attributeLength = ntohs(attributeLength); attributeLength = ntohs(attributeLength);

View file

@ -169,12 +169,12 @@ public:
void resetPacketStats(); void resetPacketStats();
std::unique_ptr<NLPacket> constructPingPacket(PingType_t pingType = PingType::Agnostic); std::unique_ptr<NLPacket> constructPingPacket(PingType_t pingType = PingType::Agnostic);
std::unique_ptr<NLPacket> constructPingReplyPacket(const QByteArray& pingPacket); std::unique_ptr<NLPacket> constructPingReplyPacket(QSharedPointer<NLPacket> pingPacket);
std::unique_ptr<NLPacket> constructICEPingPacket(PingType_t pingType, const QUuid& iceID); std::unique_ptr<NLPacket> constructICEPingPacket(PingType_t pingType, const QUuid& iceID);
std::unique_ptr<NLPacket> constructICEPingReplyPacket(const QByteArray& pingPacket, const QUuid& iceID); std::unique_ptr<NLPacket> constructICEPingReplyPacket(QSharedPointer<NLPacket> pingPacket, const QUuid& iceID);
virtual bool processSTUNResponse(const QByteArray& packet); virtual bool processSTUNResponse(QSharedPointer<NLPacket> packet);
void sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr); void sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr);
void sendPeerQueryToIceServer(const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, const QUuid& peerID); void sendPeerQueryToIceServer(const HifiSockAddr& iceServerSockAddr, const QUuid& clientID, const QUuid& peerID);

View file

@ -92,16 +92,16 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
startSTUNPublicSocketUpdate(); startSTUNPublicSocketUpdate();
auto& packetReceiver = getPacketReceiver(); auto& packetReceiver = getPacketReceiver();
packetReceiver.registerPacketListener(PacketType::DomainList, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::DomainList, this, "processDomainServerList");
packetReceiver.registerPacketListener(PacketType::DomainServerAddedNode, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::DomainServerAddedNode, this, "processDomainServerAddedNode");
packetReceiver.registerPacketListener(PacketType::DomainServerRequireDTLS, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::DomainServerRequireDTLS, &_domainHandler, "processDTLSRequirementPacket");
packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::DomainServerPathResponse, this, "processDomainServerPathQueryResponse");
packetReceiver.registerPacketListener(PacketType::Ping, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::ICEServerPeerInformation, &_domainHandler, "processICEResponsePacket");
packetReceiver.registerPacketListener(PacketType::PingReply, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::Ping, this, "processPingPacket");
packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::PingReply, this, "processPingReplyPacket");
packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::ICEPing, this, "processICEPingPacket");
packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::ICEPingReply, this, "processICEPingReplyPacket");
packetReceiver.registerPacketListener(PacketType::DomainServerPathResponse, this, "processReceivedPacket"); packetReceiver.registerPacketListener(PacketType::StunResponse, this, "processSTUNResponse");
} }
qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) { qint64 NodeList::sendStats(const QJsonObject& statsObject, const HifiSockAddr& destination) {
@ -128,9 +128,8 @@ qint64 NodeList::sendStatsToDomainServer(const QJsonObject& statsObject) {
return sendStats(statsObject, _domainHandler.getSockAddr()); return sendStats(statsObject, _domainHandler.getSockAddr());
} }
void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode) { void NodeList::timePingReply(QSharedPointer<NLPacket> packet, const SharedNodePointer& sendingNode) {
QDataStream packetStream(packet); QDataStream packetStream(packet.data());
packetStream.skipRawData(numBytesForPacketHeader(packet));
quint8 pingType; quint8 pingType;
quint64 ourOriginalTime, othersReplyTime; quint64 ourOriginalTime, othersReplyTime;
@ -164,108 +163,52 @@ void NodeList::timePingReply(const QByteArray& packet, const SharedNodePointer&
} }
} }
// TODO: Break this out into individual packet types void NodeList::processPingPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
void NodeList::processReceivedPacket(std::unique_ptr<NLPacket>, HifiSockAddr senderSockAddr) { // send back a reply
qDebug() << "Got packet!"; auto replyPacket = constructPingReplyPacket(packet);
const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr();
sendPacket(std::move(replyPacket), sendingNode, senderSockAddr);
// If we don't have a symmetric socket for this node and this socket doesn't match
// what we have for public and local then set it as the symmetric.
// This allows a server on a reachable port to communicate with nodes on symmetric NATs
if (sendingNode->getSymmetricSocket().isNull()) {
if (senderSockAddr != sendingNode->getLocalSocket() && senderSockAddr != sendingNode->getPublicSocket()) {
sendingNode->setSymmetricSocket(senderSockAddr);
}
}
} }
void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteArray& packet) { void NodeList::processPingReplyPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode) {
PacketType::Value packetType = packetTypeForPacket(packet); // activate the appropriate socket for this node, if not yet updated
switch (packetType) { activateSocketFromNodeCommunication(packet, sendingNode);
case PacketType::DomainList:
case PacketType::DomainServerAddedNode: {
if (!_domainHandler.getSockAddr().isNull()) {
// only process a packet from domain-server if we're talking to a domain
// TODO: how do we make sure this is actually the domain we want the list from (DTLS probably)
if (packetType == PacketType::DomainList) {
processDomainServerList(packet);
} else if (packetType == PacketType::DomainServerAddedNode) {
processDomainServerAddedNode(packet);
}
}
break;
}
case PacketType::DomainServerRequireDTLS: {
_domainHandler.parseDTLSRequirementPacket(packet);
break;
}
case PacketType::ICEServerPeerInformation: {
if (!_domainHandler.getICEPeer().hasSockets()) {
_domainHandler.processICEResponsePacket(packet);
}
break;
}
case PacketType::Ping: {
// send back a reply
SharedNodePointer matchingNode = sendingNodeForPacket(packet);
if (matchingNode) {
matchingNode->setLastHeardMicrostamp(usecTimestampNow());
auto replyPacket = constructPingReplyPacket(packet);
sendPacket(std::move(replyPacket), matchingNode, senderSockAddr);
// If we don't have a symmetric socket for this node and this socket doesn't match // set the ping time for this node for stat collection
// what we have for public and local then set it as the symmetric. timePingReply(packet, sendingNode);
// This allows a server on a reachable port to communicate with nodes on symmetric NATs }
if (matchingNode->getSymmetricSocket().isNull()) {
if (senderSockAddr != matchingNode->getLocalSocket() && senderSockAddr != matchingNode->getPublicSocket()) {
matchingNode->setSymmetricSocket(senderSockAddr);
}
}
}
break; void NodeList::processICEPingPacket(QSharedPointer<NLPacket> packet) {
// send back a reply
auto replyPacket = constructICEPingReplyPacket(packet, _domainHandler.getICEClientID());
sendPacket(std::move(replyPacket), packet->getSenderSockAddr());
}
void NodeList::processICEPingReplyPacket(QSharedPointer<NLPacket> packet) {
const HifiSockAddr& senderSockAddr = packet->getSenderSockAddr();
qCDebug(networking) << "Received reply from domain-server on" << senderSockAddr;
if (_domainHandler.getIP().isNull()) {
// for now we're unsafely assuming this came back from the domain
if (senderSockAddr == _domainHandler.getICEPeer().getLocalSocket()) {
qCDebug(networking) << "Connecting to domain using local socket";
_domainHandler.activateICELocalSocket();
} else if (senderSockAddr == _domainHandler.getICEPeer().getPublicSocket()) {
qCDebug(networking) << "Conecting to domain using public socket";
_domainHandler.activateICEPublicSocket();
} else {
qCDebug(networking) << "Reply does not match either local or public socket for domain. Will not connect.";
} }
case PacketType::PingReply: {
SharedNodePointer sendingNode = sendingNodeForPacket(packet);
if (sendingNode) {
sendingNode->setLastHeardMicrostamp(usecTimestampNow());
// activate the appropriate socket for this node, if not yet updated
activateSocketFromNodeCommunication(packet, sendingNode);
// set the ping time for this node for stat collection
timePingReply(packet, sendingNode);
}
break;
}
case PacketType::ICEPing: {
// send back a reply
auto replyPacket = constructICEPingReplyPacket(packet, _domainHandler.getICEClientID());
sendPacket(std::move(replyPacket), senderSockAddr);
break;
}
case PacketType::ICEPingReply: {
qCDebug(networking) << "Received reply from domain-server on" << senderSockAddr;
if (_domainHandler.getIP().isNull()) {
// for now we're unsafely assuming this came back from the domain
if (senderSockAddr == _domainHandler.getICEPeer().getLocalSocket()) {
qCDebug(networking) << "Connecting to domain using local socket";
_domainHandler.activateICELocalSocket();
} else if (senderSockAddr == _domainHandler.getICEPeer().getPublicSocket()) {
qCDebug(networking) << "Conecting to domain using public socket";
_domainHandler.activateICEPublicSocket();
} else {
qCDebug(networking) << "Reply does not match either local or public socket for domain. Will not connect.";
}
}
}
case PacketType::StunResponse: {
// a STUN packet begins with 00, we've checked the second zero with packetVersionMatch
// pass it along so it can be processed into our public address and port
processSTUNResponse(packet);
break;
}
case PacketType::DomainServerPathResponse: {
handleDSPathQueryResponse(packet);
break;
}
default:
LimitedNodeList::processNodeData(senderSockAddr, packet);
break;
} }
} }
@ -436,43 +379,30 @@ void NodeList::sendDSPathQuery(const QString& newPath) {
} }
} }
void NodeList::handleDSPathQueryResponse(const QByteArray& packet) { void NodeList::processDomainServerPathQueryResponse(QSharedPointer<NLPacket> packet) {
// This is a response to a path query we theoretically made. // This is a response to a path query we theoretically made.
// In the future we may want to check that this was actually from our DS and for a query we actually made. // In the future we may want to check that this was actually from our DS and for a query we actually made.
int numHeaderBytes = numBytesForPacketHeaderGivenPacketType(PacketType::DomainServerPathResponse);
const char* startPosition = packet.data() + numHeaderBytes;
const char* currentPosition = startPosition;
// figure out how many bytes the path query is // figure out how many bytes the path query is
qint16 numPathBytes; qint16 numPathBytes;
memcpy(&numPathBytes, currentPosition, sizeof(numPathBytes)); packet->readPrimitive(&numPathBytes);
currentPosition += sizeof(numPathBytes);
// make sure it is safe to pull the path // pull the path from the packet
if (numPathBytes <= packet.size() - numHeaderBytes - (currentPosition - startPosition)) { QString pathQuery = QString::fromUtf8(packet->read(numPathBytes));
// pull the path from the packet
QString pathQuery = QString::fromUtf8(currentPosition, numPathBytes);
currentPosition += numPathBytes;
// figure out how many bytes the viewpoint is // figure out how many bytes the viewpoint is
qint16 numViewpointBytes; qint16 numViewpointBytes;
memcpy(&numViewpointBytes, currentPosition, sizeof(numViewpointBytes)); packet->readPrimitive(&numViewpointBytes);
currentPosition += sizeof(numViewpointBytes);
// make sure it is safe to pull the viewpoint // pull the viewpoint from the packet
if (numViewpointBytes <= packet.size() - numHeaderBytes - (currentPosition - startPosition)) { QString viewpoint = QString::fromUtf8(packet->read(numViewpointBytes));
// pull the viewpoint from the packet
QString viewpoint = QString::fromUtf8(currentPosition, numViewpointBytes);
// Hand it off to the AddressManager so it can handle it as a relative viewpoint // Hand it off to the AddressManager so it can handle it as a relative viewpoint
if (DependencyManager::get<AddressManager>()->goToViewpointForPath(viewpoint, pathQuery)) { if (DependencyManager::get<AddressManager>()->goToViewpointForPath(viewpoint, pathQuery)) {
qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery;
} else { } else {
qCDebug(networking) << "Could not go to viewpoint" << viewpoint qCDebug(networking) << "Could not go to viewpoint" << viewpoint
<< "which was the lookup result for path" << pathQuery; << "which was the lookup result for path" << pathQuery;
}
}
} }
} }
@ -527,49 +457,51 @@ void NodeList::pingPunchForDomainServer() {
} }
} }
int NodeList::processDomainServerList(const QByteArray& packet) { void NodeList::processDomainServerList(QSharedPointer<NLPacket> packet) {
if (_domainHandler.getSockAddr().isNull()) {
// refuse to process this packet if we aren't currently connected to the DS
return;
}
// this is a packet from the domain server, reset the count of un-replied check-ins // this is a packet from the domain server, reset the count of un-replied check-ins
_numNoReplyDomainCheckIns = 0; _numNoReplyDomainCheckIns = 0;
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList); DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList);
QDataStream packetStream(packet.data());
// grab the domain's ID from the beginning of the packet
QUuid domainUUID;
packetStream >> domainUUID;
// if this was the first domain-server list from this domain, we've now connected // if this was the first domain-server list from this domain, we've now connected
if (!_domainHandler.isConnected()) { if (!_domainHandler.isConnected()) {
_domainHandler.setUUID(uuidFromPacketHeader(packet)); _domainHandler.setUUID(domainUUID);
_domainHandler.setIsConnected(true); _domainHandler.setIsConnected(true);
} }
int readNodes = 0;
QDataStream packetStream(packet);
packetStream.skipRawData(numBytesForPacketHeader(packet));
// pull our owner UUID from the packet, it's always the first thing // pull our owner UUID from the packet, it's always the first thing
QUuid newUUID; QUuid newUUID;
packetStream >> newUUID; packetStream >> newUUID;
setSessionUUID(newUUID); setSessionUUID(newUUID);
// TODO: when fixing this read these are actually chars now, not bools quint8 thisNodeCanAdjustLocks;
bool thisNodeCanAdjustLocks;
packetStream >> thisNodeCanAdjustLocks; packetStream >> thisNodeCanAdjustLocks;
setThisNodeCanAdjustLocks(thisNodeCanAdjustLocks); setThisNodeCanAdjustLocks((bool) thisNodeCanAdjustLocks);
bool thisNodeCanRez; quint8 thisNodeCanRez;
packetStream >> thisNodeCanRez; packetStream >> thisNodeCanRez;
setThisNodeCanRez(thisNodeCanRez); setThisNodeCanRez((bool) thisNodeCanRez);
// pull each node in the packet // pull each node in the packet
while (packetStream.device()->pos() < packet.size()) { while (packetStream.device()->pos() < packet->getSizeUsed()) {
parseNodeFromPacketStream(packetStream); parseNodeFromPacketStream(packetStream);
} }
return readNodes;
} }
void NodeList::processDomainServerAddedNode(const QByteArray& packet) { void NodeList::processDomainServerAddedNode(QSharedPointer<NLPacket> packet) {
// setup a QDataStream, skip the header // setup a QDataStream
QDataStream packetStream(packet); QDataStream packetStream(packet.data());
packetStream.skipRawData(numBytesForPacketHeader(packet));
// use our shared method to pull out the new node // use our shared method to pull out the new node
parseNodeFromPacketStream(packetStream); parseNodeFromPacketStream(packetStream);
@ -663,10 +595,9 @@ void NodeList::handleNodePingTimeout() {
} }
} }
void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode) { void NodeList::activateSocketFromNodeCommunication(QSharedPointer<NLPacket> packet, const SharedNodePointer& sendingNode) {
// deconstruct this ping packet to see if it is a public or local reply // deconstruct this ping packet to see if it is a public or local reply
QDataStream packetStream(packet); QDataStream packetStream(packet.data());
packetStream.skipRawData(numBytesForPacketHeader(packet));
quint8 pingType; quint8 pingType;
packetStream >> pingType; packetStream >> pingType;

View file

@ -71,6 +71,16 @@ public slots:
void reset(); void reset();
void sendDomainServerCheckIn(); void sendDomainServerCheckIn();
void handleDSPathQuery(const QString& newPath); void handleDSPathQuery(const QString& newPath);
void processDomainServerList(QSharedPointer<NLPacket> packet);
void processDomainServerAddedNode(QSharedPointer<NLPacket> packet);
void processDomainServerPathQueryResponse(QSharedPointer<NLPacket> packet);
void processPingPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);
void processPingReplyPacket(QSharedPointer<NLPacket> packet, SharedNodePointer sendingNode);
void processICEPingPacket(QSharedPointer<NLPacket> packet);
void processICEPingReplyPacket(QSharedPointer<NLPacket> packet);
signals: signals:
void limitOfSilentDomainCheckInsReached(); void limitOfSilentDomainCheckInsReached();
private slots: private slots:
@ -89,15 +99,11 @@ private:
void processDomainServerAuthRequest(const QByteArray& packet); void processDomainServerAuthRequest(const QByteArray& packet);
void requestAuthForDomainServer(); void requestAuthForDomainServer();
void activateSocketFromNodeCommunication(const QByteArray& packet, const SharedNodePointer& sendingNode); void activateSocketFromNodeCommunication(QSharedPointer<NLPacket> packet, const SharedNodePointer& sendingNode);
void timePingReply(const QByteArray& packet, const SharedNodePointer& sendingNode); void timePingReply(QSharedPointer<NLPacket> packet, const SharedNodePointer& sendingNode);
void handleDSPathQueryResponse(const QByteArray& packet);
void sendDSPathQuery(const QString& newPath); void sendDSPathQuery(const QString& newPath);
int processDomainServerList(const QByteArray& packet);
void processDomainServerAddedNode(const QByteArray& packet);
void parseNodeFromPacketStream(QDataStream& packetStream); void parseNodeFromPacketStream(QDataStream& packetStream);
void pingPunchForInactiveNode(const SharedNodePointer& node); void pingPunchForInactiveNode(const SharedNodePointer& node);

View file

@ -18,21 +18,21 @@
using namespace PacketType; using namespace PacketType;
const QSet<PacketType::Value> NON_VERIFIED_PACKETS = QSet<PacketType::Value>() const QSet<PacketType::Value> NON_VERIFIED_PACKETS = QSet<PacketType::Value>()
<< DomainServerRequireDTLS << DomainConnectRequest
<< DomainList << DomainListRequest << DomainConnectionDenied
<< CreateAssignment << RequestAssignment << StunResponse << CreateAssignment << RequestAssignment << StunResponse
<< NodeJsonStats << EntityQuery << NodeJsonStats << EntityQuery
<< OctreeDataNack << EntityEditNack << OctreeDataNack << EntityEditNack
<< Ping << Ping
<< PingReply << StopNode << PingReply << StopNode;
<< DomainServerPathQuery << DomainServerPathResponse
<< DomainServerAddedNode;
const QSet<PacketType::Value> SEQUENCE_NUMBERED_PACKETS = QSet<PacketType::Value>() << AvatarData; const QSet<PacketType::Value> SEQUENCE_NUMBERED_PACKETS = QSet<PacketType::Value>() << AvatarData;
const QSet<PacketType::Value> NON_SOURCED_PACKETS = QSet<PacketType::Value>() const QSet<PacketType::Value> NON_SOURCED_PACKETS = QSet<PacketType::Value>()
<< DomainServerRequireDTLS << DomainConnectRequest
<< DomainList << DomainListRequest << DomainConnectionDenied
<< DomainServerPathQuery << DomainServerPathResponse
<< DomainServerAddedNode
<< ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat << ICEServerPeerInformation << ICEServerQuery << ICEServerHeartbeat
<< ICEPing << ICEPingReply << DomainConnectRequest; << ICEPing << ICEPingReply;
int arithmeticCodingValueFromBuffer(const char* checkValue) { int arithmeticCodingValueFromBuffer(const char* checkValue) {
if (((uchar) *checkValue) < 255) { if (((uchar) *checkValue) < 255) {