send Retry, Version Negotiation and SERVER_BUSY packets asynchronously

Now that there's only a single run loop in the server, we should make
sure to process incoming packets as quickly as possible. This especially
means not blocking on conn.Write().
This commit is contained in:
Marten Seemann
2020-01-13 15:20:22 +07:00
parent 7f0dc56d70
commit 44c1092ed7

View File

@@ -370,7 +370,7 @@ func (s *baseServer) handlePacketImpl(p *receivedPacket) bool /* was the packet
}
// send a Version Negotiation Packet if the client is speaking a different protocol version
if !protocol.IsSupportedVersion(s.config.Versions, hdr.Version) {
s.sendVersionNegotiationPacket(p, hdr)
go s.sendVersionNegotiationPacket(p, hdr)
return false
}
if hdr.IsLongHeader && hdr.Type != protocol.PacketTypeInitial {
@@ -417,15 +417,22 @@ func (s *baseServer) handleInitialImpl(p *receivedPacket, hdr *wire.Header) (qui
}
}
if !s.config.AcceptToken(p.remoteAddr, token) {
// Log the Initial packet now.
// If no Retry is sent, the packet will be logged by the session.
(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)
return nil, s.sendRetry(p.remoteAddr, hdr)
go func() {
if err := s.sendRetry(p.remoteAddr, hdr); err != nil {
s.logger.Debugf("Error sending Retry: %s", err)
}
}()
return nil, nil
}
if queueLen := atomic.LoadInt32(&s.sessionQueueLen); queueLen >= protocol.MaxAcceptQueueSize {
s.logger.Debugf("Rejecting new connection. Server currently busy. Accept queue length: %d (max %d)", queueLen, protocol.MaxAcceptQueueSize)
return nil, s.sendServerBusy(p.remoteAddr, hdr)
go func() {
if err := s.sendServerBusy(p.remoteAddr, hdr); err != nil {
s.logger.Debugf("Error rejecting connection: %s", err)
}
}()
return nil, nil
}
connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength)
@@ -511,6 +518,9 @@ func (s *baseServer) handleNewSession(sess quicSession) {
}
func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
// Log the Initial packet now.
// If no Retry is sent, the packet will be logged by the session.
(&wire.ExtendedHeader{Header: *hdr}).Log(s.logger)
token, err := s.tokenGenerator.NewRetryToken(remoteAddr, hdr.DestConnectionID)
if err != nil {
return err
@@ -536,10 +546,8 @@ func (s *baseServer) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
// append the Retry integrity tag
tag := handshake.GetRetryIntegrityTag(buf.Bytes(), hdr.DestConnectionID)
buf.Write(tag[:])
if _, err := s.conn.WriteTo(buf.Bytes(), remoteAddr); err != nil {
s.logger.Debugf("Error sending Retry: %s", err)
}
return nil
_, err = s.conn.WriteTo(buf.Bytes(), remoteAddr)
return err
}
func (s *baseServer) sendServerBusy(remoteAddr net.Addr, hdr *wire.Header) error {
@@ -580,10 +588,8 @@ func (s *baseServer) sendServerBusy(remoteAddr net.Addr, hdr *wire.Header) error
replyHdr.Log(s.logger)
wire.LogFrame(s.logger, ccf, true)
if _, err := s.conn.WriteTo(raw, remoteAddr); err != nil {
s.logger.Debugf("Error rejecting connection: %s", err)
}
return nil
_, err := s.conn.WriteTo(raw, remoteAddr)
return err
}
func (s *baseServer) sendVersionNegotiationPacket(p *receivedPacket, hdr *wire.Header) {