diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index ac0f9e0b07..b5872a46fd 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -1088,12 +1088,14 @@ void LimitedNodeList::processSTUNResponse(std::unique_ptr<udt::BasePacket> packe if (parseSTUNResponse(packet.get(), newPublicAddress, newPublicPort)) { if (newPublicAddress != _publicSockAddr.getAddress() || newPublicPort != _publicSockAddr.getPort()) { - _publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort); - - qCDebug(networking, "New public socket received from STUN server is %s:%hu", + qCDebug(networking, "New public socket received from STUN server is %s:%hu (was %s:%hu)", + newPublicAddress.toString().toStdString().c_str(), + newPublicPort, _publicSockAddr.getAddress().toString().toLocal8Bit().constData(), _publicSockAddr.getPort()); + _publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort); + if (!_hasCompletedInitialSTUN) { // if we're here we have definitely completed our initial STUN sequence stopInitialSTUNUpdate(true); diff --git a/libraries/networking/src/NetworkPeer.cpp b/libraries/networking/src/NetworkPeer.cpp index 4e0a82ba0e..a48922726e 100644 --- a/libraries/networking/src/NetworkPeer.cpp +++ b/libraries/networking/src/NetworkPeer.cpp @@ -59,13 +59,13 @@ void NetworkPeer::setPublicSocket(const HifiSockAddr& publicSocket) { bool wasOldSocketNull = _publicSocket.isNull(); - auto temp = _publicSocket.objectName(); + auto previousSocket = _publicSocket; _publicSocket = publicSocket; - _publicSocket.setObjectName(temp); + _publicSocket.setObjectName(previousSocket.objectName()); if (!wasOldSocketNull) { - qCDebug(networking) << "Public socket change for node" << *this; - emit socketUpdated(); + qCDebug(networking) << "Public socket change for node" << *this << "; previously" << previousSocket; + emit socketUpdated(previousSocket, _publicSocket); } } } @@ -79,13 +79,13 @@ void NetworkPeer::setLocalSocket(const HifiSockAddr& localSocket) { bool wasOldSocketNull = _localSocket.isNull(); - auto temp = _localSocket.objectName(); + auto previousSocket = _localSocket; _localSocket = localSocket; - _localSocket.setObjectName(temp); + _localSocket.setObjectName(previousSocket.objectName()); if (!wasOldSocketNull) { - qCDebug(networking) << "Local socket change for node" << *this; - emit socketUpdated(); + qCDebug(networking) << "Local socket change for node" << *this << "; previously" << previousSocket; + emit socketUpdated(previousSocket, _localSocket); } } } @@ -99,13 +99,13 @@ void NetworkPeer::setSymmetricSocket(const HifiSockAddr& symmetricSocket) { bool wasOldSocketNull = _symmetricSocket.isNull(); - auto temp = _symmetricSocket.objectName(); + auto previousSocket = _symmetricSocket; _symmetricSocket = symmetricSocket; - _symmetricSocket.setObjectName(temp); + _symmetricSocket.setObjectName(previousSocket.objectName()); if (!wasOldSocketNull) { - qCDebug(networking) << "Symmetric socket change for node" << *this; - emit socketUpdated(); + qCDebug(networking) << "Symmetric socket change for node" << *this << "; previously" << previousSocket; + emit socketUpdated(previousSocket, _symmetricSocket); } } } diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index e2149d64af..4c08c97d3c 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -94,7 +94,7 @@ public slots: signals: void pingTimerTimeout(); void socketActivated(const HifiSockAddr& sockAddr); - void socketUpdated(); + void socketUpdated(HifiSockAddr previousAddress, HifiSockAddr currentAddress); protected: void setActiveSocket(HifiSockAddr* discoveredSocket); diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 418dc8f417..872ee4dd4c 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -114,6 +114,7 @@ SendQueue& Connection::getSendQueue() { QObject::connect(_sendQueue.get(), &SendQueue::packetRetransmitted, this, &Connection::recordRetransmission); QObject::connect(_sendQueue.get(), &SendQueue::queueInactive, this, &Connection::queueInactive); QObject::connect(_sendQueue.get(), &SendQueue::timeout, this, &Connection::queueTimeout); + QObject::connect(this, &Connection::destinationAddressChange, _sendQueue.get(), &SendQueue::updateDestinationAddress); // set defaults on the send queue from our congestion control object and estimatedTimeout() @@ -485,3 +486,10 @@ std::unique_ptr<Packet> PendingReceivedMessage::removeNextPacket() { } return std::unique_ptr<Packet>(); } + +void Connection::setDestinationAddress(const HifiSockAddr& destination) { + if (_destination != destination) { + _destination = destination; + emit destinationAddressChange(destination); + } +} diff --git a/libraries/networking/src/udt/Connection.h b/libraries/networking/src/udt/Connection.h index 938ec36860..47edb021c8 100644 --- a/libraries/networking/src/udt/Connection.h +++ b/libraries/networking/src/udt/Connection.h @@ -76,10 +76,12 @@ public: void recordSentUnreliablePackets(int wireSize, int payloadSize); void recordReceivedUnreliablePackets(int wireSize, int payloadSize); + void setDestinationAddress(const HifiSockAddr& destination); signals: void packetSent(); void receiverHandshakeRequestComplete(const HifiSockAddr& sockAddr); + void destinationAddressChange(HifiSockAddr currentAddress); private slots: void recordSentPackets(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint); diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 15841b5c21..2997c272f9 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -557,3 +557,7 @@ void SendQueue::deactivate() { bool SendQueue::isFlowWindowFull() const { return seqlen(SequenceNumber { (uint32_t) _lastACKSequenceNumber }, _currentSequenceNumber) > _flowWindowSize; } + +void SendQueue::updateDestinationAddress(HifiSockAddr newAddress) { + _destination = newAddress; +} diff --git a/libraries/networking/src/udt/SendQueue.h b/libraries/networking/src/udt/SendQueue.h index c1a2b59075..2153745250 100644 --- a/libraries/networking/src/udt/SendQueue.h +++ b/libraries/networking/src/udt/SendQueue.h @@ -75,6 +75,7 @@ public slots: void ack(SequenceNumber ack); void fastRetransmit(SequenceNumber ack); void handshakeACK(); + void updateDestinationAddress(HifiSockAddr newAddress); signals: void packetSent(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint); diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index c56f276560..4714160ace 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -538,6 +538,33 @@ void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) { } } +void Socket::handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAddr currentAddress) { + { + Lock connectionsLock(_connectionsHashMutex); + _connectionsHash.erase(currentAddress); + + const auto connectionIter = _connectionsHash.find(previousAddress); + if (connectionIter != _connectionsHash.end()) { + auto connection = move(connectionIter->second); + _connectionsHash.erase(connectionIter); + connection->setDestinationAddress(currentAddress); + _connectionsHash[currentAddress] = move(connection); + } + } + + { + Lock sequenceNumbersLock(_unreliableSequenceNumbersMutex); + _unreliableSequenceNumbers.erase(currentAddress); + + const auto sequenceNumbersIter = _unreliableSequenceNumbers.find(previousAddress); + if (sequenceNumbersIter != _unreliableSequenceNumbers.end()) { + auto sequenceNumbers = sequenceNumbersIter->second; + _unreliableSequenceNumbers.erase(sequenceNumbersIter); + _unreliableSequenceNumbers[currentAddress] = sequenceNumbers; + } + } +} + #if (PR_BUILD || DEV_BUILD) void Socket::sendFakedHandshakeRequest(const HifiSockAddr& sockAddr) { diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index ad9d6de8b8..74eb413bc2 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -106,11 +106,11 @@ private slots: void handleSocketError(QAbstractSocket::SocketError socketError); void handleStateChanged(QAbstractSocket::SocketState socketState); + void handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAddr currentAddress); private: void setSystemBufferSizes(); Connection* findOrCreateConnection(const HifiSockAddr& sockAddr, bool filterCreation = false); - bool socketMatchesNodeOrDomain(const HifiSockAddr& sockAddr); // privatized methods used by UDTTest - they are private since they must be called on the Socket thread ConnectionStats::Stats sampleStatsForConnection(const HifiSockAddr& destination);