server_tls.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package quic
  2. import (
  3. "bytes"
  4. "crypto/tls"
  5. "errors"
  6. "net"
  7. "github.com/bifurcation/mint"
  8. "github.com/lucas-clemente/quic-go/internal/handshake"
  9. "github.com/lucas-clemente/quic-go/internal/protocol"
  10. "github.com/lucas-clemente/quic-go/internal/utils"
  11. "github.com/lucas-clemente/quic-go/internal/wire"
  12. )
  13. type tlsSession struct {
  14. connID protocol.ConnectionID
  15. sess quicSession
  16. }
  17. type serverTLS struct {
  18. conn net.PacketConn
  19. config *Config
  20. mintConf *mint.Config
  21. params *handshake.TransportParameters
  22. cookieGenerator *handshake.CookieGenerator
  23. newSession func(connection, sessionRunner, protocol.ConnectionID, protocol.ConnectionID, protocol.ConnectionID, protocol.PacketNumber, *Config, *mint.Config, *handshake.TransportParameters, utils.Logger, protocol.VersionNumber) (quicSession, error)
  24. sessionRunner sessionRunner
  25. sessionChan chan<- tlsSession
  26. logger utils.Logger
  27. }
  28. func newServerTLS(
  29. conn net.PacketConn,
  30. config *Config,
  31. runner sessionRunner,
  32. tlsConf *tls.Config,
  33. logger utils.Logger,
  34. ) (*serverTLS, <-chan tlsSession, error) {
  35. cookieGenerator, err := handshake.NewCookieGenerator()
  36. if err != nil {
  37. return nil, nil, err
  38. }
  39. params := &handshake.TransportParameters{
  40. StreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow,
  41. ConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow,
  42. IdleTimeout: config.IdleTimeout,
  43. MaxBidiStreams: uint16(config.MaxIncomingStreams),
  44. MaxUniStreams: uint16(config.MaxIncomingUniStreams),
  45. DisableMigration: true,
  46. // TODO(#855): generate a real token
  47. StatelessResetToken: bytes.Repeat([]byte{42}, 16),
  48. }
  49. mconf, err := tlsToMintConfig(tlsConf, protocol.PerspectiveServer)
  50. if err != nil {
  51. return nil, nil, err
  52. }
  53. sessionChan := make(chan tlsSession)
  54. s := &serverTLS{
  55. conn: conn,
  56. config: config,
  57. mintConf: mconf,
  58. sessionRunner: runner,
  59. sessionChan: sessionChan,
  60. cookieGenerator: cookieGenerator,
  61. params: params,
  62. newSession: newTLSServerSession,
  63. logger: logger,
  64. }
  65. return s, sessionChan, nil
  66. }
  67. func (s *serverTLS) HandleInitial(p *receivedPacket) {
  68. // TODO: add a check that DestConnID == SrcConnID
  69. s.logger.Debugf("<- Received Initial packet.")
  70. sess, connID, err := s.handleInitialImpl(p)
  71. if err != nil {
  72. s.logger.Errorf("Error occurred handling initial packet: %s", err)
  73. return
  74. }
  75. if sess == nil { // a stateless reset was done
  76. return
  77. }
  78. s.sessionChan <- tlsSession{
  79. connID: connID,
  80. sess: sess,
  81. }
  82. }
  83. func (s *serverTLS) handleInitialImpl(p *receivedPacket) (quicSession, protocol.ConnectionID, error) {
  84. hdr := p.header
  85. if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial {
  86. return nil, nil, errors.New("dropping Initial packet with too short connection ID")
  87. }
  88. if len(hdr.Raw)+len(p.data) < protocol.MinInitialPacketSize {
  89. return nil, nil, errors.New("dropping too small Initial packet")
  90. }
  91. var cookie *handshake.Cookie
  92. if len(hdr.Token) > 0 {
  93. c, err := s.cookieGenerator.DecodeToken(hdr.Token)
  94. if err == nil {
  95. cookie = c
  96. }
  97. }
  98. if !s.config.AcceptCookie(p.remoteAddr, cookie) {
  99. // Log the Initial packet now.
  100. // If no Retry is sent, the packet will be logged by the session.
  101. p.header.Log(s.logger)
  102. return nil, nil, s.sendRetry(p.remoteAddr, hdr)
  103. }
  104. extHandler := handshake.NewExtensionHandlerServer(s.params, s.config.Versions, hdr.Version, s.logger)
  105. mconf := s.mintConf.Clone()
  106. mconf.ExtensionHandler = extHandler
  107. // A server is allowed to perform multiple Retries.
  108. // It doesn't make much sense, but it's something that our API allows.
  109. // In that case it must use a source connection ID of at least 8 bytes.
  110. connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength)
  111. if err != nil {
  112. return nil, nil, err
  113. }
  114. s.logger.Debugf("Changing connection ID to %s.", connID)
  115. sess, err := s.newSession(
  116. &conn{pconn: s.conn, currentAddr: p.remoteAddr},
  117. s.sessionRunner,
  118. hdr.DestConnectionID,
  119. hdr.SrcConnectionID,
  120. connID,
  121. 1,
  122. s.config,
  123. mconf,
  124. s.params,
  125. s.logger,
  126. hdr.Version,
  127. )
  128. if err != nil {
  129. return nil, nil, err
  130. }
  131. go sess.run()
  132. sess.handlePacket(p)
  133. return sess, connID, nil
  134. }
  135. func (s *serverTLS) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
  136. token, err := s.cookieGenerator.NewToken(remoteAddr)
  137. if err != nil {
  138. return err
  139. }
  140. connID, err := protocol.GenerateConnectionIDForInitial()
  141. if err != nil {
  142. return err
  143. }
  144. replyHdr := &wire.Header{
  145. IsLongHeader: true,
  146. Type: protocol.PacketTypeRetry,
  147. Version: hdr.Version,
  148. SrcConnectionID: connID,
  149. DestConnectionID: hdr.SrcConnectionID,
  150. OrigDestConnectionID: hdr.DestConnectionID,
  151. Token: token,
  152. }
  153. s.logger.Debugf("Changing connection ID to %s.\n-> Sending Retry", connID)
  154. replyHdr.Log(s.logger)
  155. buf := &bytes.Buffer{}
  156. if err := replyHdr.Write(buf, protocol.PerspectiveServer, hdr.Version); err != nil {
  157. return err
  158. }
  159. if _, err := s.conn.WriteTo(buf.Bytes(), remoteAddr); err != nil {
  160. s.logger.Debugf("Error sending Retry: %s", err)
  161. }
  162. return nil
  163. }