skip processing of control packets before handshake

This commit is contained in:
Stephen Birarda 2015-08-25 17:26:25 -07:00
parent 83d76084f1
commit 82f5e2e04f
3 changed files with 28 additions and 15 deletions

View file

@ -388,28 +388,35 @@ bool Connection::processReceivedSequenceNumber(SequenceNumber sequenceNumber, in
void Connection::processControl(std::unique_ptr<ControlPacket> controlPacket) {
if (!_hasReceivedHandshake && controlPacket->getType() != ControlPacket::Handshake) {
// we refuse to process any packets until the handshake is received
return;
}
// Simple dispatch to control packets processing methods based on their type.
// Processing of control packets (other than Handshake / Handshake ACK)
// is not performed if the handshake has not been completed.
// Simple dispatch to control packets processing methods based on their type
switch (controlPacket->getType()) {
case ControlPacket::ACK:
if (controlPacket->getPayloadSize() == sizeof(SequenceNumber)) {
processLightACK(move(controlPacket));
} else {
processACK(move(controlPacket));
if (_hasReceivedHandshakeACK) {
if (controlPacket->getPayloadSize() == sizeof(SequenceNumber)) {
processLightACK(move(controlPacket));
} else {
processACK(move(controlPacket));
}
}
break;
case ControlPacket::ACK2:
processACK2(move(controlPacket));
if (_hasReceivedHandshake) {
processACK2(move(controlPacket));
}
break;
case ControlPacket::NAK:
processNAK(move(controlPacket));
if (_hasReceivedHandshakeACK) {
processNAK(move(controlPacket));
}
break;
case ControlPacket::TimeoutNAK:
processTimeoutNAK(move(controlPacket));
if (_hasReceivedHandshakeACK) {
processTimeoutNAK(move(controlPacket));
}
break;
case ControlPacket::Handshake:
processHandshake(move(controlPacket));
@ -611,12 +618,16 @@ void Connection::processHandshake(std::unique_ptr<ControlPacket> controlPacket)
static auto handshakeACK = ControlPacket::create(ControlPacket::HandshakeACK, 0);
_parentSocket->writeBasePacket(*handshakeACK, _destination);
// indicate that handshake has been received
_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();
// indicate that handshake ACK was received
_hasReceivedHandshakeACK = true;
}
void Connection::processTimeoutNAK(std::unique_ptr<ControlPacket> controlPacket) {

View file

@ -109,6 +109,7 @@ private:
bool _hasReceivedFirstPacket { false };
bool _hasReceivedHandshake { false }; // flag for receipt of handshake from server
bool _hasReceivedHandshakeACK { false }; // flag for receipt of handshake ACK from client
LossList _lossList; // List of all missing packets
SequenceNumber _lastReceivedSequenceNumber; // The largest sequence number received from the peer

View file

@ -216,8 +216,8 @@ void SendQueue::run() {
lastSendHandshake = high_resolution_clock::now();
}
// skip over this iteration since we haven't completed the handshake
continue;
// we allow processing in this while to continue so that processEvents is called
// but we skip over sending of packets until _hasReceivedHandshakeACK is true
}
bool resentPacket = false;
@ -266,7 +266,8 @@ void SendQueue::run() {
// if we didn't find a packet to re-send AND we think we can fit a new packet on the wire
// (this is according to the current flow window size) then we send out a new packet
if (!resentPacket
if (_hasReceivedHandshakeACK
&& !resentPacket
&& seqlen(SequenceNumber { (uint32_t) _lastACKSequenceNumber }, _currentSequenceNumber) <= _flowWindowSize) {
// we didn't re-send a packet, so time to send a new one