| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- package quic
- import (
- "bytes"
- "crypto/tls"
- "errors"
- "net"
- "github.com/bifurcation/mint"
- "github.com/lucas-clemente/quic-go/internal/handshake"
- "github.com/lucas-clemente/quic-go/internal/protocol"
- "github.com/lucas-clemente/quic-go/internal/utils"
- "github.com/lucas-clemente/quic-go/internal/wire"
- )
- type tlsSession struct {
- connID protocol.ConnectionID
- sess quicSession
- }
- type serverTLS struct {
- conn net.PacketConn
- config *Config
- mintConf *mint.Config
- params *handshake.TransportParameters
- cookieGenerator *handshake.CookieGenerator
- newSession func(connection, sessionRunner, protocol.ConnectionID, protocol.ConnectionID, protocol.ConnectionID, protocol.PacketNumber, *Config, *mint.Config, *handshake.TransportParameters, utils.Logger, protocol.VersionNumber) (quicSession, error)
- sessionRunner sessionRunner
- sessionChan chan<- tlsSession
- logger utils.Logger
- }
- func newServerTLS(
- conn net.PacketConn,
- config *Config,
- runner sessionRunner,
- tlsConf *tls.Config,
- logger utils.Logger,
- ) (*serverTLS, <-chan tlsSession, error) {
- cookieGenerator, err := handshake.NewCookieGenerator()
- if err != nil {
- return nil, nil, err
- }
- params := &handshake.TransportParameters{
- StreamFlowControlWindow: protocol.ReceiveStreamFlowControlWindow,
- ConnectionFlowControlWindow: protocol.ReceiveConnectionFlowControlWindow,
- IdleTimeout: config.IdleTimeout,
- MaxBidiStreams: uint16(config.MaxIncomingStreams),
- MaxUniStreams: uint16(config.MaxIncomingUniStreams),
- DisableMigration: true,
- // TODO(#855): generate a real token
- StatelessResetToken: bytes.Repeat([]byte{42}, 16),
- }
- mconf, err := tlsToMintConfig(tlsConf, protocol.PerspectiveServer)
- if err != nil {
- return nil, nil, err
- }
- sessionChan := make(chan tlsSession)
- s := &serverTLS{
- conn: conn,
- config: config,
- mintConf: mconf,
- sessionRunner: runner,
- sessionChan: sessionChan,
- cookieGenerator: cookieGenerator,
- params: params,
- newSession: newTLSServerSession,
- logger: logger,
- }
- return s, sessionChan, nil
- }
- func (s *serverTLS) HandleInitial(p *receivedPacket) {
- // TODO: add a check that DestConnID == SrcConnID
- s.logger.Debugf("<- Received Initial packet.")
- sess, connID, err := s.handleInitialImpl(p)
- if err != nil {
- s.logger.Errorf("Error occurred handling initial packet: %s", err)
- return
- }
- if sess == nil { // a stateless reset was done
- return
- }
- s.sessionChan <- tlsSession{
- connID: connID,
- sess: sess,
- }
- }
- func (s *serverTLS) handleInitialImpl(p *receivedPacket) (quicSession, protocol.ConnectionID, error) {
- hdr := p.header
- if len(hdr.Token) == 0 && hdr.DestConnectionID.Len() < protocol.MinConnectionIDLenInitial {
- return nil, nil, errors.New("dropping Initial packet with too short connection ID")
- }
- if len(hdr.Raw)+len(p.data) < protocol.MinInitialPacketSize {
- return nil, nil, errors.New("dropping too small Initial packet")
- }
- var cookie *handshake.Cookie
- if len(hdr.Token) > 0 {
- c, err := s.cookieGenerator.DecodeToken(hdr.Token)
- if err == nil {
- cookie = c
- }
- }
- if !s.config.AcceptCookie(p.remoteAddr, cookie) {
- // Log the Initial packet now.
- // If no Retry is sent, the packet will be logged by the session.
- p.header.Log(s.logger)
- return nil, nil, s.sendRetry(p.remoteAddr, hdr)
- }
- extHandler := handshake.NewExtensionHandlerServer(s.params, s.config.Versions, hdr.Version, s.logger)
- mconf := s.mintConf.Clone()
- mconf.ExtensionHandler = extHandler
- // A server is allowed to perform multiple Retries.
- // It doesn't make much sense, but it's something that our API allows.
- // In that case it must use a source connection ID of at least 8 bytes.
- connID, err := protocol.GenerateConnectionID(s.config.ConnectionIDLength)
- if err != nil {
- return nil, nil, err
- }
- s.logger.Debugf("Changing connection ID to %s.", connID)
- sess, err := s.newSession(
- &conn{pconn: s.conn, currentAddr: p.remoteAddr},
- s.sessionRunner,
- hdr.DestConnectionID,
- hdr.SrcConnectionID,
- connID,
- 1,
- s.config,
- mconf,
- s.params,
- s.logger,
- hdr.Version,
- )
- if err != nil {
- return nil, nil, err
- }
- go sess.run()
- sess.handlePacket(p)
- return sess, connID, nil
- }
- func (s *serverTLS) sendRetry(remoteAddr net.Addr, hdr *wire.Header) error {
- token, err := s.cookieGenerator.NewToken(remoteAddr)
- if err != nil {
- return err
- }
- connID, err := protocol.GenerateConnectionIDForInitial()
- if err != nil {
- return err
- }
- replyHdr := &wire.Header{
- IsLongHeader: true,
- Type: protocol.PacketTypeRetry,
- Version: hdr.Version,
- SrcConnectionID: connID,
- DestConnectionID: hdr.SrcConnectionID,
- OrigDestConnectionID: hdr.DestConnectionID,
- Token: token,
- }
- s.logger.Debugf("Changing connection ID to %s.\n-> Sending Retry", connID)
- replyHdr.Log(s.logger)
- buf := &bytes.Buffer{}
- if err := replyHdr.Write(buf, protocol.PerspectiveServer, hdr.Version); err != nil {
- return err
- }
- if _, err := s.conn.WriteTo(buf.Bytes(), remoteAddr); err != nil {
- s.logger.Debugf("Error sending Retry: %s", err)
- }
- return nil
- }
|