first cut at support for verifying all protocol version compatibility
This commit is contained in:
parent
e07674134f
commit
1d9981e624
@ -56,10 +56,24 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "packetVersion:" << message->getVersion();
|
||||||
|
|
||||||
|
|
||||||
QDataStream packetStream(message->getMessage());
|
QDataStream packetStream(message->getMessage());
|
||||||
|
|
||||||
// read a NodeConnectionData object from the packet so we can pass around this data while we're inspecting it
|
// read a NodeConnectionData object from the packet so we can pass around this data while we're inspecting it
|
||||||
NodeConnectionData nodeConnection = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr());
|
NodeConnectionData nodeConnection = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr());
|
||||||
|
|
||||||
|
QByteArray myProtocolVersion = protocolVersionsSignature();
|
||||||
|
if (nodeConnection.protocolVersion != myProtocolVersion) {
|
||||||
|
QString protocolVersionError = "Protocol version mismatch - Domain version:" + QCoreApplication::applicationVersion();
|
||||||
|
qDebug() << "Protocol Version mismatch - denying connection.";
|
||||||
|
sendConnectionDeniedPacket(protocolVersionError, message->getSenderSockAddr(),
|
||||||
|
DomainHandler::ConnectionRefusedReason::ProtocolMismatch);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//qDebug() << __FUNCTION__ << "Protocol Version MATCH - continue with processing connection.";
|
||||||
|
|
||||||
|
|
||||||
if (nodeConnection.localSockAddr.isNull() || nodeConnection.publicSockAddr.isNull()) {
|
if (nodeConnection.localSockAddr.isNull() || nodeConnection.publicSockAddr.isNull()) {
|
||||||
qDebug() << "Unexpected data received for node local socket or public socket. Will not allow connection.";
|
qDebug() << "Unexpected data received for node local socket or public socket. Will not allow connection.";
|
||||||
@ -97,7 +111,9 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << " about to processAgentConnectRequest() ---------------------";
|
||||||
node = processAgentConnectRequest(nodeConnection, username, usernameSignature);
|
node = processAgentConnectRequest(nodeConnection, username, usernameSignature);
|
||||||
|
//qDebug() << __FUNCTION__ << " AFTER processAgentConnectRequest() node: " << node << " ---------------------";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node) {
|
if (node) {
|
||||||
@ -109,6 +125,9 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
|||||||
|
|
||||||
// signal that we just connected a node so the DomainServer can get it a list
|
// signal that we just connected a node so the DomainServer can get it a list
|
||||||
// and broadcast its presence right away
|
// and broadcast its presence right away
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << " about to connectedNode(node) ---------------------";
|
||||||
|
|
||||||
emit connectedNode(node);
|
emit connectedNode(node);
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Refusing connection from node at" << message->getSenderSockAddr();
|
qDebug() << "Refusing connection from node at" << message->getSenderSockAddr();
|
||||||
@ -332,7 +351,7 @@ SharedNodePointer DomainGatekeeper::addVerifiedNodeFromConnectRequest(const Node
|
|||||||
bool DomainGatekeeper::verifyUserSignature(const QString& username,
|
bool DomainGatekeeper::verifyUserSignature(const QString& username,
|
||||||
const QByteArray& usernameSignature,
|
const QByteArray& usernameSignature,
|
||||||
const HifiSockAddr& senderSockAddr) {
|
const HifiSockAddr& senderSockAddr) {
|
||||||
|
|
||||||
// it's possible this user can be allowed to connect, but we need to check their username signature
|
// it's possible this user can be allowed to connect, but we need to check their username signature
|
||||||
QByteArray publicKeyArray = _userPublicKeys.value(username);
|
QByteArray publicKeyArray = _userPublicKeys.value(username);
|
||||||
|
|
||||||
@ -370,7 +389,8 @@ bool DomainGatekeeper::verifyUserSignature(const QString& username,
|
|||||||
} else {
|
} else {
|
||||||
if (!senderSockAddr.isNull()) {
|
if (!senderSockAddr.isNull()) {
|
||||||
qDebug() << "Error decrypting username signature for " << username << "- denying connection.";
|
qDebug() << "Error decrypting username signature for " << username << "- denying connection.";
|
||||||
sendConnectionDeniedPacket("Error decrypting username signature.", senderSockAddr);
|
sendConnectionDeniedPacket("Error decrypting username signature.", senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason::LoginError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// free up the public key, we don't need it anymore
|
// free up the public key, we don't need it anymore
|
||||||
@ -382,13 +402,15 @@ bool DomainGatekeeper::verifyUserSignature(const QString& username,
|
|||||||
// we can't let this user in since we couldn't convert their public key to an RSA key we could use
|
// we can't let this user in since we couldn't convert their public key to an RSA key we could use
|
||||||
if (!senderSockAddr.isNull()) {
|
if (!senderSockAddr.isNull()) {
|
||||||
qDebug() << "Couldn't convert data to RSA key for" << username << "- denying connection.";
|
qDebug() << "Couldn't convert data to RSA key for" << username << "- denying connection.";
|
||||||
sendConnectionDeniedPacket("Couldn't convert data to RSA key.", senderSockAddr);
|
sendConnectionDeniedPacket("Couldn't convert data to RSA key.", senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason::LoginError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!senderSockAddr.isNull()) {
|
if (!senderSockAddr.isNull()) {
|
||||||
qDebug() << "Insufficient data to decrypt username signature - denying connection.";
|
qDebug() << "Insufficient data to decrypt username signature - denying connection.";
|
||||||
sendConnectionDeniedPacket("Insufficient data", senderSockAddr);
|
sendConnectionDeniedPacket("Insufficient data", senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason::LoginError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,7 +424,8 @@ bool DomainGatekeeper::isVerifiedAllowedUser(const QString& username, const QByt
|
|||||||
if (username.isEmpty()) {
|
if (username.isEmpty()) {
|
||||||
qDebug() << "Connect request denied - no username provided.";
|
qDebug() << "Connect request denied - no username provided.";
|
||||||
|
|
||||||
sendConnectionDeniedPacket("No username provided", senderSockAddr);
|
sendConnectionDeniedPacket("No username provided", senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason::LoginError);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -416,7 +439,8 @@ bool DomainGatekeeper::isVerifiedAllowedUser(const QString& username, const QByt
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Connect request denied for user" << username << "- not in allowed users list.";
|
qDebug() << "Connect request denied for user" << username << "- not in allowed users list.";
|
||||||
sendConnectionDeniedPacket("User not on whitelist.", senderSockAddr);
|
sendConnectionDeniedPacket("User not on whitelist.", senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason::NotAuthorized);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -452,7 +476,8 @@ bool DomainGatekeeper::isWithinMaxCapacity(const QString& username, const QByteA
|
|||||||
|
|
||||||
// deny connection from this user
|
// deny connection from this user
|
||||||
qDebug() << connectedUsers << "/" << maximumUserCapacity << "users connected, denying new connection.";
|
qDebug() << connectedUsers << "/" << maximumUserCapacity << "users connected, denying new connection.";
|
||||||
sendConnectionDeniedPacket("Too many connected users.", senderSockAddr);
|
sendConnectionDeniedPacket("Too many connected users.", senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason::TooManyUsers);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -516,7 +541,8 @@ void DomainGatekeeper::publicKeyJSONCallback(QNetworkReply& requestReply) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr) {
|
void DomainGatekeeper::sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason reasonCode) {
|
||||||
// this is an agent and we've decided we won't let them connect - send them a packet to deny connection
|
// this is an agent and we've decided we won't let them connect - send them a packet to deny connection
|
||||||
QByteArray utfString = reason.toUtf8();
|
QByteArray utfString = reason.toUtf8();
|
||||||
quint16 payloadSize = utfString.size();
|
quint16 payloadSize = utfString.size();
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
#include <QtNetwork/QNetworkReply>
|
#include <QtNetwork/QNetworkReply>
|
||||||
|
|
||||||
|
#include <DomainHandler.h>
|
||||||
|
|
||||||
#include <NLPacket.h>
|
#include <NLPacket.h>
|
||||||
#include <Node.h>
|
#include <Node.h>
|
||||||
#include <UUIDHasher.h>
|
#include <UUIDHasher.h>
|
||||||
@ -74,7 +76,8 @@ private:
|
|||||||
const HifiSockAddr& senderSockAddr);
|
const HifiSockAddr& senderSockAddr);
|
||||||
|
|
||||||
void sendConnectionTokenPacket(const QString& username, const HifiSockAddr& senderSockAddr);
|
void sendConnectionTokenPacket(const QString& username, const HifiSockAddr& senderSockAddr);
|
||||||
void sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr);
|
void sendConnectionDeniedPacket(const QString& reason, const HifiSockAddr& senderSockAddr,
|
||||||
|
DomainHandler::ConnectionRefusedReason reasonCode = DomainHandler::ConnectionRefusedReason::Unknown);
|
||||||
|
|
||||||
void pingPunchForConnectingPeer(const SharedNetworkPeer& peer);
|
void pingPunchForConnectingPeer(const SharedNetworkPeer& peer);
|
||||||
|
|
||||||
|
@ -303,6 +303,36 @@ const QString FULL_AUTOMATIC_NETWORKING_VALUE = "full";
|
|||||||
const QString IP_ONLY_AUTOMATIC_NETWORKING_VALUE = "ip";
|
const QString IP_ONLY_AUTOMATIC_NETWORKING_VALUE = "ip";
|
||||||
const QString DISABLED_AUTOMATIC_NETWORKING_VALUE = "disabled";
|
const QString DISABLED_AUTOMATIC_NETWORKING_VALUE = "disabled";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool DomainServer::packetVersionMatch(const udt::Packet& packet) {
|
||||||
|
PacketType headerType = NLPacket::typeInHeader(packet);
|
||||||
|
PacketVersion headerVersion = NLPacket::versionInHeader(packet);
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "type:" << headerType << "version:" << (int)headerVersion;
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||||
|
|
||||||
|
// This implements a special case that handles OLD clients which don't know how to negotiate matching
|
||||||
|
// protocol versions. We know these clients will sent DomainConnectRequest with older versions. We also
|
||||||
|
// know these clients will show a warning dialog if they get an EntityData with a protocol version they
|
||||||
|
// don't understand, so we can send them an empty EntityData with our latest version and they will
|
||||||
|
// warn the user that the protocol is not compatible
|
||||||
|
if (headerType == PacketType::DomainConnectRequest &&
|
||||||
|
headerVersion < static_cast<PacketVersion>(DomainConnectRequestVersion::HasProtocolVersions)) {
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "OLD VERSION checkin sending an intentional bad packet -------------------------------";
|
||||||
|
|
||||||
|
auto packetWithBadVersion = NLPacket::create(PacketType::EntityData);
|
||||||
|
nodeList->sendPacket(std::move(packetWithBadVersion), packet.getSenderSockAddr());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// let the normal nodeList implementation handle all other packets.
|
||||||
|
return nodeList->isPacketVerified(packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
|
void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
|
||||||
|
|
||||||
const QString CUSTOM_LOCAL_PORT_OPTION = "metaverse.local_port";
|
const QString CUSTOM_LOCAL_PORT_OPTION = "metaverse.local_port";
|
||||||
@ -376,6 +406,10 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) {
|
|||||||
|
|
||||||
// add whatever static assignments that have been parsed to the queue
|
// add whatever static assignments that have been parsed to the queue
|
||||||
addStaticAssignmentsToQueue();
|
addStaticAssignmentsToQueue();
|
||||||
|
|
||||||
|
// set packetVersionMatch as the verify packet operator for the udt::Socket
|
||||||
|
//using std::placeholders::_1;
|
||||||
|
nodeList->setPacketFilterOperator(&DomainServer::packetVersionMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString ACCESS_TOKEN_KEY_PATH = "metaverse.access_token";
|
const QString ACCESS_TOKEN_KEY_PATH = "metaverse.access_token";
|
||||||
@ -666,6 +700,8 @@ void DomainServer::populateDefaultStaticAssignmentsExcludingTypes(const QSet<Ass
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::processListRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
void DomainServer::processListRequestPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "---------------";
|
||||||
|
|
||||||
QDataStream packetStream(message->getMessage());
|
QDataStream packetStream(message->getMessage());
|
||||||
NodeConnectionData nodeRequestData = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr(), false);
|
NodeConnectionData nodeRequestData = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr(), false);
|
||||||
@ -746,6 +782,9 @@ void DomainServer::handleConnectedNode(SharedNodePointer newNode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) {
|
void DomainServer::sendDomainListToNode(const SharedNodePointer& node, const HifiSockAddr &senderSockAddr) {
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "---------------";
|
||||||
|
|
||||||
const int NUM_DOMAIN_LIST_EXTENDED_HEADER_BYTES = NUM_BYTES_RFC4122_UUID + 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
|
||||||
|
@ -99,6 +99,8 @@ private:
|
|||||||
|
|
||||||
void optionallyGetTemporaryName(const QStringList& arguments);
|
void optionallyGetTemporaryName(const QStringList& arguments);
|
||||||
|
|
||||||
|
static bool packetVersionMatch(const udt::Packet& packet);
|
||||||
|
|
||||||
bool resetAccountManagerAccessToken();
|
bool resetAccountManagerAccessToken();
|
||||||
|
|
||||||
void setupAutomaticNetworking();
|
void setupAutomaticNetworking();
|
||||||
|
@ -19,6 +19,15 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
|
|||||||
|
|
||||||
if (isConnectRequest) {
|
if (isConnectRequest) {
|
||||||
dataStream >> newHeader.connectUUID;
|
dataStream >> newHeader.connectUUID;
|
||||||
|
|
||||||
|
// Read out the protocol version signature from the connect message
|
||||||
|
char* rawBytes;
|
||||||
|
uint length;
|
||||||
|
|
||||||
|
// FIXME -- do we need to delete the rawBytes after it's been copied into the QByteArray?
|
||||||
|
dataStream.readBytes(rawBytes, length);
|
||||||
|
newHeader.protocolVersion = QByteArray(rawBytes, length);
|
||||||
|
//qDebug() << __FUNCTION__ << "...got protocol version from node... version:" << newHeader.protocolVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
dataStream >> newHeader.nodeType
|
dataStream >> newHeader.nodeType
|
||||||
|
@ -28,6 +28,8 @@ public:
|
|||||||
HifiSockAddr senderSockAddr;
|
HifiSockAddr senderSockAddr;
|
||||||
QList<NodeType_t> interestList;
|
QList<NodeType_t> interestList;
|
||||||
QString placeName;
|
QString placeName;
|
||||||
|
|
||||||
|
QByteArray protocolVersion;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -631,6 +631,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||||||
connect(&domainHandler, SIGNAL(connectedToDomain(const QString&)), SLOT(updateWindowTitle()));
|
connect(&domainHandler, SIGNAL(connectedToDomain(const QString&)), SLOT(updateWindowTitle()));
|
||||||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
|
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
|
||||||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails()));
|
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails()));
|
||||||
|
|
||||||
|
connect(&domainHandler, &DomainHandler::resetting, nodeList.data(), &NodeList::resetDomainServerCheckInVersion);
|
||||||
|
|
||||||
// update our location every 5 seconds in the metaverse server, assuming that we are authenticated with one
|
// update our location every 5 seconds in the metaverse server, assuming that we are authenticated with one
|
||||||
const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * MSECS_PER_SEC;
|
const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * MSECS_PER_SEC;
|
||||||
@ -653,7 +655,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||||||
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
|
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
|
||||||
connect(nodeList.data(), &NodeList::uuidChanged, getMyAvatar(), &MyAvatar::setSessionUUID);
|
connect(nodeList.data(), &NodeList::uuidChanged, getMyAvatar(), &MyAvatar::setSessionUUID);
|
||||||
connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID);
|
connect(nodeList.data(), &NodeList::uuidChanged, this, &Application::setSessionUUID);
|
||||||
connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset);
|
|
||||||
|
connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, this, &Application::limitOfSilentDomainCheckInsReached);
|
||||||
|
//connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset);
|
||||||
|
|
||||||
|
|
||||||
connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
connect(nodeList.data(), &NodeList::packetVersionMismatch, this, &Application::notifyPacketVersionMismatch);
|
||||||
|
|
||||||
// connect to appropriate slots on AccountManager
|
// connect to appropriate slots on AccountManager
|
||||||
@ -4569,6 +4575,21 @@ void Application::setSessionUUID(const QUuid& sessionUUID) const {
|
|||||||
Physics::setSessionUUID(sessionUUID);
|
Physics::setSessionUUID(sessionUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// If we're not getting anything back from the domain server checkin, it might be that the domain speaks an
|
||||||
|
// older version of the DomainConnectRequest protocal. We will attempt to send and older version of DomainConnectRequest.
|
||||||
|
// We won't actually complete the connection, but if the server responds, we know that it needs to be upgraded (or we
|
||||||
|
// need to be downgraded to talk to it).
|
||||||
|
void Application::limitOfSilentDomainCheckInsReached() {
|
||||||
|
//qDebug() << __FUNCTION__;
|
||||||
|
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
nodeList->downgradeDomainServerCheckInVersion(); // attempt to use an older domain checkin version
|
||||||
|
|
||||||
|
nodeList->reset();
|
||||||
|
}
|
||||||
|
|
||||||
bool Application::askToSetAvatarUrl(const QString& url) {
|
bool Application::askToSetAvatarUrl(const QString& url) {
|
||||||
QUrl realUrl(url);
|
QUrl realUrl(url);
|
||||||
if (realUrl.isLocalFile()) {
|
if (realUrl.isLocalFile()) {
|
||||||
|
@ -261,6 +261,12 @@ public slots:
|
|||||||
void resetSensors(bool andReload = false);
|
void resetSensors(bool andReload = false);
|
||||||
void setActiveFaceTracker() const;
|
void setActiveFaceTracker() const;
|
||||||
|
|
||||||
|
#if (PR_BUILD || DEV_BUILD)
|
||||||
|
void sendWrongProtocolVersionsSignature(bool checked) {
|
||||||
|
::sendWrongProtocolVersionsSignature(checked);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IVIEWHMD
|
#ifdef HAVE_IVIEWHMD
|
||||||
void setActiveEyeTracker();
|
void setActiveEyeTracker();
|
||||||
void calibrateEyeTracker1Point();
|
void calibrateEyeTracker1Point();
|
||||||
@ -314,6 +320,8 @@ private slots:
|
|||||||
bool displayAvatarAttachmentConfirmationDialog(const QString& name) const;
|
bool displayAvatarAttachmentConfirmationDialog(const QString& name) const;
|
||||||
|
|
||||||
void setSessionUUID(const QUuid& sessionUUID) const;
|
void setSessionUUID(const QUuid& sessionUUID) const;
|
||||||
|
void limitOfSilentDomainCheckInsReached();
|
||||||
|
|
||||||
void domainChanged(const QString& domainHostname);
|
void domainChanged(const QString& domainHostname);
|
||||||
void updateWindowTitle() const;
|
void updateWindowTitle() const;
|
||||||
void nodeAdded(SharedNodePointer node) const;
|
void nodeAdded(SharedNodePointer node) const;
|
||||||
|
@ -545,6 +545,13 @@ Menu::Menu() {
|
|||||||
addActionToQMenuAndActionHash(networkMenu, MenuOption::BandwidthDetails, 0,
|
addActionToQMenuAndActionHash(networkMenu, MenuOption::BandwidthDetails, 0,
|
||||||
dialogsManager.data(), SLOT(bandwidthDetails()));
|
dialogsManager.data(), SLOT(bandwidthDetails()));
|
||||||
|
|
||||||
|
#if (PR_BUILD || DEV_BUILD)
|
||||||
|
addCheckableActionToQMenuAndActionHash(networkMenu, MenuOption::SendWrongProtocolVersion, 0, false,
|
||||||
|
qApp, SLOT(sendWrongProtocolVersionsSignature(bool)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Developer > Timing >>>
|
// Developer > Timing >>>
|
||||||
MenuWrapper* timingMenu = developerMenu->addMenu("Timing");
|
MenuWrapper* timingMenu = developerMenu->addMenu("Timing");
|
||||||
|
@ -167,6 +167,7 @@ namespace MenuOption {
|
|||||||
const QString RunTimingTests = "Run Timing Tests";
|
const QString RunTimingTests = "Run Timing Tests";
|
||||||
const QString ScriptEditor = "Script Editor...";
|
const QString ScriptEditor = "Script Editor...";
|
||||||
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
const QString ScriptedMotorControl = "Enable Scripted Motor Control";
|
||||||
|
const QString SendWrongProtocolVersion = "Send wrong protocol version";
|
||||||
const QString SetHomeLocation = "Set Home Location";
|
const QString SetHomeLocation = "Set Home Location";
|
||||||
const QString ShowDSConnectTable = "Show Domain Connection Timing";
|
const QString ShowDSConnectTable = "Show Domain Connection Timing";
|
||||||
const QString ShowBordersEntityNodes = "Show Entity Nodes";
|
const QString ShowBordersEntityNodes = "Show Entity Nodes";
|
||||||
|
@ -16,6 +16,8 @@
|
|||||||
#include <QtCore/QString>
|
#include <QtCore/QString>
|
||||||
#include <QtScript/QScriptValue>
|
#include <QtScript/QScriptValue>
|
||||||
|
|
||||||
|
#include <DomainHandler.h>
|
||||||
|
|
||||||
class WebWindowClass;
|
class WebWindowClass;
|
||||||
|
|
||||||
class WindowScriptingInterface : public QObject, public Dependency {
|
class WindowScriptingInterface : public QObject, public Dependency {
|
||||||
@ -45,7 +47,7 @@ public slots:
|
|||||||
signals:
|
signals:
|
||||||
void domainChanged(const QString& domainHostname);
|
void domainChanged(const QString& domainHostname);
|
||||||
void svoImportRequested(const QString& url);
|
void svoImportRequested(const QString& url);
|
||||||
void domainConnectionRefused(const QString& reason);
|
void domainConnectionRefused(const QString& reasonMessage, DomainHandler::ConnectionRefusedReason reason = DomainHandler::ConnectionRefusedReason::Unknown);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
WebWindowClass* doCreateWebWindow(const QString& title, const QString& url, int width, int height);
|
WebWindowClass* doCreateWebWindow(const QString& title, const QString& url, int width, int height);
|
||||||
|
@ -355,34 +355,53 @@ void DomainHandler::processICEResponsePacket(QSharedPointer<ReceivedMessage> mes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DomainHandler::reasonSuggestsLogin(ConnectionRefusedReason reasonCode) {
|
||||||
|
switch (reasonCode) {
|
||||||
|
case ConnectionRefusedReason::LoginError:
|
||||||
|
case ConnectionRefusedReason::NotAuthorized:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
case ConnectionRefusedReason::Unknown:
|
||||||
|
case ConnectionRefusedReason::ProtocolMismatch:
|
||||||
|
case ConnectionRefusedReason::TooManyUsers:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer<ReceivedMessage> message) {
|
void DomainHandler::processDomainServerConnectionDeniedPacket(QSharedPointer<ReceivedMessage> message) {
|
||||||
// Read deny reason from packet
|
// Read deny reason from packet
|
||||||
|
ConnectionRefusedReason reasonCode = DomainHandler::ConnectionRefusedReason::Unknown;
|
||||||
quint16 reasonSize;
|
quint16 reasonSize;
|
||||||
message->readPrimitive(&reasonSize);
|
message->readPrimitive(&reasonSize);
|
||||||
QString reason = QString::fromUtf8(message->readWithoutCopy(reasonSize));
|
QString reasonMessage = QString::fromUtf8(message->readWithoutCopy(reasonSize));
|
||||||
|
|
||||||
// output to the log so the user knows they got a denied connection request
|
// output to the log so the user knows they got a denied connection request
|
||||||
// and check and signal for an access token so that we can make sure they are logged in
|
// and check and signal for an access token so that we can make sure they are logged in
|
||||||
qCWarning(networking) << "The domain-server denied a connection request: " << reason;
|
qCWarning(networking) << "The domain-server denied a connection request: " << reasonMessage;
|
||||||
qCWarning(networking) << "Make sure you are logged in.";
|
qCWarning(networking) << "Make sure you are logged in.";
|
||||||
|
|
||||||
if (!_domainConnectionRefusals.contains(reason)) {
|
if (!_domainConnectionRefusals.contains(reasonMessage)) {
|
||||||
_domainConnectionRefusals.append(reason);
|
_domainConnectionRefusals.append(reasonMessage);
|
||||||
emit domainConnectionRefused(reason);
|
emit domainConnectionRefused(reasonMessage, reasonCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto accountManager = DependencyManager::get<AccountManager>();
|
auto accountManager = DependencyManager::get<AccountManager>();
|
||||||
|
|
||||||
if (!_hasCheckedForAccessToken) {
|
// Some connection refusal reasons imply that a login is required. If so, suggest a new login
|
||||||
accountManager->checkAndSignalForAccessToken();
|
if (reasonSuggestsLogin(reasonCode)) {
|
||||||
_hasCheckedForAccessToken = true;
|
if (!_hasCheckedForAccessToken) {
|
||||||
}
|
accountManager->checkAndSignalForAccessToken();
|
||||||
|
_hasCheckedForAccessToken = true;
|
||||||
|
}
|
||||||
|
|
||||||
static const int CONNECTION_DENIALS_FOR_KEYPAIR_REGEN = 3;
|
static const int CONNECTION_DENIALS_FOR_KEYPAIR_REGEN = 3;
|
||||||
|
|
||||||
// force a re-generation of key-pair after CONNECTION_DENIALS_FOR_KEYPAIR_REGEN failed connection attempts
|
// force a re-generation of key-pair after CONNECTION_DENIALS_FOR_KEYPAIR_REGEN failed connection attempts
|
||||||
if (++_connectionDenialsSinceKeypairRegen >= CONNECTION_DENIALS_FOR_KEYPAIR_REGEN) {
|
if (++_connectionDenialsSinceKeypairRegen >= CONNECTION_DENIALS_FOR_KEYPAIR_REGEN) {
|
||||||
accountManager->generateNewUserKeypair();
|
accountManager->generateNewUserKeypair();
|
||||||
_connectionDenialsSinceKeypairRegen = 0;
|
_connectionDenialsSinceKeypairRegen = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,6 +84,15 @@ public:
|
|||||||
bool isSocketKnown() const { return !_sockAddr.getAddress().isNull(); }
|
bool isSocketKnown() const { return !_sockAddr.getAddress().isNull(); }
|
||||||
|
|
||||||
void softReset();
|
void softReset();
|
||||||
|
|
||||||
|
enum class ConnectionRefusedReason : uint8_t {
|
||||||
|
Unknown,
|
||||||
|
ProtocolMismatch,
|
||||||
|
LoginError,
|
||||||
|
NotAuthorized,
|
||||||
|
TooManyUsers
|
||||||
|
};
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setHostnameAndPort(const QString& hostname, quint16 port = DEFAULT_DOMAIN_SERVER_PORT);
|
void setHostnameAndPort(const QString& hostname, quint16 port = DEFAULT_DOMAIN_SERVER_PORT);
|
||||||
void setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id);
|
void setIceServerHostnameAndID(const QString& iceServerHostname, const QUuid& id);
|
||||||
@ -115,9 +124,10 @@ signals:
|
|||||||
void settingsReceived(const QJsonObject& domainSettingsObject);
|
void settingsReceived(const QJsonObject& domainSettingsObject);
|
||||||
void settingsReceiveFail();
|
void settingsReceiveFail();
|
||||||
|
|
||||||
void domainConnectionRefused(QString reason);
|
void domainConnectionRefused(QString reasonMessage, ConnectionRefusedReason reason = ConnectionRefusedReason::Unknown);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool reasonSuggestsLogin(ConnectionRefusedReason reasonCode);
|
||||||
void sendDisconnectPacket();
|
void sendDisconnectPacket();
|
||||||
void hardReset();
|
void hardReset();
|
||||||
|
|
||||||
|
@ -162,13 +162,17 @@ QUdpSocket& LimitedNodeList::getDTLSSocket() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool LimitedNodeList::isPacketVerified(const udt::Packet& packet) {
|
bool LimitedNodeList::isPacketVerified(const udt::Packet& packet) {
|
||||||
|
//qDebug() << __FUNCTION__;
|
||||||
return packetVersionMatch(packet) && packetSourceAndHashMatch(packet);
|
return packetVersionMatch(packet) && packetSourceAndHashMatch(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) {
|
bool LimitedNodeList::packetVersionMatch(const udt::Packet& packet) {
|
||||||
|
|
||||||
PacketType headerType = NLPacket::typeInHeader(packet);
|
PacketType headerType = NLPacket::typeInHeader(packet);
|
||||||
PacketVersion headerVersion = NLPacket::versionInHeader(packet);
|
PacketVersion headerVersion = NLPacket::versionInHeader(packet);
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "headerType:" << headerType << "version:" << (int)headerVersion;
|
||||||
|
|
||||||
if (headerVersion != versionForPacketType(headerType)) {
|
if (headerVersion != versionForPacketType(headerType)) {
|
||||||
|
|
||||||
static QMultiHash<QUuid, PacketType> sourcedVersionDebugSuppressMap;
|
static QMultiHash<QUuid, PacketType> sourcedVersionDebugSuppressMap;
|
||||||
|
@ -221,6 +221,10 @@ public:
|
|||||||
|
|
||||||
void setConnectionMaxBandwidth(int maxBandwidth) { _nodeSocket.setConnectionMaxBandwidth(maxBandwidth); }
|
void setConnectionMaxBandwidth(int maxBandwidth) { _nodeSocket.setConnectionMaxBandwidth(maxBandwidth); }
|
||||||
|
|
||||||
|
void setPacketFilterOperator(udt::PacketFilterOperator filterOperator) { _nodeSocket.setPacketFilterOperator(filterOperator); }
|
||||||
|
bool packetVersionMatch(const udt::Packet& packet);
|
||||||
|
bool isPacketVerified(const udt::Packet& packet);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reset();
|
void reset();
|
||||||
void eraseAllNodes();
|
void eraseAllNodes();
|
||||||
@ -267,8 +271,6 @@ protected:
|
|||||||
|
|
||||||
void setLocalSocket(const HifiSockAddr& sockAddr);
|
void setLocalSocket(const HifiSockAddr& sockAddr);
|
||||||
|
|
||||||
bool isPacketVerified(const udt::Packet& packet);
|
|
||||||
bool packetVersionMatch(const udt::Packet& packet);
|
|
||||||
bool packetSourceAndHashMatch(const udt::Packet& packet);
|
bool packetSourceAndHashMatch(const udt::Packet& packet);
|
||||||
void processSTUNResponse(std::unique_ptr<udt::BasePacket> packet);
|
void processSTUNResponse(std::unique_ptr<udt::BasePacket> packet);
|
||||||
|
|
||||||
|
@ -24,8 +24,8 @@ int NLPacket::maxPayloadSize(PacketType type, bool isPartOfMessage) {
|
|||||||
return Packet::maxPayloadSize(isPartOfMessage) - NLPacket::localHeaderSize(type);
|
return Packet::maxPayloadSize(isPartOfMessage) - NLPacket::localHeaderSize(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<NLPacket> NLPacket::create(PacketType type, qint64 size, bool isReliable, bool isPartOfMessage) {
|
std::unique_ptr<NLPacket> NLPacket::create(PacketType type, qint64 size, bool isReliable, bool isPartOfMessage, PacketVersion version) {
|
||||||
auto packet = std::unique_ptr<NLPacket>(new NLPacket(type, size, isReliable, isPartOfMessage));
|
auto packet = std::unique_ptr<NLPacket>(new NLPacket(type, size, isReliable, isPartOfMessage, version));
|
||||||
|
|
||||||
packet->open(QIODevice::ReadWrite);
|
packet->open(QIODevice::ReadWrite);
|
||||||
|
|
||||||
@ -61,13 +61,12 @@ std::unique_ptr<NLPacket> NLPacket::createCopy(const NLPacket& other) {
|
|||||||
return std::unique_ptr<NLPacket>(new NLPacket(other));
|
return std::unique_ptr<NLPacket>(new NLPacket(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
NLPacket::NLPacket(PacketType type, qint64 size, bool isReliable, bool isPartOfMessage) :
|
NLPacket::NLPacket(PacketType type, qint64 size, bool isReliable, bool isPartOfMessage, PacketVersion version) :
|
||||||
Packet((size == -1) ? -1 : NLPacket::localHeaderSize(type) + size, isReliable, isPartOfMessage),
|
Packet((size == -1) ? -1 : NLPacket::localHeaderSize(type) + size, isReliable, isPartOfMessage),
|
||||||
_type(type),
|
_type(type),
|
||||||
_version(versionForPacketType(type))
|
_version((version == 0) ? versionForPacketType(type) : version)
|
||||||
{
|
{
|
||||||
adjustPayloadStartAndCapacity(NLPacket::localHeaderSize(_type));
|
adjustPayloadStartAndCapacity(NLPacket::localHeaderSize(_type));
|
||||||
|
|
||||||
writeTypeAndVersion();
|
writeTypeAndVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ public:
|
|||||||
sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH;
|
sizeof(PacketType) + sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID + NUM_BYTES_MD5_HASH;
|
||||||
|
|
||||||
static std::unique_ptr<NLPacket> create(PacketType type, qint64 size = -1,
|
static std::unique_ptr<NLPacket> create(PacketType type, qint64 size = -1,
|
||||||
bool isReliable = false, bool isPartOfMessage = false);
|
bool isReliable = false, bool isPartOfMessage = false, PacketVersion version = 0);
|
||||||
|
|
||||||
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
|
static std::unique_ptr<NLPacket> fromReceivedPacket(std::unique_ptr<char[]> data, qint64 size,
|
||||||
const HifiSockAddr& senderSockAddr);
|
const HifiSockAddr& senderSockAddr);
|
||||||
@ -73,7 +73,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
NLPacket(PacketType type, qint64 size = -1, bool forceReliable = false, bool isPartOfMessage = false);
|
NLPacket(PacketType type, qint64 size = -1, bool forceReliable = false, bool isPartOfMessage = false, PacketVersion version = 0);
|
||||||
NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
NLPacket(std::unique_ptr<char[]> data, qint64 size, const HifiSockAddr& senderSockAddr);
|
||||||
|
|
||||||
NLPacket(const NLPacket& other);
|
NLPacket(const NLPacket& other);
|
||||||
|
@ -292,7 +292,9 @@ void NodeList::sendDomainServerCheckIn() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto domainPacket = NLPacket::create(domainPacketType);
|
auto packetVersion = (domainPacketType == PacketType::DomainConnectRequest) ? _domainConnectRequestVersion : 0;
|
||||||
|
//qDebug() << __FUNCTION__ << " NLPacket::create() version:" << (int)packetVersion;
|
||||||
|
auto domainPacket = NLPacket::create(domainPacketType, -1, false, false, packetVersion);
|
||||||
|
|
||||||
QDataStream packetStream(domainPacket.get());
|
QDataStream packetStream(domainPacket.get());
|
||||||
|
|
||||||
@ -312,12 +314,28 @@ void NodeList::sendDomainServerCheckIn() {
|
|||||||
|
|
||||||
// pack the connect UUID for this connect request
|
// pack the connect UUID for this connect request
|
||||||
packetStream << connectUUID;
|
packetStream << connectUUID;
|
||||||
|
|
||||||
|
// include the protocol version signature in our connect request
|
||||||
|
if (_domainConnectRequestVersion >= static_cast<PacketVersion>(DomainConnectRequestVersion::HasProtocolVersions)) {
|
||||||
|
QByteArray protocolVersionSig = protocolVersionsSignature();
|
||||||
|
packetStream.writeBytes(protocolVersionSig.constData(), protocolVersionSig.size());
|
||||||
|
//qDebug() << __FUNCTION__ << " including protocol version --------------------------";
|
||||||
|
} else {
|
||||||
|
//qDebug() << __FUNCTION__ << "_domainConnectRequestVersion less than HasProtocolVersions - not including protocol version";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//qDebug() << __FUNCTION__ << "NOT a DomainConnnectRequest ----------- not including checkin details -------";
|
||||||
}
|
}
|
||||||
|
|
||||||
// pack our data to send to the domain-server including
|
// pack our data to send to the domain-server including
|
||||||
// the hostname information (so the domain-server can see which place name we came in on)
|
// the hostname information (so the domain-server can see which place name we came in on)
|
||||||
packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList()
|
packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList();
|
||||||
<< DependencyManager::get<AddressManager>()->getPlaceName();
|
if (_domainConnectRequestVersion >= static_cast<PacketVersion>(DomainConnectRequestVersion::HasHostname)) {
|
||||||
|
packetStream << DependencyManager::get<AddressManager>()->getPlaceName();
|
||||||
|
//qDebug() << __FUNCTION__ << " including host name --------------------------";
|
||||||
|
} else {
|
||||||
|
//qDebug() << __FUNCTION__ << "_domainConnectRequestVersion less than HasHostname - not including host name";
|
||||||
|
}
|
||||||
|
|
||||||
if (!_domainHandler.isConnected()) {
|
if (!_domainHandler.isConnected()) {
|
||||||
DataServerAccountInfo& accountInfo = accountManager->getAccountInfo();
|
DataServerAccountInfo& accountInfo = accountManager->getAccountInfo();
|
||||||
@ -345,6 +363,7 @@ void NodeList::sendDomainServerCheckIn() {
|
|||||||
|
|
||||||
// increment the count of un-replied check-ins
|
// increment the count of un-replied check-ins
|
||||||
_numNoReplyDomainCheckIns++;
|
_numNoReplyDomainCheckIns++;
|
||||||
|
//qDebug() << __FUNCTION__ << " _numNoReplyDomainCheckIns:" << _numNoReplyDomainCheckIns << " --------------------------";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,15 +523,22 @@ void NodeList::processDomainServerConnectionTokenPacket(QSharedPointer<ReceivedM
|
|||||||
}
|
}
|
||||||
|
|
||||||
void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message) {
|
void NodeList::processDomainServerList(QSharedPointer<ReceivedMessage> message) {
|
||||||
|
//qDebug() << __FUNCTION__;
|
||||||
|
|
||||||
if (_domainHandler.getSockAddr().isNull()) {
|
if (_domainHandler.getSockAddr().isNull()) {
|
||||||
// refuse to process this packet if we aren't currently connected to the DS
|
// refuse to process this packet if we aren't currently connected to the DS
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "_numNoReplyDomainCheckIns:" << _numNoReplyDomainCheckIns;
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
|
//qDebug() << __FUNCTION__ << "RESET.... _numNoReplyDomainCheckIns:" << _numNoReplyDomainCheckIns;
|
||||||
|
|
||||||
// emit our signal so listeners know we just heard from the DS
|
// emit our signal so listeners know we just heard from the DS
|
||||||
|
//qDebug() << __FUNCTION__ << "about to emit receivedDomainServerList() -----------------------------------------------";
|
||||||
emit receivedDomainServerList();
|
emit receivedDomainServerList();
|
||||||
|
|
||||||
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList);
|
DependencyManager::get<NodeList>()->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveDSList);
|
||||||
|
@ -68,6 +68,13 @@ public:
|
|||||||
|
|
||||||
void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; }
|
void setIsShuttingDown(bool isShuttingDown) { _isShuttingDown = isShuttingDown; }
|
||||||
|
|
||||||
|
/// downgrades the DomainConnnectRequest PacketVersion to attempt to probe for older domain servers
|
||||||
|
void downgradeDomainServerCheckInVersion() {
|
||||||
|
qDebug() << __FUNCTION__ << "----------------------------------------------------------";
|
||||||
|
_domainConnectRequestVersion--;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reset();
|
void reset();
|
||||||
void sendDomainServerCheckIn();
|
void sendDomainServerCheckIn();
|
||||||
@ -85,6 +92,12 @@ public slots:
|
|||||||
|
|
||||||
void processICEPingPacket(QSharedPointer<ReceivedMessage> message);
|
void processICEPingPacket(QSharedPointer<ReceivedMessage> message);
|
||||||
|
|
||||||
|
void resetDomainServerCheckInVersion()
|
||||||
|
{
|
||||||
|
qDebug() << __FUNCTION__ << "----------------------------------------------------------";
|
||||||
|
_domainConnectRequestVersion = versionForPacketType(PacketType::DomainConnectRequest);
|
||||||
|
}
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void limitOfSilentDomainCheckInsReached();
|
void limitOfSilentDomainCheckInsReached();
|
||||||
void receivedDomainServerList();
|
void receivedDomainServerList();
|
||||||
@ -123,6 +136,8 @@ private:
|
|||||||
HifiSockAddr _assignmentServerSocket;
|
HifiSockAddr _assignmentServerSocket;
|
||||||
bool _isShuttingDown { false };
|
bool _isShuttingDown { false };
|
||||||
QTimer _keepAlivePingTimer;
|
QTimer _keepAlivePingTimer;
|
||||||
|
|
||||||
|
PacketVersion _domainConnectRequestVersion = versionForPacketType(PacketType::DomainConnectRequest);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_NodeList_h
|
#endif // hifi_NodeList_h
|
||||||
|
@ -309,22 +309,29 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
|
|||||||
connectionType,
|
connectionType,
|
||||||
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage),
|
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage),
|
||||||
Q_ARG(SharedNodePointer, matchingNode));
|
Q_ARG(SharedNodePointer, matchingNode));
|
||||||
|
|
||||||
|
qDebug() << __FUNCTION__ << "line:" << __LINE__ << "success:" << success << "packetType:" << packetType;
|
||||||
|
|
||||||
} else if (metaMethod.parameterTypes().contains(QSHAREDPOINTER_NODE_NORMALIZED)) {
|
} else if (metaMethod.parameterTypes().contains(QSHAREDPOINTER_NODE_NORMALIZED)) {
|
||||||
success = metaMethod.invoke(listener.object,
|
success = metaMethod.invoke(listener.object,
|
||||||
connectionType,
|
connectionType,
|
||||||
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage),
|
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage),
|
||||||
Q_ARG(QSharedPointer<Node>, matchingNode));
|
Q_ARG(QSharedPointer<Node>, matchingNode));
|
||||||
|
|
||||||
|
qDebug() << __FUNCTION__ << "line:" << __LINE__ << "success:" << success << "packetType:" << packetType;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
success = metaMethod.invoke(listener.object,
|
success = metaMethod.invoke(listener.object,
|
||||||
connectionType,
|
connectionType,
|
||||||
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage));
|
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage));
|
||||||
|
qDebug() << __FUNCTION__ << "line:" << __LINE__ << "success:" << success << "packetType:" << packetType;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
listenerIsDead = true;
|
listenerIsDead = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
qDebug() << __FUNCTION__ << "line:" << __LINE__ << "Got verified unsourced packet list." << "packetType:" << packetType;
|
||||||
|
|
||||||
// qDebug() << "Got verified unsourced packet list: " << QString(nlPacketList->getMessage());
|
// qDebug() << "Got verified unsourced packet list: " << QString(nlPacketList->getMessage());
|
||||||
emit dataReceived(NodeType::Unassigned, receivedMessage->getSize());
|
emit dataReceived(NodeType::Unassigned, receivedMessage->getSize());
|
||||||
|
|
||||||
@ -332,6 +339,8 @@ void PacketReceiver::handleVerifiedMessage(QSharedPointer<ReceivedMessage> recei
|
|||||||
if (listener.object) {
|
if (listener.object) {
|
||||||
success = listener.method.invoke(listener.object,
|
success = listener.method.invoke(listener.object,
|
||||||
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage));
|
Q_ARG(QSharedPointer<ReceivedMessage>, receivedMessage));
|
||||||
|
|
||||||
|
qDebug() << __FUNCTION__ << "line:" << __LINE__ << "success:" << success << "packetType:" << packetType;
|
||||||
} else {
|
} else {
|
||||||
listenerIsDead = true;
|
listenerIsDead = true;
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,9 @@
|
|||||||
#include "PacketHeaders.h"
|
#include "PacketHeaders.h"
|
||||||
|
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
|
#include <QtCore/QDataStream>
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QMetaEnum>
|
#include <QtCore/QMetaEnum>
|
||||||
|
|
||||||
@ -58,9 +60,13 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||||||
case PacketType::AssetUpload:
|
case PacketType::AssetUpload:
|
||||||
// Removal of extension from Asset requests
|
// Removal of extension from Asset requests
|
||||||
return 18;
|
return 18;
|
||||||
|
|
||||||
|
case PacketType::DomainConnectionDenied:
|
||||||
|
return static_cast<PacketVersion>(DomainConnectionDeniedVersion::IncludesReasonCode);
|
||||||
|
|
||||||
case PacketType::DomainConnectRequest:
|
case PacketType::DomainConnectRequest:
|
||||||
// addition of referring hostname information
|
return static_cast<PacketVersion>(DomainConnectRequestVersion::HasProtocolVersions);
|
||||||
return 18;
|
|
||||||
default:
|
default:
|
||||||
return 17;
|
return 17;
|
||||||
}
|
}
|
||||||
@ -80,3 +86,36 @@ QDebug operator<<(QDebug debug, const PacketType& type) {
|
|||||||
debug.nospace().noquote() << (uint8_t) type << " (" << typeName << ")";
|
debug.nospace().noquote() << (uint8_t) type << " (" << typeName << ")";
|
||||||
return debug.space();
|
return debug.space();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (PR_BUILD || DEV_BUILD)
|
||||||
|
static bool sendWrongProtocolVersion = false;
|
||||||
|
void sendWrongProtocolVersionsSignature(bool sendWrongVersion) {
|
||||||
|
sendWrongProtocolVersion = sendWrongVersion;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QByteArray protocolVersionsSignature() {
|
||||||
|
static QByteArray protocolVersionSignature;
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
QByteArray buffer;
|
||||||
|
QDataStream stream(&buffer, QIODevice::WriteOnly);
|
||||||
|
uint8_t numberOfProtocols = static_cast<uint8_t>(PacketType::LAST_PACKET_TYPE) + 1;
|
||||||
|
stream << numberOfProtocols;
|
||||||
|
for (uint8_t packetType = 0; packetType < numberOfProtocols; packetType++) {
|
||||||
|
uint8_t packetTypeVersion = static_cast<uint8_t>(versionForPacketType(static_cast<PacketType>(packetType)));
|
||||||
|
stream << packetTypeVersion;
|
||||||
|
}
|
||||||
|
QCryptographicHash hash(QCryptographicHash::Md5);
|
||||||
|
hash.addData(buffer);
|
||||||
|
protocolVersionSignature = hash.result();
|
||||||
|
});
|
||||||
|
|
||||||
|
#if (PR_BUILD || DEV_BUILD)
|
||||||
|
if (sendWrongProtocolVersion) {
|
||||||
|
return QByteArray("INCORRECTVERSION"); // only for debugging version checking
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return protocolVersionSignature;
|
||||||
|
}
|
||||||
|
@ -61,7 +61,7 @@ public:
|
|||||||
AssignmentClientStatus,
|
AssignmentClientStatus,
|
||||||
NoisyMute,
|
NoisyMute,
|
||||||
AvatarIdentity,
|
AvatarIdentity,
|
||||||
AvatarBillboard,
|
TYPE_UNUSED_1,
|
||||||
DomainConnectRequest,
|
DomainConnectRequest,
|
||||||
DomainServerRequireDTLS,
|
DomainServerRequireDTLS,
|
||||||
NodeJsonStats,
|
NodeJsonStats,
|
||||||
@ -94,7 +94,8 @@ public:
|
|||||||
ICEServerHeartbeatDenied,
|
ICEServerHeartbeatDenied,
|
||||||
AssetMappingOperation,
|
AssetMappingOperation,
|
||||||
AssetMappingOperationReply,
|
AssetMappingOperationReply,
|
||||||
ICEServerHeartbeatACK
|
ICEServerHeartbeatACK,
|
||||||
|
LAST_PACKET_TYPE = ICEServerHeartbeatACK
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -109,6 +110,11 @@ extern const QSet<PacketType> NON_SOURCED_PACKETS;
|
|||||||
extern const QSet<PacketType> RELIABLE_PACKETS;
|
extern const QSet<PacketType> RELIABLE_PACKETS;
|
||||||
|
|
||||||
PacketVersion versionForPacketType(PacketType packetType);
|
PacketVersion versionForPacketType(PacketType packetType);
|
||||||
|
QByteArray protocolVersionsSignature(); /// returns a unqiue signature for all the current protocols
|
||||||
|
|
||||||
|
#if (PR_BUILD || DEV_BUILD)
|
||||||
|
void sendWrongProtocolVersionsSignature(bool sendWrongVersion); /// for debugging version negotiation
|
||||||
|
#endif
|
||||||
|
|
||||||
uint qHash(const PacketType& key, uint seed);
|
uint qHash(const PacketType& key, uint seed);
|
||||||
QDebug operator<<(QDebug debug, const PacketType& type);
|
QDebug operator<<(QDebug debug, const PacketType& type);
|
||||||
@ -179,4 +185,15 @@ enum class AvatarMixerPacketVersion : PacketVersion {
|
|||||||
AvatarEntities
|
AvatarEntities
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class DomainConnectRequestVersion : PacketVersion {
|
||||||
|
NoHostname = 17,
|
||||||
|
HasHostname,
|
||||||
|
HasProtocolVersions
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class DomainConnectionDeniedVersion : PacketVersion {
|
||||||
|
ReasonMessageOnly = 17,
|
||||||
|
IncludesReasonCode
|
||||||
|
};
|
||||||
|
|
||||||
#endif // hifi_PacketHeaders_h
|
#endif // hifi_PacketHeaders_h
|
||||||
|
Loading…
x
Reference in New Issue
Block a user