From 18a293c020f8bda43569c47478ad2a7fd1e7f094 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 28 Mar 2014 08:58:49 -0700 Subject: [PATCH 1/3] add a symmetric socket to the Node class --- libraries/shared/src/Node.cpp | 1 + libraries/shared/src/Node.h | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/Node.cpp b/libraries/shared/src/Node.cpp index dadf39f790..d300cd7ba0 100644 --- a/libraries/shared/src/Node.cpp +++ b/libraries/shared/src/Node.cpp @@ -51,6 +51,7 @@ Node::Node(const QUuid& uuid, char type, const HifiSockAddr& publicSocket, const _lastHeardMicrostamp(usecTimestampNow()), _publicSocket(publicSocket), _localSocket(localSocket), + _symmetricSocket(), _activeSocket(NULL), _connectionSecret(), _bytesReceivedMovingAverage(NULL), diff --git a/libraries/shared/src/Node.h b/libraries/shared/src/Node.h index 43ec5baf81..1c9ee97477 100644 --- a/libraries/shared/src/Node.h +++ b/libraries/shared/src/Node.h @@ -70,7 +70,9 @@ public: void setPublicSocket(const HifiSockAddr& publicSocket); const HifiSockAddr& getLocalSocket() const { return _localSocket; } void setLocalSocket(const HifiSockAddr& localSocket); - + const HifiSockAddr& getSymmetricSocket() const { return _symmetricSocket; } + void setSymmetricSocket(const HifiSockAddr& symmetricSocket) { _symmetricSocket = symmetricSocket; } + const HifiSockAddr* getActiveSocket() const { return _activeSocket; } void activatePublicSocket(); @@ -110,6 +112,7 @@ private: quint64 _lastHeardMicrostamp; HifiSockAddr _publicSocket; HifiSockAddr _localSocket; + HifiSockAddr _symmetricSocket; HifiSockAddr* _activeSocket; QUuid _connectionSecret; SimpleMovingAverage* _bytesReceivedMovingAverage; From f80b415497e6c1402ed46217280702fae0129f1b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 28 Mar 2014 09:07:30 -0700 Subject: [PATCH 2/3] handle activation and setting of symmetric socket --- libraries/shared/src/Node.cpp | 14 ++++++++++++++ libraries/shared/src/Node.h | 3 ++- libraries/shared/src/NodeList.cpp | 12 ++++++++++++ libraries/shared/src/NodeList.h | 1 + 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/Node.cpp b/libraries/shared/src/Node.cpp index d300cd7ba0..a4491fb707 100644 --- a/libraries/shared/src/Node.cpp +++ b/libraries/shared/src/Node.cpp @@ -85,6 +85,15 @@ void Node::setLocalSocket(const HifiSockAddr& localSocket) { _localSocket = localSocket; } +void Node::setSymmetricSocket(const HifiSockAddr& symmetricSocket) { + if (_activeSocket == &_symmetricSocket) { + // if the active socket was the symmetric socket then reset it to NULL + _activeSocket = NULL; + } + + _symmetricSocket = symmetricSocket; +} + void Node::activateLocalSocket() { qDebug() << "Activating local socket for node" << *this; _activeSocket = &_localSocket; @@ -95,6 +104,11 @@ void Node::activatePublicSocket() { _activeSocket = &_publicSocket; } +void Node::activateSymmetricSocket() { + qDebug() << "Activating symmetric socket for node" << *this; + _activeSocket = &_symmetricSocket; +} + void Node::recordBytesReceived(int bytesReceived) { if (!_bytesReceivedMovingAverage) { _bytesReceivedMovingAverage = new SimpleMovingAverage(100); diff --git a/libraries/shared/src/Node.h b/libraries/shared/src/Node.h index 1c9ee97477..79d75629a6 100644 --- a/libraries/shared/src/Node.h +++ b/libraries/shared/src/Node.h @@ -71,12 +71,13 @@ public: const HifiSockAddr& getLocalSocket() const { return _localSocket; } void setLocalSocket(const HifiSockAddr& localSocket); const HifiSockAddr& getSymmetricSocket() const { return _symmetricSocket; } - void setSymmetricSocket(const HifiSockAddr& symmetricSocket) { _symmetricSocket = symmetricSocket; } + void setSymmetricSocket(const HifiSockAddr& symmetricSocket); const HifiSockAddr* getActiveSocket() const { return _activeSocket; } void activatePublicSocket(); void activateLocalSocket(); + void activateSymmetricSocket(); const QUuid& getConnectionSecret() const { return _connectionSecret; } void setConnectionSecret(const QUuid& connectionSecret) { _connectionSecret = connectionSecret; } diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 761ea40d55..bcd40a8de4 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -294,6 +294,15 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr matchingNode->setLastHeardMicrostamp(usecTimestampNow()); QByteArray replyPacket = constructPingReplyPacket(packet); writeDatagram(replyPacket, matchingNode, 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 (matchingNode->getSymmetricSocket().isNull()) { + if (senderSockAddr != matchingNode->getLocalSocket() && senderSockAddr != matchingNode->getPublicSocket()) { + matchingNode->setSymmetricSocket(senderSockAddr); + } + } } break; @@ -879,6 +888,9 @@ void NodeList::activateSocketFromNodeCommunication(const QByteArray& packet, con sendingNode->activateLocalSocket(); } else if (pingType == PingType::Public && !sendingNode->getActiveSocket()) { sendingNode->activatePublicSocket(); + } else if (pingType == PingType::Symmetric && !sendingNode->getActiveSocket()) { + + } } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index d05d6a2fbc..182c72b670 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -58,6 +58,7 @@ 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 QObject { From 8b1b2d8d9901a07fa9483ef7a30fe743b70b5f91 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 28 Mar 2014 09:11:20 -0700 Subject: [PATCH 3/3] send a symmetric ping packet if appropriate when pinging nodes --- libraries/shared/src/NodeList.cpp | 9 +++++++-- libraries/shared/src/NodeList.h | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index bcd40a8de4..879377a2fd 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -791,7 +791,7 @@ QByteArray NodeList::constructPingReplyPacket(const QByteArray& pingPacket) { return replyPacket; } -void NodeList::pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& node) { +void NodeList::pingPunchForInactiveNode(const SharedNodePointer& node) { // send the ping packet to the local and public sockets for this node QByteArray localPingPacket = constructPingPacket(PingType::Local); @@ -799,6 +799,11 @@ void NodeList::pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& QByteArray publicPingPacket = constructPingPacket(PingType::Public); writeDatagram(publicPingPacket, node, node->getPublicSocket()); + + if (!node->getSymmetricSocket().isNull()) { + QByteArray symmetricPingPacket = constructPingPacket(PingType::Symmetric); + writeDatagram(symmetricPingPacket, node, node->getSymmetricSocket()); + } } SharedNodePointer NodeList::addOrUpdateNode(const QUuid& uuid, char nodeType, @@ -869,7 +874,7 @@ void NodeList::pingInactiveNodes() { foreach (const SharedNodePointer& node, getNodeHash()) { if (!node->getActiveSocket()) { // we don't have an active link to this node, ping it to set that up - pingPublicAndLocalSocketsForInactiveNode(node); + pingPunchForInactiveNode(node); } } } diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 182c72b670..34078b6a94 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -102,7 +102,7 @@ public: QByteArray constructPingPacket(PingType_t pingType = PingType::Agnostic); QByteArray constructPingReplyPacket(const QByteArray& pingPacket); - void pingPublicAndLocalSocketsForInactiveNode(const SharedNodePointer& node); + void pingPunchForInactiveNode(const SharedNodePointer& node); SharedNodePointer nodeWithUUID(const QUuid& nodeUUID, bool blockingLock = true); SharedNodePointer sendingNodeForPacket(const QByteArray& packet);