mirror of
https://github.com/overte-org/overte.git
synced 2025-08-16 05:50:41 +02:00
send a handshake before first packet send
This commit is contained in:
parent
67816c033a
commit
cabdee8391
7 changed files with 56 additions and 3 deletions
|
@ -400,6 +400,12 @@ void Connection::processControl(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
case ControlPacket::TimeoutNAK:
|
||||
processTimeoutNAK(move(controlPacket));
|
||||
break;
|
||||
case ControlPacket::Handshake:
|
||||
processHandshake(move(controlPacket));
|
||||
break;
|
||||
case ControlPacket::HandshakeACK:
|
||||
processHandshakeACK(move(controlPacket));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -589,6 +595,19 @@ void Connection::processNAK(std::unique_ptr<ControlPacket> controlPacket) {
|
|||
_stats.record(ConnectionStats::Stats::ReceivedNAK);
|
||||
}
|
||||
|
||||
void Connection::processHandshake(std::unique_ptr<ControlPacket> controlPacket) {
|
||||
// immediately respond with a handshake ACK
|
||||
static auto handshakeACK = ControlPacket::create(ControlPacket::HandshakeACK, 0);
|
||||
_parentSocket->writeBasePacket(*handshakeACK, _destination);
|
||||
|
||||
_hasReceivedHandshake = true;
|
||||
}
|
||||
|
||||
void Connection::processHandshakeACK(std::unique_ptr<ControlPacket> controlPacket) {
|
||||
// hand off this handshake ACK to the send queue so it knows it can start sending
|
||||
getSendQueue().handshakeACK();
|
||||
}
|
||||
|
||||
void Connection::processTimeoutNAK(std::unique_ptr<ControlPacket> controlPacket) {
|
||||
// Override SendQueue's LossList with the timeout NAK list
|
||||
getSendQueue().overrideNAKListFromPacket(*controlPacket);
|
||||
|
|
|
@ -90,6 +90,8 @@ private:
|
|||
void processACK2(std::unique_ptr<ControlPacket> controlPacket);
|
||||
void processNAK(std::unique_ptr<ControlPacket> controlPacket);
|
||||
void processTimeoutNAK(std::unique_ptr<ControlPacket> controlPacket);
|
||||
void processHandshake(std::unique_ptr<ControlPacket> controlPacket);
|
||||
void processHandshakeACK(std::unique_ptr<ControlPacket> controlPacket);
|
||||
|
||||
SendQueue& getSendQueue();
|
||||
SequenceNumber nextACK() const;
|
||||
|
@ -106,6 +108,7 @@ private:
|
|||
std::chrono::high_resolution_clock::time_point _lastNAKTime;
|
||||
|
||||
bool _hasReceivedFirstPacket { false };
|
||||
bool _hasReceivedHandshake { false }; // flag for receipt of handshake from server
|
||||
|
||||
LossList _lossList; // List of all missing packets
|
||||
SequenceNumber _lastReceivedSequenceNumber; // The largest sequence number received from the peer
|
||||
|
|
|
@ -100,7 +100,7 @@ void ControlPacket::readType() {
|
|||
Q_ASSERT_X(bitAndType & CONTROL_BIT_MASK, "ControlPacket::readHeader()", "This should be a control packet");
|
||||
|
||||
uint16_t packetType = (bitAndType & ~CONTROL_BIT_MASK) >> (8 * sizeof(Type));
|
||||
Q_ASSERT_X(packetType <= ControlPacket::Type::TimeoutNAK, "ControlPacket::readType()", "Received a control packet with wrong type");
|
||||
Q_ASSERT_X(packetType <= ControlPacket::Type::HandshakeACK, "ControlPacket::readType()", "Received a control packet with wrong type");
|
||||
|
||||
// read the type
|
||||
_type = (Type) packetType;
|
||||
|
|
|
@ -30,7 +30,9 @@ public:
|
|||
ACK,
|
||||
ACK2,
|
||||
NAK,
|
||||
TimeoutNAK
|
||||
TimeoutNAK,
|
||||
Handshake,
|
||||
HandshakeACK
|
||||
};
|
||||
|
||||
static std::unique_ptr<ControlPacket> create(Type type, qint64 size = -1);
|
||||
|
|
|
@ -169,7 +169,8 @@ SequenceNumber LossList::popFirstSequenceNumber() {
|
|||
|
||||
void LossList::write(ControlPacket& packet, int maxPairs) {
|
||||
int writtenPairs = 0;
|
||||
for(const auto& pair : _lossList) {
|
||||
|
||||
for (const auto& pair : _lossList) {
|
||||
packet.writePrimitive(pair.first);
|
||||
packet.writePrimitive(pair.second);
|
||||
|
||||
|
|
|
@ -195,6 +195,31 @@ void SendQueue::run() {
|
|||
// Record timing
|
||||
_lastSendTimestamp = high_resolution_clock::now();
|
||||
|
||||
if (!_hasReceivedHandshakeACK) {
|
||||
// we haven't received a handshake ACK from the client
|
||||
// if it has been at least 100ms since we last sent a handshake, send another now
|
||||
|
||||
// hold the time of last send in a static
|
||||
static auto lastSendHandshake = high_resolution_clock::time_point();
|
||||
|
||||
static const int HANDSHAKE_RESEND_INTERVAL_MS = 100;
|
||||
|
||||
// calculation the duration since the last handshake send
|
||||
auto sinceLastHandshake = duration_cast<milliseconds>(high_resolution_clock::now() - lastSendHandshake);
|
||||
|
||||
if (sinceLastHandshake.count() >= HANDSHAKE_RESEND_INTERVAL_MS) {
|
||||
|
||||
// it has been long enough since last handshake, send another
|
||||
static auto handshakePacket = ControlPacket::create(ControlPacket::Handshake, 0);
|
||||
_socket->writeBasePacket(*handshakePacket, _destination);
|
||||
|
||||
lastSendHandshake = high_resolution_clock::now();
|
||||
}
|
||||
|
||||
// skip over this iteration since we haven't completed the handshake
|
||||
continue;
|
||||
}
|
||||
|
||||
bool resentPacket = false;
|
||||
|
||||
// the following while makes sure that we find a packet to re-send, if there is one
|
||||
|
|
|
@ -59,6 +59,7 @@ public slots:
|
|||
void ack(SequenceNumber ack);
|
||||
void nak(SequenceNumber start, SequenceNumber end);
|
||||
void overrideNAKListFromPacket(ControlPacket& packet);
|
||||
void handshakeACK() { _hasReceivedHandshakeACK = true; }
|
||||
|
||||
signals:
|
||||
void packetSent(int dataSize, int payloadSize);
|
||||
|
@ -85,6 +86,8 @@ private:
|
|||
Socket* _socket { nullptr }; // Socket to send packet on
|
||||
HifiSockAddr _destination; // Destination addr
|
||||
|
||||
std::atomic<bool> _hasReceivedHandshakeACK { false }; // flag for receipt of handshake ACK from client
|
||||
|
||||
std::atomic<uint32_t> _lastACKSequenceNumber; // Last ACKed sequence number
|
||||
|
||||
MessageNumber _currentMessageNumber { 0 };
|
||||
|
|
Loading…
Reference in a new issue