implement packet send modes to determine what kind of packets are sent

This commit is contained in:
Marten Seemann
2018-03-09 17:20:02 +07:00
parent 6a2c4548f7
commit b5977236ff
9 changed files with 205 additions and 92 deletions

View File

@@ -766,40 +766,56 @@ func (s *session) processTransportParameters(params *handshake.TransportParamete
func (s *session) sendPackets() error {
s.pacingDeadline = time.Time{}
if !s.sentPacketHandler.SendingAllowed() { // if congestion limited, at least try sending an ACK frame
return s.maybeSendAckOnlyPacket()
sendMode := s.sentPacketHandler.SendMode()
if sendMode == ackhandler.SendNone { // shortcut: return immediately if there's nothing to send
return nil
}
numPackets := s.sentPacketHandler.ShouldSendNumPackets()
var numPacketsSent int
// Send retransmissions, until
// * we're congestion limited, or
// * there are no more retransmissions, or
// * the maximum number of packets was reached
for ; numPacketsSent < numPackets; numPacketsSent++ {
sentPacket, err := s.maybeSendRetransmission()
if err != nil {
return err
sendLoop:
for {
switch sendMode {
case ackhandler.SendNone:
break sendLoop
case ackhandler.SendAck:
// We can at most send a single ACK only packet.
// There will only be a new ACK after receiving new packets.
// SendAck is only returned when we're congestion limited, so we don't need to set the pacingt timer.
return s.maybeSendAckOnlyPacket()
case ackhandler.SendRetransmission:
sentPacket, err := s.maybeSendRetransmission()
if err != nil {
return err
}
if sentPacket {
numPacketsSent++
// This can happen if a retransmission queued, but it wasn't necessary to send it.
// e.g. when an Initial is queued, but we already received a packet from the server.
}
case ackhandler.SendAny:
sentPacket, err := s.sendPacket()
if err != nil {
return err
}
if !sentPacket {
break sendLoop
}
numPacketsSent++
default:
return fmt.Errorf("BUG: invalid send mode %d", sendMode)
}
if !sentPacket { // no more retransmission to send. Proceed to send new data.
if numPacketsSent >= numPackets {
break
}
if !s.sentPacketHandler.SendingAllowed() {
return nil
}
}
for ; numPacketsSent < numPackets; numPacketsSent++ {
sentPacket, err := s.sendPacket()
if err != nil {
return err
}
// If no packet was sent, or we're congestion limit, we're done here.
if !sentPacket || !s.sentPacketHandler.SendingAllowed() {
return nil
}
sendMode = s.sentPacketHandler.SendMode()
}
// Only start the pacing timer if we sent as many packets as we were allowed.
// There will probably be more to send when calling sendPacket again.
s.pacingDeadline = s.sentPacketHandler.TimeUntilSend()
if numPacketsSent == numPackets {
s.pacingDeadline = s.sentPacketHandler.TimeUntilSend()
}
return nil
}
@@ -837,7 +853,6 @@ func (s *session) maybeSendRetransmission() (bool, error) {
// As soon as we receive one response, we don't need to send any more Initials.
if s.receivedFirstPacket && retransmitPacket.PacketType == protocol.PacketTypeInitial {
utils.Debugf("Skipping retransmission of packet %d. Already received a response to an Initial.", retransmitPacket.PacketNumber)
retransmitPacket = nil
continue
}
break