From 498d681d3e8d740cb8fb0d35d1ba3959ff93da56 Mon Sep 17 00:00:00 2001 From: Simon Walton <simon@highfidelity.io> Date: Fri, 7 Jun 2019 12:04:04 -0700 Subject: [PATCH 1/4] Force new IP port on local address change --- libraries/networking/src/LimitedNodeList.cpp | 8 ++++++-- libraries/networking/src/udt/Socket.cpp | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 0eda2ee2e0..97a12e4c71 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -1172,7 +1172,7 @@ void LimitedNodeList::stopInitialSTUNUpdate(bool success) { // We now setup a timer here to fire every so often to check that our IP address has not changed. // Or, if we failed - if will check if we can eventually get a public socket - const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 30 * 1000; + const int STUN_IP_ADDRESS_CHECK_INTERVAL_MSECS = 10 * 1000; QTimer* stunOccasionalTimer = new QTimer { this }; connect(stunOccasionalTimer, &QTimer::timeout, this, &LimitedNodeList::sendSTUNRequest); @@ -1230,12 +1230,16 @@ void LimitedNodeList::errorTestingLocalSocket() { } void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) { - if (sockAddr != _localSockAddr) { + if (sockAddr.getAddress() != _localSockAddr.getAddress()) { if (_localSockAddr.isNull()) { qCInfo(networking) << "Local socket is" << sockAddr; } else { qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr; + if (_hasTCPCheckedLocalSocket) { // Force a port change for NAT: + _nodeSocket.rebind(0); + _localSockAddr.setPort(_nodeSocket.localPort()); + } } _localSockAddr = sockAddr; diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 98d6c0a6be..5a3111a7eb 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -73,6 +73,7 @@ void Socket::rebind() { void Socket::rebind(quint16 localPort) { _udpSocket.close(); + _udpSocket.waitForDisconnected(); bind(QHostAddress::AnyIPv4, localPort); } From c088fab60602b9f5455f5d1e05208db2eff7c038 Mon Sep 17 00:00:00 2001 From: Simon Walton <simon@highfidelity.io> Date: Fri, 7 Jun 2019 16:23:38 -0700 Subject: [PATCH 2/4] Fix annoying typo --- libraries/networking/src/LimitedNodeList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 97a12e4c71..d8d43f4b02 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -983,7 +983,7 @@ void LimitedNodeList::sendSTUNRequest() { const int NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL = 10; if (!_hasCompletedInitialSTUN) { - qCDebug(networking) << "Sending intial stun request to" << STUN_SERVER_HOSTNAME; + qCDebug(networking) << "Sending initial stun request to" << STUN_SERVER_HOSTNAME; if (_numInitialSTUNRequests > NUM_INITIAL_STUN_REQUESTS_BEFORE_FAIL) { // we're still trying to do our initial STUN we're over the fail threshold From d780964cb4979abfdf501dc72f16abe1106f6130 Mon Sep 17 00:00:00 2001 From: Simon Walton <simon@highfidelity.io> Date: Mon, 10 Jun 2019 17:28:49 -0700 Subject: [PATCH 3/4] Reset NodeList upon local nework change; abort current socket when rebinding Also ensure QUdpSocket is owned by LimitedNodeList. --- libraries/networking/src/LimitedNodeList.cpp | 1 + libraries/networking/src/udt/Socket.cpp | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 2f1a8c9d10..9b1f011680 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -1239,6 +1239,7 @@ void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) { } else { qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr; if (_hasTCPCheckedLocalSocket) { // Force a port change for NAT: + reset(); _nodeSocket.rebind(0); _localSockAddr.setPort(_nodeSocket.localPort()); } diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 75d4c9ef45..bcc2293e1f 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -33,6 +33,7 @@ using namespace udt; Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) : QObject(parent), + _udpSocket(parent), _readyReadBackupTimer(new QTimer(this)), _shouldChangeSocketOptions(shouldChangeSocketOptions) { @@ -50,6 +51,7 @@ Socket::Socket(QObject* parent, bool shouldChangeSocketOptions) : } void Socket::bind(const QHostAddress& address, quint16 port) { + _udpSocket.bind(address, port); if (_shouldChangeSocketOptions) { @@ -72,8 +74,7 @@ void Socket::rebind() { } void Socket::rebind(quint16 localPort) { - _udpSocket.close(); - _udpSocket.waitForDisconnected(); + _udpSocket.abort(); bind(QHostAddress::AnyIPv4, localPort); } From cfcea359b2c5dc28630f952bf3794af687ee6faf Mon Sep 17 00:00:00 2001 From: Simon Walton <simon@highfidelity.io> Date: Fri, 14 Jun 2019 16:51:59 -0700 Subject: [PATCH 4/4] Handle local address changes for servers --- domain-server/src/DomainServer.cpp | 4 ++++ libraries/networking/src/LimitedNodeList.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 44887599d3..00ca858a1f 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -739,6 +739,10 @@ void DomainServer::setupNodeListAndAssignments() { connect(nodeList.data(), &LimitedNodeList::nodeAdded, this, &DomainServer::nodeAdded); connect(nodeList.data(), &LimitedNodeList::nodeKilled, this, &DomainServer::nodeKilled); + connect(nodeList.data(), &LimitedNodeList::localSockAddrChanged, this, + [this](const HifiSockAddr& localSockAddr) { + DependencyManager::get<LimitedNodeList>()->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, localSockAddr.getPort()); + }); // register as the packet receiver for the types we want PacketReceiver& packetReceiver = nodeList->getPacketReceiver(); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 92a5692ca9..e47b4cc7bc 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -1237,16 +1237,18 @@ void LimitedNodeList::setLocalSocket(const HifiSockAddr& sockAddr) { if (_localSockAddr.isNull()) { qCInfo(networking) << "Local socket is" << sockAddr; + _localSockAddr = sockAddr; } else { qCInfo(networking) << "Local socket has changed from" << _localSockAddr << "to" << sockAddr; + _localSockAddr = sockAddr; if (_hasTCPCheckedLocalSocket) { // Force a port change for NAT: reset(); _nodeSocket.rebind(0); _localSockAddr.setPort(_nodeSocket.localPort()); + qCInfo(networking) << "Local port changed to" << _localSockAddr.getPort(); } } - _localSockAddr = sockAddr; emit localSockAddrChanged(_localSockAddr); } }