handle ping out from node requiring ice connection to domain

This commit is contained in:
Stephen Birarda 2014-10-02 16:24:46 -07:00
parent c36774e85d
commit c7aaf0ce4a
8 changed files with 77 additions and 50 deletions

View file

@ -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;
}

View file

@ -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)

View file

@ -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);

View file

@ -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);
}

View file

@ -52,6 +52,14 @@ typedef QSharedPointer<Node> SharedNodePointer;
typedef QHash<QUuid, SharedNodePointer> 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();

View file

@ -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; }

View file

@ -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

View file

@ -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();