github.com/TugasAkhir-QUIC/quic-go@v0.0.2-0.20240215011318-d20e25a9054c/transport.go (about)

     1  package quic
     2  
     3  import (
     4  	"context"
     5  	"crypto/rand"
     6  	"crypto/tls"
     7  	"errors"
     8  	"math"
     9  	"net"
    10  	"sync"
    11  	"sync/atomic"
    12  	"time"
    13  
    14  	"github.com/TugasAkhir-QUIC/quic-go/internal/protocol"
    15  	"github.com/TugasAkhir-QUIC/quic-go/internal/utils"
    16  	"github.com/TugasAkhir-QUIC/quic-go/internal/wire"
    17  	"github.com/TugasAkhir-QUIC/quic-go/logging"
    18  )
    19  
    20  var errListenerAlreadySet = errors.New("listener already set")
    21  
    22  const (
    23  	// defaultMaxNumUnvalidatedHandshakes is the default value for Transport.MaxUnvalidatedHandshakes.
    24  	defaultMaxNumUnvalidatedHandshakes = 128
    25  	// defaultMaxNumHandshakes is the default value for Transport.MaxHandshakes.
    26  	// It's not clear how to choose a reasonable value that works for all use cases.
    27  	// In production, implementations should:
    28  	// 1. Choose a lower value.
    29  	// 2. Implement some kind of IP-address based filtering using the Config.GetConfigForClient
    30  	//    callback in order to prevent flooding attacks from a single / small number of IP addresses.
    31  	defaultMaxNumHandshakes = math.MaxInt32
    32  )
    33  
    34  // The Transport is the central point to manage incoming and outgoing QUIC connections.
    35  // QUIC demultiplexes connections based on their QUIC Connection IDs, not based on the 4-tuple.
    36  // This means that a single UDP socket can be used for listening for incoming connections, as well as
    37  // for dialing an arbitrary number of outgoing connections.
    38  // A Transport handles a single net.PacketConn, and offers a range of configuration options
    39  // compared to the simple helper functions like Listen and Dial that this package provides.
    40  type Transport struct {
    41  	// A single net.PacketConn can only be handled by one Transport.
    42  	// Bad things will happen if passed to multiple Transports.
    43  	//
    44  	// A number of optimizations will be enabled if the connections implements the OOBCapablePacketConn interface,
    45  	// as a *net.UDPConn does.
    46  	// 1. It enables the Don't Fragment (DF) bit on the IP header.
    47  	//    This is required to run DPLPMTUD (Path MTU Discovery, RFC 8899).
    48  	// 2. It enables reading of the ECN bits from the IP header.
    49  	//    This allows the remote node to speed up its loss detection and recovery.
    50  	// 3. It uses batched syscalls (recvmmsg) to more efficiently receive packets from the socket.
    51  	// 4. It uses Generic Segmentation Offload (GSO) to efficiently send batches of packets (on Linux).
    52  	//
    53  	// After passing the connection to the Transport, it's invalid to call ReadFrom or WriteTo on the connection.
    54  	Conn net.PacketConn
    55  
    56  	// The length of the connection ID in bytes.
    57  	// It can be any value between 1 and 20.
    58  	// Due to the increased risk of collisions, it is not recommended to use connection IDs shorter than 4 bytes.
    59  	// If unset, a 4 byte connection ID will be used.
    60  	ConnectionIDLength int
    61  
    62  	// Use for generating new connection IDs.
    63  	// This allows the application to control of the connection IDs used,
    64  	// which allows routing / load balancing based on connection IDs.
    65  	// All Connection IDs returned by the ConnectionIDGenerator MUST
    66  	// have the same length.
    67  	ConnectionIDGenerator ConnectionIDGenerator
    68  
    69  	// The StatelessResetKey is used to generate stateless reset tokens.
    70  	// If no key is configured, sending of stateless resets is disabled.
    71  	// It is highly recommended to configure a stateless reset key, as stateless resets
    72  	// allow the peer to quickly recover from crashes and reboots of this node.
    73  	// See section 10.3 of RFC 9000 for details.
    74  	StatelessResetKey *StatelessResetKey
    75  
    76  	// The TokenGeneratorKey is used to encrypt session resumption tokens.
    77  	// If no key is configured, a random key will be generated.
    78  	// If multiple servers are authoritative for the same domain, they should use the same key,
    79  	// see section 8.1.3 of RFC 9000 for details.
    80  	TokenGeneratorKey *TokenGeneratorKey
    81  
    82  	// MaxTokenAge is the maximum age of the resumption token presented during the handshake.
    83  	// These tokens allow skipping address resumption when resuming a QUIC connection,
    84  	// and are especially useful when using 0-RTT.
    85  	// If not set, it defaults to 24 hours.
    86  	// See section 8.1.3 of RFC 9000 for details.
    87  	MaxTokenAge time.Duration
    88  
    89  	// DisableVersionNegotiationPackets disables the sending of Version Negotiation packets.
    90  	// This can be useful if version information is exchanged out-of-band.
    91  	// It has no effect for clients.
    92  	DisableVersionNegotiationPackets bool
    93  
    94  	// MaxUnvalidatedHandshakes is the maximum number of concurrent incoming QUIC handshakes
    95  	// originating from unvalidated source addresses.
    96  	// If the number of handshakes from unvalidated addresses reaches this number, new incoming
    97  	// connection attempts will need to proof reachability at the respective source address using the
    98  	// Retry mechanism, as described in RFC 9000 section 8.1.2.
    99  	// Validating the source address adds one additional network roundtrip to the handshake.
   100  	// If unset, a default value of 128 will be used.
   101  	// When set to a negative value, every connection attempt will need to validate the source address.
   102  	// It does not make sense to set this value higher than MaxHandshakes.
   103  	MaxUnvalidatedHandshakes int
   104  	// MaxHandshakes is the maximum number of concurrent incoming handshakes, both from validated
   105  	// and unvalidated source addresses.
   106  	// If unset, the number of concurrent handshakes will not be limited.
   107  	// Applications should choose a reasonable value based on their thread model, and consider
   108  	// implementing IP-based rate limiting using Config.GetConfigForClient.
   109  	// If the number of handshakes reaches this number, new connection attempts will be rejected by
   110  	// terminating the connection attempt using a CONNECTION_REFUSED error.
   111  	MaxHandshakes int
   112  
   113  	// A Tracer traces events that don't belong to a single QUIC connection.
   114  	// Tracer.Close is called when the transport is closed.
   115  	Tracer *logging.Tracer
   116  
   117  	handlerMap packetHandlerManager
   118  
   119  	mutex    sync.Mutex
   120  	initOnce sync.Once
   121  	initErr  error
   122  
   123  	// Set in init.
   124  	// If no ConnectionIDGenerator is set, this is the ConnectionIDLength.
   125  	connIDLen int
   126  	// Set in init.
   127  	// If no ConnectionIDGenerator is set, this is set to a default.
   128  	connIDGenerator ConnectionIDGenerator
   129  
   130  	server *baseServer
   131  
   132  	conn rawConn
   133  
   134  	closeQueue          chan closePacket
   135  	statelessResetQueue chan receivedPacket
   136  
   137  	listening   chan struct{} // is closed when listen returns
   138  	closed      bool
   139  	createdConn bool
   140  	isSingleUse bool // was created for a single server or client, i.e. by calling quic.Listen or quic.Dial
   141  
   142  	readingNonQUICPackets atomic.Bool
   143  	nonQUICPackets        chan receivedPacket
   144  
   145  	logger utils.Logger
   146  }
   147  
   148  // Listen starts listening for incoming QUIC connections.
   149  // There can only be a single listener on any net.PacketConn.
   150  // Listen may only be called again after the current Listener was closed.
   151  func (t *Transport) Listen(tlsConf *tls.Config, conf *Config) (*Listener, error) {
   152  	s, err := t.createServer(tlsConf, conf, false)
   153  	if err != nil {
   154  		return nil, err
   155  	}
   156  	return &Listener{baseServer: s}, nil
   157  }
   158  
   159  // ListenEarly starts listening for incoming QUIC connections.
   160  // There can only be a single listener on any net.PacketConn.
   161  // Listen may only be called again after the current Listener was closed.
   162  func (t *Transport) ListenEarly(tlsConf *tls.Config, conf *Config) (*EarlyListener, error) {
   163  	s, err := t.createServer(tlsConf, conf, true)
   164  	if err != nil {
   165  		return nil, err
   166  	}
   167  	return &EarlyListener{baseServer: s}, nil
   168  }
   169  
   170  func (t *Transport) createServer(tlsConf *tls.Config, conf *Config, allow0RTT bool) (*baseServer, error) {
   171  	if tlsConf == nil {
   172  		return nil, errors.New("quic: tls.Config not set")
   173  	}
   174  	if err := validateConfig(conf); err != nil {
   175  		return nil, err
   176  	}
   177  
   178  	t.mutex.Lock()
   179  	defer t.mutex.Unlock()
   180  
   181  	if t.server != nil {
   182  		return nil, errListenerAlreadySet
   183  	}
   184  	conf = populateConfig(conf)
   185  	if err := t.init(false); err != nil {
   186  		return nil, err
   187  	}
   188  	maxUnvalidatedHandshakes := t.MaxUnvalidatedHandshakes
   189  	if maxUnvalidatedHandshakes == 0 {
   190  		maxUnvalidatedHandshakes = defaultMaxNumUnvalidatedHandshakes
   191  	}
   192  	maxHandshakes := t.MaxHandshakes
   193  	if maxHandshakes == 0 {
   194  		maxHandshakes = defaultMaxNumHandshakes
   195  	}
   196  	s := newServer(
   197  		t.conn,
   198  		t.handlerMap,
   199  		t.connIDGenerator,
   200  		tlsConf,
   201  		conf,
   202  		t.Tracer,
   203  		t.closeServer,
   204  		*t.TokenGeneratorKey,
   205  		t.MaxTokenAge,
   206  		maxUnvalidatedHandshakes,
   207  		maxHandshakes,
   208  		t.DisableVersionNegotiationPackets,
   209  		allow0RTT,
   210  	)
   211  	t.server = s
   212  	return s, nil
   213  }
   214  
   215  // Dial dials a new connection to a remote host (not using 0-RTT).
   216  func (t *Transport) Dial(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (Connection, error) {
   217  	return t.dial(ctx, addr, "", tlsConf, conf, false)
   218  }
   219  
   220  // DialEarly dials a new connection, attempting to use 0-RTT if possible.
   221  func (t *Transport) DialEarly(ctx context.Context, addr net.Addr, tlsConf *tls.Config, conf *Config) (EarlyConnection, error) {
   222  	return t.dial(ctx, addr, "", tlsConf, conf, true)
   223  }
   224  
   225  func (t *Transport) dial(ctx context.Context, addr net.Addr, host string, tlsConf *tls.Config, conf *Config, use0RTT bool) (EarlyConnection, error) {
   226  	if err := validateConfig(conf); err != nil {
   227  		return nil, err
   228  	}
   229  	conf = populateConfig(conf)
   230  	if err := t.init(t.isSingleUse); err != nil {
   231  		return nil, err
   232  	}
   233  	var onClose func()
   234  	if t.isSingleUse {
   235  		onClose = func() { t.Close() }
   236  	}
   237  	tlsConf = tlsConf.Clone()
   238  	setTLSConfigServerName(tlsConf, addr, host)
   239  	return dial(ctx, newSendConn(t.conn, addr, packetInfo{}, utils.DefaultLogger), t.connIDGenerator, t.handlerMap, tlsConf, conf, onClose, use0RTT)
   240  }
   241  
   242  func (t *Transport) init(allowZeroLengthConnIDs bool) error {
   243  	t.initOnce.Do(func() {
   244  		var conn rawConn
   245  		if c, ok := t.Conn.(rawConn); ok {
   246  			conn = c
   247  		} else {
   248  			var err error
   249  			conn, err = wrapConn(t.Conn)
   250  			if err != nil {
   251  				t.initErr = err
   252  				return
   253  			}
   254  		}
   255  
   256  		t.logger = utils.DefaultLogger // TODO: make this configurable
   257  		t.conn = conn
   258  		t.handlerMap = newPacketHandlerMap(t.StatelessResetKey, t.enqueueClosePacket, t.logger)
   259  		t.listening = make(chan struct{})
   260  
   261  		t.closeQueue = make(chan closePacket, 4)
   262  		t.statelessResetQueue = make(chan receivedPacket, 4)
   263  		if t.TokenGeneratorKey == nil {
   264  			var key TokenGeneratorKey
   265  			if _, err := rand.Read(key[:]); err != nil {
   266  				t.initErr = err
   267  				return
   268  			}
   269  			t.TokenGeneratorKey = &key
   270  		}
   271  
   272  		if t.ConnectionIDGenerator != nil {
   273  			t.connIDGenerator = t.ConnectionIDGenerator
   274  			t.connIDLen = t.ConnectionIDGenerator.ConnectionIDLen()
   275  		} else {
   276  			connIDLen := t.ConnectionIDLength
   277  			if t.ConnectionIDLength == 0 && !allowZeroLengthConnIDs {
   278  				connIDLen = protocol.DefaultConnectionIDLength
   279  			}
   280  			t.connIDLen = connIDLen
   281  			t.connIDGenerator = &protocol.DefaultConnectionIDGenerator{ConnLen: t.connIDLen}
   282  		}
   283  
   284  		getMultiplexer().AddConn(t.Conn)
   285  		go t.listen(conn)
   286  		go t.runSendQueue()
   287  	})
   288  	return t.initErr
   289  }
   290  
   291  // WriteTo sends a packet on the underlying connection.
   292  func (t *Transport) WriteTo(b []byte, addr net.Addr) (int, error) {
   293  	if err := t.init(false); err != nil {
   294  		return 0, err
   295  	}
   296  	return t.conn.WritePacket(b, addr, nil, 0, protocol.ECNUnsupported)
   297  }
   298  
   299  func (t *Transport) enqueueClosePacket(p closePacket) {
   300  	select {
   301  	case t.closeQueue <- p:
   302  	default:
   303  		// Oops, we're backlogged.
   304  		// Just drop the packet, sending CONNECTION_CLOSE copies is best effort anyway.
   305  	}
   306  }
   307  
   308  func (t *Transport) runSendQueue() {
   309  	for {
   310  		select {
   311  		case <-t.listening:
   312  			return
   313  		case p := <-t.closeQueue:
   314  			t.conn.WritePacket(p.payload, p.addr, p.info.OOB(), 0, protocol.ECNUnsupported)
   315  		case p := <-t.statelessResetQueue:
   316  			t.sendStatelessReset(p)
   317  		}
   318  	}
   319  }
   320  
   321  // Close closes the underlying connection.
   322  // If any listener was started, it will be closed as well.
   323  // It is invalid to start new listeners or connections after that.
   324  func (t *Transport) Close() error {
   325  	t.close(errors.New("closing"))
   326  	if t.createdConn {
   327  		if err := t.Conn.Close(); err != nil {
   328  			return err
   329  		}
   330  	} else if t.conn != nil {
   331  		t.conn.SetReadDeadline(time.Now())
   332  		defer func() { t.conn.SetReadDeadline(time.Time{}) }()
   333  	}
   334  	if t.listening != nil {
   335  		<-t.listening // wait until listening returns
   336  	}
   337  	return nil
   338  }
   339  
   340  func (t *Transport) closeServer() {
   341  	t.mutex.Lock()
   342  	t.server = nil
   343  	if t.isSingleUse {
   344  		t.closed = true
   345  	}
   346  	t.mutex.Unlock()
   347  	if t.createdConn {
   348  		t.Conn.Close()
   349  	}
   350  	if t.isSingleUse {
   351  		t.conn.SetReadDeadline(time.Now())
   352  		defer func() { t.conn.SetReadDeadline(time.Time{}) }()
   353  		<-t.listening // wait until listening returns
   354  	}
   355  }
   356  
   357  func (t *Transport) close(e error) {
   358  	t.mutex.Lock()
   359  	defer t.mutex.Unlock()
   360  	if t.closed {
   361  		return
   362  	}
   363  
   364  	if t.handlerMap != nil {
   365  		t.handlerMap.Close(e)
   366  	}
   367  	if t.server != nil {
   368  		t.server.close(e, false)
   369  	}
   370  	if t.Tracer != nil && t.Tracer.Close != nil {
   371  		t.Tracer.Close()
   372  	}
   373  	t.closed = true
   374  }
   375  
   376  // only print warnings about the UDP receive buffer size once
   377  var setBufferWarningOnce sync.Once
   378  
   379  func (t *Transport) listen(conn rawConn) {
   380  	defer close(t.listening)
   381  	defer getMultiplexer().RemoveConn(t.Conn)
   382  
   383  	for {
   384  		p, err := conn.ReadPacket()
   385  		//nolint:staticcheck // SA1019 ignore this!
   386  		// TODO: This code is used to ignore wsa errors on Windows.
   387  		// Since net.Error.Temporary is deprecated as of Go 1.18, we should find a better solution.
   388  		// See https://github.com/quic-go/quic-go/issues/1737 for details.
   389  		if nerr, ok := err.(net.Error); ok && nerr.Temporary() {
   390  			t.mutex.Lock()
   391  			closed := t.closed
   392  			t.mutex.Unlock()
   393  			if closed {
   394  				return
   395  			}
   396  			t.logger.Debugf("Temporary error reading from conn: %w", err)
   397  			continue
   398  		}
   399  		if err != nil {
   400  			// Windows returns an error when receiving a UDP datagram that doesn't fit into the provided buffer.
   401  			if isRecvMsgSizeErr(err) {
   402  				continue
   403  			}
   404  			t.close(err)
   405  			return
   406  		}
   407  		t.handlePacket(p)
   408  	}
   409  }
   410  
   411  func (t *Transport) handlePacket(p receivedPacket) {
   412  	if len(p.data) == 0 {
   413  		return
   414  	}
   415  	if !wire.IsPotentialQUICPacket(p.data[0]) && !wire.IsLongHeaderPacket(p.data[0]) {
   416  		t.handleNonQUICPacket(p)
   417  		return
   418  	}
   419  	connID, err := wire.ParseConnectionID(p.data, t.connIDLen)
   420  	if err != nil {
   421  		t.logger.Debugf("error parsing connection ID on packet from %s: %s", p.remoteAddr, err)
   422  		if t.Tracer != nil && t.Tracer.DroppedPacket != nil {
   423  			t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropHeaderParseError)
   424  		}
   425  		p.buffer.MaybeRelease()
   426  		return
   427  	}
   428  
   429  	// If there's a connection associated with the connection ID, pass the packet there.
   430  	if handler, ok := t.handlerMap.Get(connID); ok {
   431  		handler.handlePacket(p)
   432  		return
   433  	}
   434  	// RFC 9000 section 10.3.1 requires that the stateless reset detection logic is run for both
   435  	// packets that cannot be associated with any connections, and for packets that can't be decrypted.
   436  	// We deviate from the RFC and ignore the latter: If a packet's connection ID is associated with an
   437  	// existing connection, it is dropped there if if it can't be decrypted.
   438  	// Stateless resets use random connection IDs, and at reasonable connection ID lengths collisions are
   439  	// exceedingly rare. In the unlikely event that a stateless reset is misrouted to an existing connection,
   440  	// it is to be expected that the next stateless reset will be correctly detected.
   441  	if isStatelessReset := t.maybeHandleStatelessReset(p.data); isStatelessReset {
   442  		return
   443  	}
   444  	if !wire.IsLongHeaderPacket(p.data[0]) {
   445  		t.maybeSendStatelessReset(p)
   446  		return
   447  	}
   448  
   449  	t.mutex.Lock()
   450  	defer t.mutex.Unlock()
   451  	if t.server == nil { // no server set
   452  		t.logger.Debugf("received a packet with an unexpected connection ID %s", connID)
   453  		return
   454  	}
   455  	t.server.handlePacket(p)
   456  }
   457  
   458  func (t *Transport) maybeSendStatelessReset(p receivedPacket) {
   459  	if t.StatelessResetKey == nil {
   460  		p.buffer.Release()
   461  		return
   462  	}
   463  
   464  	// Don't send a stateless reset in response to very small packets.
   465  	// This includes packets that could be stateless resets.
   466  	if len(p.data) <= protocol.MinStatelessResetSize {
   467  		p.buffer.Release()
   468  		return
   469  	}
   470  
   471  	select {
   472  	case t.statelessResetQueue <- p:
   473  	default:
   474  		// it's fine to not send a stateless reset when we're busy
   475  		p.buffer.Release()
   476  	}
   477  }
   478  
   479  func (t *Transport) sendStatelessReset(p receivedPacket) {
   480  	defer p.buffer.Release()
   481  
   482  	connID, err := wire.ParseConnectionID(p.data, t.connIDLen)
   483  	if err != nil {
   484  		t.logger.Errorf("error parsing connection ID on packet from %s: %s", p.remoteAddr, err)
   485  		return
   486  	}
   487  	token := t.handlerMap.GetStatelessResetToken(connID)
   488  	t.logger.Debugf("Sending stateless reset to %s (connection ID: %s). Token: %#x", p.remoteAddr, connID, token)
   489  	data := make([]byte, protocol.MinStatelessResetSize-16, protocol.MinStatelessResetSize)
   490  	rand.Read(data)
   491  	data[0] = (data[0] & 0x7f) | 0x40
   492  	data = append(data, token[:]...)
   493  	if _, err := t.conn.WritePacket(data, p.remoteAddr, p.info.OOB(), 0, protocol.ECNUnsupported); err != nil {
   494  		t.logger.Debugf("Error sending Stateless Reset to %s: %s", p.remoteAddr, err)
   495  	}
   496  }
   497  
   498  func (t *Transport) maybeHandleStatelessReset(data []byte) bool {
   499  	// stateless resets are always short header packets
   500  	if wire.IsLongHeaderPacket(data[0]) {
   501  		return false
   502  	}
   503  	if len(data) < 17 /* type byte + 16 bytes for the reset token */ {
   504  		return false
   505  	}
   506  
   507  	token := *(*protocol.StatelessResetToken)(data[len(data)-16:])
   508  	if conn, ok := t.handlerMap.GetByResetToken(token); ok {
   509  		t.logger.Debugf("Received a stateless reset with token %#x. Closing connection.", token)
   510  		go conn.destroy(&StatelessResetError{Token: token})
   511  		return true
   512  	}
   513  	return false
   514  }
   515  
   516  func (t *Transport) handleNonQUICPacket(p receivedPacket) {
   517  	// Strictly speaking, this is racy,
   518  	// but we only care about receiving packets at some point after ReadNonQUICPacket has been called.
   519  	if !t.readingNonQUICPackets.Load() {
   520  		return
   521  	}
   522  	select {
   523  	case t.nonQUICPackets <- p:
   524  	default:
   525  		if t.Tracer != nil && t.Tracer.DroppedPacket != nil {
   526  			t.Tracer.DroppedPacket(p.remoteAddr, logging.PacketTypeNotDetermined, p.Size(), logging.PacketDropDOSPrevention)
   527  		}
   528  	}
   529  }
   530  
   531  const maxQueuedNonQUICPackets = 32
   532  
   533  // ReadNonQUICPacket reads non-QUIC packets received on the underlying connection.
   534  // The detection logic is very simple: Any packet that has the first and second bit of the packet set to 0.
   535  // Note that this is stricter than the detection logic defined in RFC 9443.
   536  func (t *Transport) ReadNonQUICPacket(ctx context.Context, b []byte) (int, net.Addr, error) {
   537  	if err := t.init(false); err != nil {
   538  		return 0, nil, err
   539  	}
   540  	if !t.readingNonQUICPackets.Load() {
   541  		t.nonQUICPackets = make(chan receivedPacket, maxQueuedNonQUICPackets)
   542  		t.readingNonQUICPackets.Store(true)
   543  	}
   544  	select {
   545  	case <-ctx.Done():
   546  		return 0, nil, ctx.Err()
   547  	case p := <-t.nonQUICPackets:
   548  		n := copy(b, p.data)
   549  		return n, p.remoteAddr, nil
   550  	case <-t.listening:
   551  		return 0, nil, errors.New("closed")
   552  	}
   553  }
   554  
   555  func setTLSConfigServerName(tlsConf *tls.Config, addr net.Addr, host string) {
   556  	// If no ServerName is set, infer the ServerName from the host we're connecting to.
   557  	if tlsConf.ServerName != "" {
   558  		return
   559  	}
   560  	if host == "" {
   561  		if udpAddr, ok := addr.(*net.UDPAddr); ok {
   562  			tlsConf.ServerName = udpAddr.IP.String()
   563  			return
   564  		}
   565  	}
   566  	h, _, err := net.SplitHostPort(host)
   567  	if err != nil { // This happens if the host doesn't contain a port number.
   568  		tlsConf.ServerName = host
   569  		return
   570  	}
   571  	tlsConf.ServerName = h
   572  }