From b442075205800eb730bd7b14a3a7e02607cbbbd0 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Mon, 29 Feb 2016 14:22:08 -0800 Subject: [PATCH] Add initial seq number to handshake --- libraries/networking/src/udt/Connection.cpp | 14 ++++++++++--- libraries/networking/src/udt/SendQueue.cpp | 22 +++++++++++++-------- libraries/networking/src/udt/SendQueue.h | 2 +- 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 1ab8441ba3..cb197f15c7 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -731,15 +731,20 @@ void Connection::processNAK(std::unique_ptr controlPacket) { } void Connection::processHandshake(std::unique_ptr controlPacket) { + SequenceNumber initialSequenceNumber; + controlPacket->readPrimitive(&initialSequenceNumber); - if (!_hasReceivedHandshake || _hasReceivedData) { + if (!_hasReceivedHandshake || initialSequenceNumber != _initialReceiveSequenceNumber) { // server sent us a handshake - we need to assume this means state should be reset // as long as we haven't received a handshake yet or we have and we've received some data resetReceiveState(); + _initialReceiveSequenceNumber = initialSequenceNumber; } // immediately respond with a handshake ACK - static auto handshakeACK = ControlPacket::create(ControlPacket::HandshakeACK, 0); + static auto handshakeACK = ControlPacket::create(ControlPacket::HandshakeACK, sizeof(SequenceNumber)); + handshakeACK->seek(0); + handshakeACK->writePrimitive(initialSequenceNumber); _parentSocket->writeBasePacket(*handshakeACK, _destination); // indicate that handshake has been received @@ -749,8 +754,11 @@ void Connection::processHandshake(std::unique_ptr controlPacket) void Connection::processHandshakeACK(std::unique_ptr controlPacket) { // if we've decided to clean up the send queue then this handshake ACK should be ignored, it's useless if (_sendQueue) { + SequenceNumber initialSequenceNumber; + controlPacket->readPrimitive(&initialSequenceNumber); + // hand off this handshake ACK to the send queue so it knows it can start sending - getSendQueue().handshakeACK(); + getSendQueue().handshakeACK(initialSequenceNumber); // indicate that handshake ACK was received _hasReceivedHandshakeACK = true; diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 77b0c53da7..5c6db5adf3 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -202,7 +202,11 @@ void SendQueue::sendHandshake() { std::unique_lock handshakeLock { _handshakeMutex }; if (!_hasReceivedHandshakeACK) { // we haven't received a handshake ACK from the client, send another now - static const auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, 0); + static const auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, sizeof(SequenceNumber)); + + handshakePacket->seek(0); + + handshakePacket->writePrimitive(_initialSequenceNumber); _socket->writeBasePacket(*handshakePacket, _destination); // we wait for the ACK or the re-send interval to expire @@ -211,14 +215,16 @@ void SendQueue::sendHandshake() { } } -void SendQueue::handshakeACK() { - { - std::lock_guard locker { _handshakeMutex }; - _hasReceivedHandshakeACK = true; +void SendQueue::handshakeACK(SequenceNumber initialSequenceNumber) { + if (initialSequenceNumber == _initialSequenceNumber) { + { + std::lock_guard locker { _handshakeMutex }; + _hasReceivedHandshakeACK = true; + } + + // Notify on the handshake ACK condition + _handshakeACKCondition.notify_one(); } - - // Notify on the handshake ACK condition - _handshakeACKCondition.notify_one(); } SequenceNumber SendQueue::getNextSequenceNumber() { diff --git a/libraries/networking/src/udt/SendQueue.h b/libraries/networking/src/udt/SendQueue.h index 29ad7c6d73..0390f2ff1f 100644 --- a/libraries/networking/src/udt/SendQueue.h +++ b/libraries/networking/src/udt/SendQueue.h @@ -71,7 +71,7 @@ public slots: void ack(SequenceNumber ack); void nak(SequenceNumber start, SequenceNumber end); void overrideNAKListFromPacket(ControlPacket& packet); - void handshakeACK(); + void handshakeACK(SequenceNumber initialSequenceNumber); signals: void packetSent(int dataSize, int payloadSize);