From c7aaf0ce4ac6d117bd98a607483f4368c72720bc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 2 Oct 2014 16:24:46 -0700 Subject: [PATCH] handle ping out from node requiring ice connection to domain --- domain-server/src/DomainServer.cpp | 6 +++ libraries/networking/src/DomainHandler.cpp | 2 +- libraries/networking/src/DomainHandler.h | 3 +- libraries/networking/src/LimitedNodeList.cpp | 34 ++++++++++++- libraries/networking/src/LimitedNodeList.h | 14 +++++- libraries/networking/src/NetworkPeer.h | 2 + libraries/networking/src/NodeList.cpp | 53 ++++++++------------ libraries/networking/src/NodeList.h | 13 +---- 8 files changed, 77 insertions(+), 50 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 78baf803fa..28765e0620 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1028,6 +1028,12 @@ void DomainServer::processDatagram(const QByteArray& receivedPacket, const HifiS case PacketTypeStunResponse: nodeList->processSTUNResponse(receivedPacket); break; + case PacketTypePing: { + QByteArray pingReplyPacket = nodeList->constructPingReplyPacket(receivedPacket); + nodeList->writeUnverifiedDatagram(pingReplyPacket, senderSockAddr); + + break; + } default: break; } diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index 2eb11f4922..d4da00db2c 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -135,7 +135,7 @@ void DomainHandler::setIceServerHostnameAndID(const QString& iceServerHostname, // re-set the domain info to connect to new domain hardReset(); - _uuid = id; + setUUID(id); _iceServerSockAddr = HifiSockAddr(iceServerHostname, ICE_SERVER_DEFAULT_PORT); qDebug() << "Domain ID changed to" << uuidStringWithoutCurlyBraces(_uuid) diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 4c58a2b615..f490fc5e65 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -56,7 +56,8 @@ public: void setAssignmentUUID(const QUuid& assignmentUUID) { _assignmentUUID = assignmentUUID; } bool requiresICE() const { return !_iceServerSockAddr.isNull(); } - NetworkPeer& getICEPeer() { return _icePeer; } + const HifiSockAddr& getICEServerSockAddr() const { return _iceServerSockAddr; } + const NetworkPeer& getICEPeer() const { return _icePeer; } bool isConnected() const { return _isConnected; } void setIsConnected(bool isConnected); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index b32fbe3b37..4d603e6929 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -459,6 +459,35 @@ unsigned LimitedNodeList::broadcastToNodes(const QByteArray& packet, const NodeS return n; } +QByteArray LimitedNodeList::constructPingPacket(PingType_t pingType) { + QByteArray pingPacket = byteArrayWithPopulatedHeader(PacketTypePing); + + QDataStream packetStream(&pingPacket, QIODevice::Append); + + packetStream << pingType; + packetStream << usecTimestampNow(); + + return pingPacket; +} + +QByteArray LimitedNodeList::constructPingReplyPacket(const QByteArray& pingPacket) { + QDataStream pingPacketStream(pingPacket); + pingPacketStream.skipRawData(numBytesForPacketHeader(pingPacket)); + + PingType_t typeFromOriginalPing; + pingPacketStream >> typeFromOriginalPing; + + quint64 timeFromOriginalPing; + pingPacketStream >> timeFromOriginalPing; + + QByteArray replyPacket = byteArrayWithPopulatedHeader(PacketTypePingReply); + QDataStream packetStream(&replyPacket, QIODevice::Append); + + packetStream << typeFromOriginalPing << timeFromOriginalPing << usecTimestampNow(); + + return replyPacket; +} + SharedNodePointer LimitedNodeList::soloNodeOfType(char nodeType) { if (memchr(SOLO_NODE_TYPES, nodeType, sizeof(SOLO_NODE_TYPES))) { @@ -619,7 +648,8 @@ bool LimitedNodeList::processSTUNResponse(const QByteArray& packet) { return false; } -void LimitedNodeList::sendHeartbeatToIceServer(QUuid headerID, const QUuid& connectionRequestID) { +void LimitedNodeList::sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr, + QUuid headerID, const QUuid& connectionRequestID) { if (headerID.isNull()) { headerID = _sessionUUID; @@ -637,5 +667,5 @@ void LimitedNodeList::sendHeartbeatToIceServer(QUuid headerID, const QUuid& conn << uuidStringWithoutCurlyBraces(connectionRequestID); } - _nodeSocket.writeDatagram(iceRequestByteArray, QHostAddress::LocalHost, ICE_SERVER_DEFAULT_PORT); + writeUnverifiedDatagram(iceRequestByteArray, iceServerSockAddr); } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 1e97ba8190..6f6c4539b8 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -52,6 +52,14 @@ typedef QSharedPointer SharedNodePointer; typedef QHash NodeHash; Q_DECLARE_METATYPE(SharedNodePointer) +typedef quint8 PingType_t; +namespace PingType { + const PingType_t Agnostic = 0; + const PingType_t Local = 1; + const PingType_t Public = 2; + const PingType_t Symmetric = 3; +} + class LimitedNodeList : public QObject { Q_OBJECT public: @@ -104,10 +112,14 @@ public: void getPacketStats(float &packetsPerSecond, float &bytesPerSecond); void resetPacketStats(); + QByteArray constructPingPacket(PingType_t pingType = PingType::Agnostic); + QByteArray constructPingReplyPacket(const QByteArray& pingPacket); + virtual void sendSTUNRequest(); virtual bool processSTUNResponse(const QByteArray& packet); - void sendHeartbeatToIceServer(QUuid headerID = QUuid(), const QUuid& connectRequestID = QUuid()); + void sendHeartbeatToIceServer(const HifiSockAddr& iceServerSockAddr, + QUuid headerID = QUuid(), const QUuid& connectRequestID = QUuid()); public slots: void reset(); void eraseAllNodes(); diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index c590c49cf3..1e9b61d9f2 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -30,6 +30,8 @@ public: NetworkPeer(const NetworkPeer &otherPeer); NetworkPeer& operator=(const NetworkPeer& otherPeer); + bool isNull() const { return _uuid.isNull(); } + const QUuid& getUUID() const { return _uuid; } void setUUID(const QUuid& uuid) { _uuid = uuid; } diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 0333b4fb34..25c86a41b8 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -64,6 +64,9 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned // clear our NodeList when the domain changes connect(&_domainHandler, &DomainHandler::hostnameChanged, this, &NodeList::reset); + // handle ICE signal from DS so connection is attempted immediately + connect(&_domainHandler, &DomainHandler::requestICEConnectionAttempt, this, &NodeList::handleICEConnectionToDomainServer); + // clear our NodeList when logout is requested connect(&AccountManager::getInstance(), &AccountManager::logoutComplete , this, &NodeList::reset); } @@ -158,6 +161,8 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr // set the ping time for this node for stat collection timePingReply(packet, sendingNode); + } else if (uuidFromPacketHeader(packet) == _domainHandler.getUUID()) { + qDebug() << "RECEIVED A REPLY FROM DOMAIN"; } break; @@ -247,7 +252,7 @@ void NodeList::sendDomainServerCheckIn() { // send a STUN request to figure it out sendSTUNRequest(); } else if (!_domainHandler.isConnected() && _domainHandler.requiresICE()) { - sendICERequestForDomainConnection(); + handleICEConnectionToDomainServer(); } else if (!_domainHandler.getIP().isNull()) { bool isUsingDTLS = false; @@ -304,11 +309,22 @@ void NodeList::sendDomainServerCheckIn() { } } -void NodeList::sendICERequestForDomainConnection() { - +void NodeList::handleICEConnectionToDomainServer() { static QUuid iceUUID = QUuid::createUuid(); - LimitedNodeList::sendHeartbeatToIceServer(iceUUID, _domainHandler.getUUID()); + if (_domainHandler.getICEPeer().isNull()) { + LimitedNodeList::sendHeartbeatToIceServer(_domainHandler.getICEServerSockAddr(), iceUUID, _domainHandler.getUUID()); + } else { + qDebug() << "Sending ping packets to establish connectivity with domain-server with ID" + << uuidStringWithoutCurlyBraces(_domainHandler.getUUID()); + + // send the ping packet to the local and public sockets for this node + QByteArray localPingPacket = constructPingPacket(PingType::Local); + writeDatagram(localPingPacket, _domainHandler.getICEPeer().getLocalSocket(), iceUUID); + + QByteArray publicPingPacket = constructPingPacket(PingType::Public); + writeDatagram(publicPingPacket, _domainHandler.getICEPeer().getPublicSocket(), iceUUID); + } } int NodeList::processDomainServerList(const QByteArray& packet) { @@ -382,35 +398,6 @@ void NodeList::sendAssignment(Assignment& assignment) { _nodeSocket.writeDatagram(packet, assignmentServerSocket->getAddress(), assignmentServerSocket->getPort()); } -QByteArray NodeList::constructPingPacket(PingType_t pingType) { - QByteArray pingPacket = byteArrayWithPopulatedHeader(PacketTypePing); - - QDataStream packetStream(&pingPacket, QIODevice::Append); - - packetStream << pingType; - packetStream << usecTimestampNow(); - - return pingPacket; -} - -QByteArray NodeList::constructPingReplyPacket(const QByteArray& pingPacket) { - QDataStream pingPacketStream(pingPacket); - pingPacketStream.skipRawData(numBytesForPacketHeader(pingPacket)); - - PingType_t typeFromOriginalPing; - pingPacketStream >> typeFromOriginalPing; - - quint64 timeFromOriginalPing; - pingPacketStream >> timeFromOriginalPing; - - QByteArray replyPacket = byteArrayWithPopulatedHeader(PacketTypePingReply); - QDataStream packetStream(&replyPacket, QIODevice::Append); - - packetStream << typeFromOriginalPing << timeFromOriginalPing << usecTimestampNow(); - - return replyPacket; -} - void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { // send the ping packet to the local and public sockets for this node diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index ad0f74e517..c1e2d12319 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -37,14 +37,6 @@ const int MAX_SILENT_DOMAIN_SERVER_CHECK_INS = 5; class Assignment; -typedef quint8 PingType_t; -namespace PingType { - const PingType_t Agnostic = 0; - const PingType_t Local = 1; - const PingType_t Public = 2; - const PingType_t Symmetric = 3; -} - class NodeList : public LimitedNodeList { Q_OBJECT public: @@ -69,9 +61,6 @@ public: void setAssignmentServerSocket(const HifiSockAddr& serverSocket) { _assignmentServerSocket = serverSocket; } void sendAssignment(Assignment& assignment); - - QByteArray constructPingPacket(PingType_t pingType = PingType::Agnostic); - QByteArray constructPingReplyPacket(const QByteArray& pingPacket); void pingPunchForInactiveNode(const SharedNodePointer& node); @@ -91,7 +80,7 @@ private: void sendSTUNRequest(); bool processSTUNResponse(const QByteArray& packet); - void sendICERequestForDomainConnection(); + void handleICEConnectionToDomainServer(); void processDomainServerAuthRequest(const QByteArray& packet); void requestAuthForDomainServer();