mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 13:19:54 +02:00
update NodeList for new packet receive code
This commit is contained in:
parent
4442bb55d6
commit
d85fbbfb74
8 changed files with 143 additions and 202 deletions
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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; }
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue