github.com/psiphon-Labs/psiphon-tunnel-core@v2.0.28+incompatible/psiphon/common/quic/quic.go (about)

     1  //go:build !PSIPHON_DISABLE_QUIC
     2  // +build !PSIPHON_DISABLE_QUIC
     3  
     4  /*
     5   * Copyright (c) 2018, Psiphon Inc.
     6   * All rights reserved.
     7   *
     8   * This program is free software: you can redistribute it and/or modify
     9   * it under the terms of the GNU General Public License as published by
    10   * the Free Software Foundation, either version 3 of the License, or
    11   * (at your option) any later version.
    12   *
    13   * This program is distributed in the hope that it will be useful,
    14   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    16   * GNU General Public License for more details.
    17   *
    18   * You should have received a copy of the GNU General Public License
    19   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    20   *
    21   */
    22  
    23  /*
    24  
    25  Package quic wraps github.com/lucas-clemente/quic-go with net.Listener and
    26  net.Conn types that provide a drop-in replacement for net.TCPConn.
    27  
    28  Each QUIC session has exactly one stream, which is the equivilent of a TCP
    29  stream.
    30  
    31  Conns returned from Accept will have an established QUIC session and are
    32  configured to perform a deferred AcceptStream on the first Read or Write.
    33  
    34  Conns returned from Dial have an established QUIC session and stream. Dial
    35  accepts a Context input which may be used to cancel the dial.
    36  
    37  Conns mask or translate qerr.PeerGoingAway to io.EOF as appropriate.
    38  
    39  QUIC idle timeouts and keep alives are tuned to mitigate aggressive UDP NAT
    40  timeouts on mobile data networks while accounting for the fact that mobile
    41  devices in standby/sleep may not be able to initiate the keep alive.
    42  
    43  */
    44  package quic
    45  
    46  import (
    47  	"context"
    48  	"crypto/tls"
    49  	"fmt"
    50  	"io"
    51  	"net"
    52  	"net/http"
    53  	"os"
    54  	"sync"
    55  	"sync/atomic"
    56  	"syscall"
    57  	"time"
    58  
    59  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common"
    60  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/errors"
    61  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/obfuscator"
    62  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/prng"
    63  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/protocol"
    64  	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/values"
    65  	ietf_quic "github.com/Psiphon-Labs/quic-go"
    66  	"github.com/Psiphon-Labs/quic-go/http3"
    67  )
    68  
    69  const (
    70  	SERVER_HANDSHAKE_TIMEOUT = 30 * time.Second
    71  	SERVER_IDLE_TIMEOUT      = 5 * time.Minute
    72  	CLIENT_IDLE_TIMEOUT      = 30 * time.Second
    73  	UDP_PACKET_WRITE_TIMEOUT = 1 * time.Second
    74  )
    75  
    76  // Enabled indicates if QUIC functionality is enabled.
    77  func Enabled() bool {
    78  	return true
    79  }
    80  
    81  const ietfQUIC1VersionNumber = 0x1
    82  
    83  var supportedVersionNumbers = map[string]uint32{
    84  	protocol.QUIC_VERSION_GQUIC39:       uint32(0x51303339),
    85  	protocol.QUIC_VERSION_GQUIC43:       uint32(0x51303433),
    86  	protocol.QUIC_VERSION_GQUIC44:       uint32(0x51303434),
    87  	protocol.QUIC_VERSION_OBFUSCATED:    uint32(0x51303433),
    88  	protocol.QUIC_VERSION_V1:            ietfQUIC1VersionNumber,
    89  	protocol.QUIC_VERSION_RANDOMIZED_V1: ietfQUIC1VersionNumber,
    90  	protocol.QUIC_VERSION_OBFUSCATED_V1: uint32(ietfQUIC1VersionNumber),
    91  	protocol.QUIC_VERSION_DECOY_V1:      uint32(ietfQUIC1VersionNumber),
    92  }
    93  
    94  func isObfuscated(quicVersion string) bool {
    95  	return quicVersion == protocol.QUIC_VERSION_OBFUSCATED ||
    96  		quicVersion == protocol.QUIC_VERSION_OBFUSCATED_V1 ||
    97  		quicVersion == protocol.QUIC_VERSION_DECOY_V1
    98  }
    99  
   100  func isDecoy(quicVersion string) bool {
   101  	return quicVersion == protocol.QUIC_VERSION_DECOY_V1
   102  }
   103  
   104  func isClientHelloRandomized(quicVersion string) bool {
   105  	return quicVersion == protocol.QUIC_VERSION_RANDOMIZED_V1
   106  }
   107  
   108  func isIETF(quicVersion string) bool {
   109  	versionNumber, ok := supportedVersionNumbers[quicVersion]
   110  	if !ok {
   111  		return false
   112  	}
   113  	return isIETFVersionNumber(versionNumber)
   114  }
   115  
   116  func isIETFVersionNumber(versionNumber uint32) bool {
   117  	return versionNumber == ietfQUIC1VersionNumber
   118  }
   119  
   120  func isGQUIC(quicVersion string) bool {
   121  	return quicVersion == protocol.QUIC_VERSION_GQUIC39 ||
   122  		quicVersion == protocol.QUIC_VERSION_GQUIC43 ||
   123  		quicVersion == protocol.QUIC_VERSION_GQUIC44 ||
   124  		quicVersion == protocol.QUIC_VERSION_OBFUSCATED
   125  }
   126  
   127  func getALPN(versionNumber uint32) string {
   128  	return "h3"
   129  }
   130  
   131  // quic_test overrides the server idle timeout.
   132  var serverIdleTimeout = SERVER_IDLE_TIMEOUT
   133  
   134  // Listener is a net.Listener.
   135  type Listener struct {
   136  	quicListener
   137  	obfuscatedPacketConn *ObfuscatedPacketConn
   138  	clientRandomHistory  *obfuscator.SeedHistory
   139  }
   140  
   141  // Listen creates a new Listener.
   142  func Listen(
   143  	logger common.Logger,
   144  	irregularTunnelLogger func(string, error, common.LogFields),
   145  	address string,
   146  	obfuscationKey string,
   147  	enableGQUIC bool) (net.Listener, error) {
   148  
   149  	certificate, privateKey, err := common.GenerateWebServerCertificate(
   150  		values.GetHostName())
   151  	if err != nil {
   152  		return nil, errors.Trace(err)
   153  	}
   154  
   155  	tlsCertificate, err := tls.X509KeyPair(
   156  		[]byte(certificate), []byte(privateKey))
   157  	if err != nil {
   158  		return nil, errors.Trace(err)
   159  	}
   160  
   161  	addr, err := net.ResolveUDPAddr("udp", address)
   162  	if err != nil {
   163  		return nil, errors.Trace(err)
   164  	}
   165  
   166  	udpConn, err := net.ListenUDP("udp", addr)
   167  	if err != nil {
   168  		return nil, errors.Trace(err)
   169  	}
   170  
   171  	seed, err := prng.NewSeed()
   172  	if err != nil {
   173  		udpConn.Close()
   174  		return nil, errors.Trace(err)
   175  	}
   176  
   177  	obfuscatedPacketConn, err := NewObfuscatedPacketConn(
   178  		udpConn, true, false, false, obfuscationKey, seed)
   179  	if err != nil {
   180  		udpConn.Close()
   181  		return nil, errors.Trace(err)
   182  	}
   183  
   184  	// QUIC clients must prove knowledge of the obfuscated key via a message
   185  	// sent in the TLS ClientHello random field, or receive no UDP packets
   186  	// back from the server. This anti-probing mechanism is implemented using
   187  	// the existing Passthrough message and SeedHistory replay detection
   188  	// mechanisms. The replay history TTL is set to the validity period of
   189  	// the passthrough message.
   190  	//
   191  	// Irregular events are logged for invalid client activity.
   192  
   193  	clientRandomHistory := obfuscator.NewSeedHistory(
   194  		&obfuscator.SeedHistoryConfig{SeedTTL: obfuscator.TLS_PASSTHROUGH_TIME_PERIOD})
   195  
   196  	verifyClientHelloRandom := func(remoteAddr net.Addr, clientHelloRandom []byte) bool {
   197  
   198  		ok := obfuscator.VerifyTLSPassthroughMessage(
   199  			true, obfuscationKey, clientHelloRandom)
   200  		if !ok {
   201  			irregularTunnelLogger(
   202  				common.IPAddressFromAddr(remoteAddr),
   203  				errors.TraceNew("invalid client random message"),
   204  				nil)
   205  			return false
   206  		}
   207  
   208  		// Replay history is set to non-strict mode, allowing for a legitimate
   209  		// client to resend its Initial packet, as may happen. Since the
   210  		// source _port_ should be the same as the source IP in this case, we use
   211  		// the full IP:port value as the client address from which a replay is
   212  		// allowed.
   213  		//
   214  		// The non-strict case where ok is true and logFields is not nil is
   215  		// ignored, and nothing is logged in that scenario.
   216  
   217  		ok, logFields := clientRandomHistory.AddNew(
   218  			false, remoteAddr.String(), "client-hello-random", clientHelloRandom)
   219  		if !ok && logFields != nil {
   220  			irregularTunnelLogger(
   221  				common.IPAddressFromAddr(remoteAddr),
   222  				errors.TraceNew("duplicate client random message"),
   223  				*logFields)
   224  		}
   225  
   226  		return ok
   227  	}
   228  
   229  	var quicListener quicListener
   230  
   231  	if !enableGQUIC {
   232  
   233  		// When gQUIC is disabled, skip the muxListener entirely. This allows
   234  		// quic-go to enable ECN operations as the packet conn is a
   235  		// quic-goOOBCapablePacketConn; this provides some performance
   236  		// optimizations and also generate packets that may be harder to
   237  		// fingerprint, due to lack of ECN bits in IP packets otherwise.
   238  		// Skipping muxListener also avoids the additional overhead of
   239  		// pumping read packets though mux channels.
   240  
   241  		tlsConfig, ietfQUICConfig := makeIETFConfig(
   242  			obfuscatedPacketConn, verifyClientHelloRandom, tlsCertificate)
   243  
   244  		listener, err := ietf_quic.Listen(
   245  			obfuscatedPacketConn, tlsConfig, ietfQUICConfig)
   246  		if err != nil {
   247  			obfuscatedPacketConn.Close()
   248  			return nil, errors.Trace(err)
   249  		}
   250  
   251  		quicListener = &ietfQUICListener{Listener: listener}
   252  
   253  	} else {
   254  
   255  		// Note that, due to nature of muxListener, full accepts may happen before
   256  		// return and caller calls Accept.
   257  
   258  		muxListener, err := newMuxListener(
   259  			logger, verifyClientHelloRandom, obfuscatedPacketConn, tlsCertificate)
   260  		if err != nil {
   261  			obfuscatedPacketConn.Close()
   262  			return nil, errors.Trace(err)
   263  		}
   264  
   265  		quicListener = muxListener
   266  	}
   267  
   268  	return &Listener{
   269  		quicListener:         quicListener,
   270  		obfuscatedPacketConn: obfuscatedPacketConn,
   271  		clientRandomHistory:  clientRandomHistory,
   272  	}, nil
   273  }
   274  
   275  func makeIETFConfig(
   276  	conn *ObfuscatedPacketConn,
   277  	verifyClientHelloRandom func(net.Addr, []byte) bool,
   278  	tlsCertificate tls.Certificate) (*tls.Config, *ietf_quic.Config) {
   279  
   280  	tlsConfig := &tls.Config{
   281  		Certificates: []tls.Certificate{tlsCertificate},
   282  		NextProtos:   []string{getALPN(ietfQUIC1VersionNumber)},
   283  	}
   284  
   285  	ietfQUICConfig := &ietf_quic.Config{
   286  		HandshakeIdleTimeout:  SERVER_HANDSHAKE_TIMEOUT,
   287  		MaxIdleTimeout:        serverIdleTimeout,
   288  		MaxIncomingStreams:    1,
   289  		MaxIncomingUniStreams: -1,
   290  		KeepAlive:             true,
   291  
   292  		// The quic-go server may respond with a version negotiation packet
   293  		// before reaching the Initial packet processing with its
   294  		// anti-probing defense. This may happen even for a malformed packet.
   295  		// To prevent all responses to probers, version negotiation is
   296  		// disabled, which disables sending these packets. The fact that the
   297  		// server does not issue version negotiation packets may be a
   298  		// fingerprint itself, but, regardless, probers cannot ellicit any
   299  		// reponse from the server without providing a well-formed Initial
   300  		// packet with a valid Client Hello random value.
   301  		//
   302  		// Limitation: once version negotiate is required, the order of
   303  		// quic-go operations may need to be changed in order to first check
   304  		// the Initial/Client Hello, and then issue any required version
   305  		// negotiation packet.
   306  		DisableVersionNegotiationPackets: true,
   307  
   308  		VerifyClientHelloRandom:       verifyClientHelloRandom,
   309  		ServerMaxPacketSizeAdjustment: conn.serverMaxPacketSizeAdjustment,
   310  	}
   311  
   312  	return tlsConfig, ietfQUICConfig
   313  }
   314  
   315  // Accept returns a net.Conn that wraps a single QUIC session and stream. The
   316  // stream establishment is deferred until the first Read or Write, allowing
   317  // Accept to be called in a fast loop while goroutines spawned to handle each
   318  // net.Conn will perform the blocking AcceptStream.
   319  func (listener *Listener) Accept() (net.Conn, error) {
   320  
   321  	session, err := listener.quicListener.Accept()
   322  	if err != nil {
   323  		return nil, errors.Trace(err)
   324  	}
   325  
   326  	return &Conn{
   327  		session:              session,
   328  		deferredAcceptStream: true,
   329  	}, nil
   330  }
   331  
   332  func (listener *Listener) Close() error {
   333  
   334  	// First close the underlying packet conn to ensure all quic-go goroutines
   335  	// as well as any blocking Accept call goroutine is interrupted. Note
   336  	// that muxListener does this as well, so this is for the IETF-only case.
   337  	_ = listener.obfuscatedPacketConn.Close()
   338  
   339  	return listener.quicListener.Close()
   340  }
   341  
   342  // Dial establishes a new QUIC session and stream to the server specified by
   343  // address.
   344  //
   345  // packetConn is used as the underlying packet connection for QUIC. The dial
   346  // may be cancelled by ctx; packetConn will be closed if the dial is
   347  // cancelled or fails.
   348  //
   349  // Keep alive and idle timeout functionality in QUIC is disabled as these
   350  // aspects are expected to be handled at a higher level.
   351  func Dial(
   352  	ctx context.Context,
   353  	packetConn net.PacketConn,
   354  	remoteAddr *net.UDPAddr,
   355  	quicSNIAddress string,
   356  	quicVersion string,
   357  	clientHelloSeed *prng.Seed,
   358  	obfuscationKey string,
   359  	obfuscationPaddingSeed *prng.Seed,
   360  	disablePathMTUDiscovery bool) (net.Conn, error) {
   361  
   362  	if quicVersion == "" {
   363  		return nil, errors.TraceNew("missing version")
   364  	}
   365  
   366  	if isClientHelloRandomized(quicVersion) && clientHelloSeed == nil {
   367  		return nil, errors.TraceNew("missing client hello randomization values")
   368  	}
   369  
   370  	// obfuscationKey is always required, as it is used for anti-probing even
   371  	// when not obfuscating the QUIC payload.
   372  	if (isObfuscated(quicVersion) && obfuscationPaddingSeed == nil) || obfuscationKey == "" {
   373  		return nil, errors.TraceNew("missing obfuscation values")
   374  	}
   375  
   376  	versionNumber, ok := supportedVersionNumbers[quicVersion]
   377  	if !ok {
   378  		return nil, errors.Tracef("unsupported version: %s", quicVersion)
   379  	}
   380  
   381  	// Fail if the destination port is invalid. Network operations should fail
   382  	// quickly in this case, but IETF quic-go has been observed to timeout,
   383  	// instead of failing quickly, in the case of invalid destination port 0.
   384  	if remoteAddr.Port <= 0 || remoteAddr.Port >= 65536 {
   385  		return nil, errors.Tracef("invalid destination port: %d", remoteAddr.Port)
   386  	}
   387  
   388  	udpConn, ok := packetConn.(udpConn)
   389  	if !ok {
   390  		return nil, errors.TraceNew("packetConn must implement net.UDPConn functions")
   391  	}
   392  
   393  	// Ensure blocked packet writes eventually timeout.
   394  	packetConn = &writeTimeoutUDPConn{
   395  		udpConn: udpConn,
   396  	}
   397  
   398  	maxPacketSizeAdjustment := 0
   399  
   400  	if isObfuscated(quicVersion) {
   401  		obfuscatedPacketConn, err := NewObfuscatedPacketConn(
   402  			packetConn,
   403  			false,
   404  			isIETFVersionNumber(versionNumber),
   405  			isDecoy(quicVersion),
   406  			obfuscationKey,
   407  			obfuscationPaddingSeed)
   408  		if err != nil {
   409  			return nil, errors.Trace(err)
   410  		}
   411  		packetConn = obfuscatedPacketConn
   412  
   413  		// Reserve space for packet obfuscation overhead so that quic-go will
   414  		// continue to produce packets of max size 1280.
   415  		maxPacketSizeAdjustment = OBFUSCATED_MAX_PACKET_SIZE_ADJUSTMENT
   416  	}
   417  
   418  	// As an anti-probing measure, QUIC clients must prove knowledge of the
   419  	// server obfuscation key in the first client packet sent to the server. In
   420  	// the case of QUIC, the first packet, the Initial packet, contains a TLS
   421  	// Client Hello, and we set the client random field to a value that both
   422  	// proves knowledge of the obfuscation key and is indistiguishable from
   423  	// random. This is the same "passthrough" technique used for TLS, although
   424  	// for QUIC the server simply doesn't respond to any packets instead of
   425  	// passing traffic through to a different server.
   426  	//
   427  	// Limitation: the legacy gQUIC implementation does not support this
   428  	// anti-probling measure; gQUIC must be disabled to ensure no response
   429  	// from the server.
   430  
   431  	var getClientHelloRandom func() ([]byte, error)
   432  	if obfuscationKey != "" {
   433  		getClientHelloRandom = func() ([]byte, error) {
   434  			random, err := obfuscator.MakeTLSPassthroughMessage(true, obfuscationKey)
   435  			if err != nil {
   436  				return nil, errors.Trace(err)
   437  			}
   438  			return random, nil
   439  		}
   440  	}
   441  
   442  	session, err := dialQUIC(
   443  		ctx,
   444  		packetConn,
   445  		remoteAddr,
   446  		quicSNIAddress,
   447  		versionNumber,
   448  		clientHelloSeed,
   449  		getClientHelloRandom,
   450  		maxPacketSizeAdjustment,
   451  		disablePathMTUDiscovery,
   452  		false)
   453  	if err != nil {
   454  		packetConn.Close()
   455  		return nil, errors.Trace(err)
   456  	}
   457  
   458  	type dialResult struct {
   459  		conn *Conn
   460  		err  error
   461  	}
   462  
   463  	resultChannel := make(chan dialResult)
   464  
   465  	go func() {
   466  
   467  		stream, err := session.OpenStream()
   468  		if err != nil {
   469  			session.Close()
   470  			resultChannel <- dialResult{err: err}
   471  			return
   472  		}
   473  
   474  		resultChannel <- dialResult{
   475  			conn: &Conn{
   476  				packetConn: packetConn,
   477  				session:    session,
   478  				stream:     stream,
   479  			},
   480  		}
   481  	}()
   482  
   483  	var conn *Conn
   484  
   485  	select {
   486  	case result := <-resultChannel:
   487  		conn, err = result.conn, result.err
   488  	case <-ctx.Done():
   489  		err = ctx.Err()
   490  		// Interrupt the goroutine
   491  		session.Close()
   492  		<-resultChannel
   493  	}
   494  
   495  	if err != nil {
   496  		packetConn.Close()
   497  		return nil, errors.Trace(err)
   498  	}
   499  
   500  	return conn, nil
   501  }
   502  
   503  // udpConn matches net.UDPConn, which implements both net.Conn and
   504  // net.PacketConn. udpConn enables handling of Dial packetConn inputs that
   505  // are not concrete *net.UDPConn types but which still implement all the
   506  // required functions. A udpConn instance can be passed to quic-go; various
   507  // quic-go code paths check that the input conn implements net.Conn and/or
   508  // net.PacketConn.
   509  //
   510  // TODO: add *AddrPort functions introduced in Go 1.18
   511  type udpConn interface {
   512  	Close() error
   513  	File() (f *os.File, err error)
   514  	LocalAddr() net.Addr
   515  	Read(b []byte) (int, error)
   516  	ReadFrom(b []byte) (int, net.Addr, error)
   517  	ReadFromUDP(b []byte) (n int, addr *net.UDPAddr, err error)
   518  	ReadMsgUDP(b, oob []byte) (n, oobn, flags int, addr *net.UDPAddr, err error)
   519  	RemoteAddr() net.Addr
   520  	SetDeadline(t time.Time) error
   521  	SetReadBuffer(bytes int) error
   522  	SetReadDeadline(t time.Time) error
   523  	SetWriteBuffer(bytes int) error
   524  	SetWriteDeadline(t time.Time) error
   525  	SyscallConn() (syscall.RawConn, error)
   526  	Write(b []byte) (int, error)
   527  	WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (n, oobn int, err error)
   528  	WriteTo(b []byte, addr net.Addr) (int, error)
   529  	WriteToUDP(b []byte, addr *net.UDPAddr) (int, error)
   530  }
   531  
   532  // writeTimeoutUDPConn sets write deadlines before each UDP packet write.
   533  //
   534  // Generally, a UDP packet write doesn't block. However, Go's
   535  // internal/poll.FD.WriteMsg continues to loop when syscall.SendmsgN fails
   536  // with EAGAIN, which indicates that an OS socket buffer is currently full;
   537  // in certain OS states this may cause WriteMsgUDP/etc. to block
   538  // indefinitely. In this scenario, we want to instead behave as if the packet
   539  // were dropped, so we set a write deadline which will eventually interrupt
   540  // any EAGAIN loop.
   541  //
   542  // Note that quic-go manages read deadlines; we set only the write deadline
   543  // here.
   544  type writeTimeoutUDPConn struct {
   545  	udpConn
   546  }
   547  
   548  func (conn *writeTimeoutUDPConn) Write(b []byte) (int, error) {
   549  
   550  	err := conn.SetWriteDeadline(time.Now().Add(UDP_PACKET_WRITE_TIMEOUT))
   551  	if err != nil {
   552  		return 0, errors.Trace(err)
   553  	}
   554  
   555  	// Do not wrap any I/O err returned by udpConn
   556  	return conn.udpConn.Write(b)
   557  }
   558  
   559  func (conn *writeTimeoutUDPConn) WriteMsgUDP(b, oob []byte, addr *net.UDPAddr) (int, int, error) {
   560  
   561  	err := conn.SetWriteDeadline(time.Now().Add(UDP_PACKET_WRITE_TIMEOUT))
   562  	if err != nil {
   563  		return 0, 0, errors.Trace(err)
   564  	}
   565  
   566  	// Do not wrap any I/O err returned by udpConn
   567  	return conn.udpConn.WriteMsgUDP(b, oob, addr)
   568  }
   569  
   570  func (conn *writeTimeoutUDPConn) WriteTo(b []byte, addr net.Addr) (int, error) {
   571  
   572  	err := conn.SetWriteDeadline(time.Now().Add(UDP_PACKET_WRITE_TIMEOUT))
   573  	if err != nil {
   574  		return 0, errors.Trace(err)
   575  	}
   576  
   577  	// Do not wrap any I/O err returned by udpConn
   578  	return conn.udpConn.WriteTo(b, addr)
   579  }
   580  
   581  func (conn *writeTimeoutUDPConn) WriteToUDP(b []byte, addr *net.UDPAddr) (int, error) {
   582  
   583  	err := conn.SetWriteDeadline(time.Now().Add(UDP_PACKET_WRITE_TIMEOUT))
   584  	if err != nil {
   585  		return 0, errors.Trace(err)
   586  	}
   587  
   588  	// Do not wrap any I/O err returned by udpConn
   589  	return conn.udpConn.WriteToUDP(b, addr)
   590  }
   591  
   592  // Conn is a net.Conn and psiphon/common.Closer.
   593  type Conn struct {
   594  	packetConn net.PacketConn
   595  	session    quicSession
   596  
   597  	deferredAcceptStream bool
   598  
   599  	acceptMutex sync.Mutex
   600  	acceptErr   error
   601  	stream      quicStream
   602  
   603  	readMutex  sync.Mutex
   604  	writeMutex sync.Mutex
   605  
   606  	isClosed int32
   607  }
   608  
   609  func (conn *Conn) doDeferredAcceptStream() error {
   610  	conn.acceptMutex.Lock()
   611  	defer conn.acceptMutex.Unlock()
   612  
   613  	if conn.stream != nil {
   614  		return nil
   615  	}
   616  
   617  	if conn.acceptErr != nil {
   618  		return conn.acceptErr
   619  	}
   620  
   621  	stream, err := conn.session.AcceptStream()
   622  	if err != nil {
   623  		conn.session.Close()
   624  		conn.acceptErr = errors.Trace(err)
   625  		return conn.acceptErr
   626  	}
   627  
   628  	conn.stream = stream
   629  
   630  	return nil
   631  }
   632  
   633  func (conn *Conn) Read(b []byte) (int, error) {
   634  
   635  	if conn.deferredAcceptStream {
   636  		err := conn.doDeferredAcceptStream()
   637  		if err != nil {
   638  			return 0, errors.Trace(err)
   639  		}
   640  	}
   641  
   642  	// Add mutex to provide full net.Conn concurrency semantics.
   643  	// https://github.com/lucas-clemente/quic-go/blob/9cc23135d0477baf83aa4715de39ae7070039cb2/stream.go#L64
   644  	// "Read() and Write() may be called concurrently, but multiple calls to
   645  	// "Read() or Write() individually must be synchronized manually."
   646  	conn.readMutex.Lock()
   647  	defer conn.readMutex.Unlock()
   648  
   649  	n, err := conn.stream.Read(b)
   650  	if conn.session.isErrorIndicatingClosed(err) {
   651  		_ = conn.Close()
   652  		err = io.EOF
   653  	}
   654  	return n, err
   655  }
   656  
   657  func (conn *Conn) Write(b []byte) (int, error) {
   658  
   659  	if conn.deferredAcceptStream {
   660  		err := conn.doDeferredAcceptStream()
   661  		if err != nil {
   662  			return 0, errors.Trace(err)
   663  		}
   664  	}
   665  
   666  	conn.writeMutex.Lock()
   667  	defer conn.writeMutex.Unlock()
   668  
   669  	n, err := conn.stream.Write(b)
   670  	if conn.session.isErrorIndicatingClosed(err) {
   671  		_ = conn.Close()
   672  		if n == len(b) {
   673  			err = nil
   674  		}
   675  	}
   676  	return n, err
   677  }
   678  
   679  func (conn *Conn) Close() error {
   680  	err := conn.session.Close()
   681  	if conn.packetConn != nil {
   682  		err1 := conn.packetConn.Close()
   683  		if err == nil {
   684  			err = err1
   685  		}
   686  	}
   687  	atomic.StoreInt32(&conn.isClosed, 1)
   688  	return err
   689  }
   690  
   691  func (conn *Conn) IsClosed() bool {
   692  	return atomic.LoadInt32(&conn.isClosed) == 1
   693  }
   694  
   695  func (conn *Conn) LocalAddr() net.Addr {
   696  	return conn.session.LocalAddr()
   697  }
   698  
   699  func (conn *Conn) RemoteAddr() net.Addr {
   700  	return conn.session.RemoteAddr()
   701  }
   702  
   703  func (conn *Conn) SetDeadline(t time.Time) error {
   704  
   705  	if conn.deferredAcceptStream {
   706  		err := conn.doDeferredAcceptStream()
   707  		if err != nil {
   708  			return errors.Trace(err)
   709  		}
   710  	}
   711  
   712  	return conn.stream.SetDeadline(t)
   713  }
   714  
   715  func (conn *Conn) SetReadDeadline(t time.Time) error {
   716  
   717  	if conn.deferredAcceptStream {
   718  		err := conn.doDeferredAcceptStream()
   719  		if err != nil {
   720  			return errors.Trace(err)
   721  		}
   722  	}
   723  
   724  	return conn.stream.SetReadDeadline(t)
   725  }
   726  
   727  func (conn *Conn) SetWriteDeadline(t time.Time) error {
   728  
   729  	if conn.deferredAcceptStream {
   730  		err := conn.doDeferredAcceptStream()
   731  		if err != nil {
   732  			return errors.Trace(err)
   733  		}
   734  	}
   735  
   736  	return conn.stream.SetWriteDeadline(t)
   737  }
   738  
   739  // QUICTransporter implements the psiphon.transporter interface, used in
   740  // psiphon.MeekConn for HTTP requests, which requires a RoundTripper and
   741  // CloseIdleConnections.
   742  type QUICTransporter struct {
   743  	quicRoundTripper
   744  	noticeEmitter           func(string)
   745  	udpDialer               func(ctx context.Context) (net.PacketConn, *net.UDPAddr, error)
   746  	quicSNIAddress          string
   747  	quicVersion             string
   748  	clientHelloSeed         *prng.Seed
   749  	disablePathMTUDiscovery bool
   750  	packetConn              atomic.Value
   751  
   752  	mutex sync.Mutex
   753  	ctx   context.Context
   754  }
   755  
   756  // NewQUICTransporter creates a new QUICTransporter.
   757  func NewQUICTransporter(
   758  	ctx context.Context,
   759  	noticeEmitter func(string),
   760  	udpDialer func(ctx context.Context) (net.PacketConn, *net.UDPAddr, error),
   761  	quicSNIAddress string,
   762  	quicVersion string,
   763  	clientHelloSeed *prng.Seed,
   764  	disablePathMTUDiscovery bool) (*QUICTransporter, error) {
   765  
   766  	if quicVersion == "" {
   767  		return nil, errors.TraceNew("missing version")
   768  	}
   769  
   770  	versionNumber, ok := supportedVersionNumbers[quicVersion]
   771  	if !ok {
   772  		return nil, errors.Tracef("unsupported version: %s", quicVersion)
   773  	}
   774  
   775  	if isClientHelloRandomized(quicVersion) && clientHelloSeed == nil {
   776  		return nil, errors.TraceNew("missing client hello randomization values")
   777  	}
   778  
   779  	t := &QUICTransporter{
   780  		noticeEmitter:           noticeEmitter,
   781  		udpDialer:               udpDialer,
   782  		quicSNIAddress:          quicSNIAddress,
   783  		quicVersion:             quicVersion,
   784  		clientHelloSeed:         clientHelloSeed,
   785  		disablePathMTUDiscovery: disablePathMTUDiscovery,
   786  		ctx:                     ctx,
   787  	}
   788  
   789  	if isIETFVersionNumber(versionNumber) {
   790  		t.quicRoundTripper = &http3.RoundTripper{Dial: t.dialIETFQUIC}
   791  	} else {
   792  		var err error
   793  		t.quicRoundTripper, err = gQUICRoundTripper(t)
   794  		if err != nil {
   795  			return nil, errors.Trace(err)
   796  		}
   797  	}
   798  
   799  	return t, nil
   800  }
   801  
   802  func (t *QUICTransporter) SetRequestContext(ctx context.Context) {
   803  	// Note: can't use sync.Value since underlying type of ctx changes.
   804  	t.mutex.Lock()
   805  	defer t.mutex.Unlock()
   806  	t.ctx = ctx
   807  }
   808  
   809  // CloseIdleConnections wraps QUIC RoundTripper.Close, which provides the
   810  // necessary functionality for psiphon.transporter as used by
   811  // psiphon.MeekConn. Note that, unlike http.Transport.CloseIdleConnections,
   812  // the connections are closed regardless of idle status.
   813  func (t *QUICTransporter) CloseIdleConnections() {
   814  
   815  	// This operation doesn't prevent a concurrent http3.client.dial from
   816  	// establishing a new packet conn; we also rely on the request context to
   817  	// fully interrupt and stop a http3.RoundTripper.
   818  
   819  	t.closePacketConn()
   820  	t.quicRoundTripper.Close()
   821  }
   822  
   823  func (t *QUICTransporter) closePacketConn() {
   824  	packetConn := t.packetConn.Load()
   825  	if p, ok := packetConn.(net.PacketConn); ok {
   826  		p.Close()
   827  	}
   828  }
   829  
   830  func (t *QUICTransporter) dialIETFQUIC(
   831  	_, _ string, _ *tls.Config, _ *ietf_quic.Config) (ietf_quic.EarlySession, error) {
   832  	session, err := t.dialQUIC()
   833  	if err != nil {
   834  		return nil, errors.Trace(err)
   835  	}
   836  	return session.(*ietfQUICSession).Session.(ietf_quic.EarlySession), nil
   837  }
   838  
   839  func (t *QUICTransporter) dialQUIC() (retSession quicSession, retErr error) {
   840  
   841  	defer func() {
   842  		if retErr != nil && t.noticeEmitter != nil {
   843  			t.noticeEmitter(fmt.Sprintf("QUICTransporter.dialQUIC failed: %s", retErr))
   844  		}
   845  	}()
   846  
   847  	versionNumber, ok := supportedVersionNumbers[t.quicVersion]
   848  	if !ok {
   849  		return nil, errors.Tracef("unsupported version: %s", t.quicVersion)
   850  	}
   851  
   852  	t.mutex.Lock()
   853  	ctx := t.ctx
   854  	t.mutex.Unlock()
   855  	if ctx == nil {
   856  		ctx = context.Background()
   857  	}
   858  
   859  	packetConn, remoteAddr, err := t.udpDialer(ctx)
   860  	if err != nil {
   861  		return nil, errors.Trace(err)
   862  	}
   863  
   864  	session, err := dialQUIC(
   865  		ctx,
   866  		packetConn,
   867  		remoteAddr,
   868  		t.quicSNIAddress,
   869  		versionNumber,
   870  		t.clientHelloSeed,
   871  		nil,
   872  		0,
   873  		t.disablePathMTUDiscovery,
   874  		true)
   875  	if err != nil {
   876  		packetConn.Close()
   877  		return nil, errors.Trace(err)
   878  	}
   879  
   880  	// dialQUIC uses quic-go.DialContext as we must create our own UDP sockets to
   881  	// set properties such as BIND_TO_DEVICE. However, when DialContext is used,
   882  	// quic-go does not take responsibiity for closing the underlying packetConn
   883  	// when the QUIC session is closed.
   884  	//
   885  	// We track the most recent packetConn in QUICTransporter and close it:
   886  	// - when CloseIdleConnections is called, as it is by psiphon.MeekConn when
   887  	//   it is closing;
   888  	// - here in dialFunc, with the assumption that only one concurrent QUIC
   889  	//   session is used per h2quic.RoundTripper.
   890  	//
   891  	// This code also assume no concurrent calls to dialFunc, as otherwise a race
   892  	// condition exists between closePacketConn and Store.
   893  
   894  	t.closePacketConn()
   895  	t.packetConn.Store(packetConn)
   896  
   897  	return session, nil
   898  }
   899  
   900  // The following code provides support for using both gQUIC and IETF QUIC,
   901  // which are implemented in two different branches (now forks) of quic-go.
   902  // (The gQUIC functions are now located in gquic.go and the entire gQUIC
   903  // quic-go stack may be conditionally excluded from builds).
   904  //
   905  // dialQUIC uses the appropriate quic-go and returns quicSession which wraps
   906  // either a ietf_quic.Session or gquic.Session.
   907  //
   908  // muxPacketConn provides a multiplexing listener that directs packets to
   909  // either a ietf_quic.Listener or a gquic.Listener based on the content of the
   910  // packet.
   911  
   912  type quicListener interface {
   913  	Close() error
   914  	Addr() net.Addr
   915  	Accept() (quicSession, error)
   916  }
   917  
   918  type quicSession interface {
   919  	io.Closer
   920  	LocalAddr() net.Addr
   921  	RemoteAddr() net.Addr
   922  	AcceptStream() (quicStream, error)
   923  	OpenStream() (quicStream, error)
   924  	isErrorIndicatingClosed(err error) bool
   925  }
   926  
   927  type quicStream interface {
   928  	io.Reader
   929  	io.Writer
   930  	io.Closer
   931  	SetReadDeadline(t time.Time) error
   932  	SetWriteDeadline(t time.Time) error
   933  	SetDeadline(t time.Time) error
   934  }
   935  
   936  type quicRoundTripper interface {
   937  	http.RoundTripper
   938  	Close() error
   939  }
   940  
   941  type ietfQUICListener struct {
   942  	ietf_quic.Listener
   943  }
   944  
   945  func (l *ietfQUICListener) Accept() (quicSession, error) {
   946  	// A specific context is not provided since the interface needs to match the
   947  	// gquic-go API, which lacks context support.
   948  	session, err := l.Listener.Accept(context.Background())
   949  	if err != nil {
   950  		return nil, errors.Trace(err)
   951  	}
   952  	return &ietfQUICSession{Session: session}, nil
   953  }
   954  
   955  type ietfQUICSession struct {
   956  	ietf_quic.Session
   957  }
   958  
   959  func (s *ietfQUICSession) AcceptStream() (quicStream, error) {
   960  	// A specific context is not provided since the interface needs to match the
   961  	// gquic-go API, which lacks context support.
   962  	//
   963  	// TODO: once gQUIC support is retired, this context may be used in place
   964  	// of the deferredAcceptStream mechanism.
   965  	stream, err := s.Session.AcceptStream(context.Background())
   966  	if err != nil {
   967  		return nil, errors.Trace(err)
   968  	}
   969  	return stream, nil
   970  }
   971  
   972  func (s *ietfQUICSession) OpenStream() (quicStream, error) {
   973  	return s.Session.OpenStream()
   974  }
   975  
   976  func (s *ietfQUICSession) Close() error {
   977  	return s.Session.CloseWithError(0, "")
   978  }
   979  
   980  func (s *ietfQUICSession) isErrorIndicatingClosed(err error) bool {
   981  	if err == nil {
   982  		return false
   983  	}
   984  	errStr := err.Error()
   985  	// The target errors are of type qerr.ApplicationError and
   986  	// qerr.IdleTimeoutError, but these are not exported by quic-go.
   987  	return errStr == "Application error 0x0" ||
   988  		errStr == "timeout: no recent network activity"
   989  }
   990  
   991  func dialQUIC(
   992  	ctx context.Context,
   993  	packetConn net.PacketConn,
   994  	remoteAddr *net.UDPAddr,
   995  	quicSNIAddress string,
   996  	versionNumber uint32,
   997  	clientHelloSeed *prng.Seed,
   998  	getClientHelloRandom func() ([]byte, error),
   999  	clientMaxPacketSizeAdjustment int,
  1000  	disablePathMTUDiscovery bool,
  1001  	dialEarly bool) (quicSession, error) {
  1002  
  1003  	if isIETFVersionNumber(versionNumber) {
  1004  		quicConfig := &ietf_quic.Config{
  1005  			HandshakeIdleTimeout: time.Duration(1<<63 - 1),
  1006  			MaxIdleTimeout:       CLIENT_IDLE_TIMEOUT,
  1007  			KeepAlive:            true,
  1008  			Versions: []ietf_quic.VersionNumber{
  1009  				ietf_quic.VersionNumber(versionNumber)},
  1010  			ClientHelloSeed:               clientHelloSeed,
  1011  			GetClientHelloRandom:          getClientHelloRandom,
  1012  			ClientMaxPacketSizeAdjustment: clientMaxPacketSizeAdjustment,
  1013  			DisablePathMTUDiscovery:       disablePathMTUDiscovery,
  1014  		}
  1015  
  1016  		deadline, ok := ctx.Deadline()
  1017  		if ok {
  1018  			quicConfig.HandshakeIdleTimeout = time.Until(deadline)
  1019  		}
  1020  
  1021  		var dialSession ietf_quic.Session
  1022  		var err error
  1023  		tlsConfig := &tls.Config{
  1024  			InsecureSkipVerify: true,
  1025  			NextProtos:         []string{getALPN(versionNumber)},
  1026  		}
  1027  
  1028  		if dialEarly {
  1029  			dialSession, err = ietf_quic.DialEarlyContext(
  1030  				ctx,
  1031  				packetConn,
  1032  				remoteAddr,
  1033  				quicSNIAddress,
  1034  				tlsConfig,
  1035  				quicConfig)
  1036  		} else {
  1037  			dialSession, err = ietf_quic.DialContext(
  1038  				ctx,
  1039  				packetConn,
  1040  				remoteAddr,
  1041  				quicSNIAddress,
  1042  				tlsConfig,
  1043  				quicConfig)
  1044  		}
  1045  		if err != nil {
  1046  			return nil, errors.Trace(err)
  1047  		}
  1048  
  1049  		return &ietfQUICSession{Session: dialSession}, nil
  1050  
  1051  	} else {
  1052  
  1053  		quicSession, err := gQUICDialContext(
  1054  			ctx,
  1055  			packetConn,
  1056  			remoteAddr,
  1057  			quicSNIAddress,
  1058  			versionNumber)
  1059  		if err != nil {
  1060  			return nil, errors.Trace(err)
  1061  		}
  1062  
  1063  		return quicSession, nil
  1064  	}
  1065  }
  1066  
  1067  const (
  1068  	muxPacketQueueSize  = 128
  1069  	muxPacketBufferSize = 1452 // quic-go.MaxReceivePacketSize
  1070  )
  1071  
  1072  type packet struct {
  1073  	addr net.Addr
  1074  	size int
  1075  	data []byte
  1076  }
  1077  
  1078  // muxPacketConn delivers packets to a specific quic-go listener.
  1079  type muxPacketConn struct {
  1080  	localAddr net.Addr
  1081  	listener  *muxListener
  1082  	packets   chan *packet
  1083  }
  1084  
  1085  func newMuxPacketConn(localAddr net.Addr, listener *muxListener) *muxPacketConn {
  1086  	return &muxPacketConn{
  1087  		localAddr: localAddr,
  1088  		listener:  listener,
  1089  		packets:   make(chan *packet, muxPacketQueueSize),
  1090  	}
  1091  }
  1092  
  1093  func (conn *muxPacketConn) ReadFrom(b []byte) (int, net.Addr, error) {
  1094  
  1095  	select {
  1096  	case p := <-conn.packets:
  1097  
  1098  		// If b is too short, the packet is truncated. This won't happen as long as
  1099  		// muxPacketBufferSize matches quic-go.MaxReceivePacketSize.
  1100  		copy(b, p.data[0:p.size])
  1101  		n := p.size
  1102  		addr := p.addr
  1103  
  1104  		// Clear and replace packet buffer.
  1105  		p.size = 0
  1106  		conn.listener.packets <- p
  1107  
  1108  		return n, addr, nil
  1109  	case <-conn.listener.stopBroadcast:
  1110  		return 0, nil, io.EOF
  1111  	}
  1112  }
  1113  
  1114  func (conn *muxPacketConn) WriteTo(b []byte, addr net.Addr) (int, error) {
  1115  	return conn.listener.conn.WriteTo(b, addr)
  1116  }
  1117  
  1118  func (conn *muxPacketConn) Close() error {
  1119  	// This Close won't unblock Read/Write operations or propagate the Close
  1120  	// signal up to muxListener.  The correct way to shutdown is to call
  1121  	// muxListener.Close.
  1122  	return nil
  1123  }
  1124  
  1125  func (conn *muxPacketConn) LocalAddr() net.Addr {
  1126  	return conn.localAddr
  1127  }
  1128  
  1129  func (conn *muxPacketConn) SetDeadline(t time.Time) error {
  1130  	return errors.TraceNew("not supported")
  1131  }
  1132  
  1133  func (conn *muxPacketConn) SetReadDeadline(t time.Time) error {
  1134  	return errors.TraceNew("not supported")
  1135  }
  1136  
  1137  func (conn *muxPacketConn) SetWriteDeadline(t time.Time) error {
  1138  	return errors.TraceNew("not supported")
  1139  }
  1140  
  1141  // SetReadBuffer and SyscallConn provide passthroughs to the underlying
  1142  // net.UDPConn implementations, used to optimize the UDP receive buffer size.
  1143  // See https://github.com/lucas-clemente/quic-go/wiki/UDP-Receive-Buffer-Size
  1144  // and ietf_quic.setReceiveBuffer. Only the IETF stack will access these
  1145  // functions.
  1146  //
  1147  // Limitation: due to the relayPackets/ReadFrom scheme, this simple
  1148  // passthrough does not suffice to provide access to ReadMsgUDP for
  1149  // https://godoc.org/github.com/lucas-clemente/quic-go#ECNCapablePacketConn.
  1150  
  1151  func (conn *muxPacketConn) SetReadBuffer(bytes int) error {
  1152  	c, ok := conn.listener.conn.OOBCapablePacketConn.(interface {
  1153  		SetReadBuffer(int) error
  1154  	})
  1155  	if !ok {
  1156  		return errors.TraceNew("not supported")
  1157  	}
  1158  	return c.SetReadBuffer(bytes)
  1159  }
  1160  
  1161  func (conn *muxPacketConn) SyscallConn() (syscall.RawConn, error) {
  1162  	c, ok := conn.listener.conn.OOBCapablePacketConn.(interface {
  1163  		SyscallConn() (syscall.RawConn, error)
  1164  	})
  1165  	if !ok {
  1166  		return nil, errors.TraceNew("not supported")
  1167  	}
  1168  	return c.SyscallConn()
  1169  }
  1170  
  1171  // muxListener is a multiplexing packet conn listener which relays packets to
  1172  // multiple quic-go listeners.
  1173  type muxListener struct {
  1174  	logger           common.Logger
  1175  	isClosed         int32
  1176  	runWaitGroup     *sync.WaitGroup
  1177  	stopBroadcast    chan struct{}
  1178  	conn             *ObfuscatedPacketConn
  1179  	packets          chan *packet
  1180  	acceptedSessions chan quicSession
  1181  	ietfQUICConn     *muxPacketConn
  1182  	ietfQUICListener quicListener
  1183  	gQUICConn        *muxPacketConn
  1184  	gQUICListener    quicListener
  1185  }
  1186  
  1187  func newMuxListener(
  1188  	logger common.Logger,
  1189  	verifyClientHelloRandom func(net.Addr, []byte) bool,
  1190  	conn *ObfuscatedPacketConn,
  1191  	tlsCertificate tls.Certificate) (*muxListener, error) {
  1192  
  1193  	listener := &muxListener{
  1194  		logger:           logger,
  1195  		runWaitGroup:     new(sync.WaitGroup),
  1196  		stopBroadcast:    make(chan struct{}),
  1197  		conn:             conn,
  1198  		packets:          make(chan *packet, muxPacketQueueSize),
  1199  		acceptedSessions: make(chan quicSession, 2), // 1 per listener
  1200  	}
  1201  
  1202  	// All packet relay buffers are allocated in advance.
  1203  	for i := 0; i < muxPacketQueueSize; i++ {
  1204  		listener.packets <- &packet{data: make([]byte, muxPacketBufferSize)}
  1205  	}
  1206  
  1207  	listener.ietfQUICConn = newMuxPacketConn(conn.LocalAddr(), listener)
  1208  
  1209  	tlsConfig, ietfQUICConfig := makeIETFConfig(
  1210  		conn, verifyClientHelloRandom, tlsCertificate)
  1211  
  1212  	il, err := ietf_quic.Listen(listener.ietfQUICConn, tlsConfig, ietfQUICConfig)
  1213  	if err != nil {
  1214  		return nil, errors.Trace(err)
  1215  	}
  1216  	listener.ietfQUICListener = &ietfQUICListener{Listener: il}
  1217  
  1218  	listener.gQUICConn = newMuxPacketConn(conn.LocalAddr(), listener)
  1219  
  1220  	gl, err := gQUICListen(listener.gQUICConn, tlsCertificate, serverIdleTimeout)
  1221  	if err != nil {
  1222  		listener.ietfQUICListener.Close()
  1223  		return nil, errors.Trace(err)
  1224  	}
  1225  	listener.gQUICListener = gl
  1226  
  1227  	listener.runWaitGroup.Add(3)
  1228  	go listener.relayPackets()
  1229  	go listener.relayAcceptedSessions(listener.gQUICListener)
  1230  	go listener.relayAcceptedSessions(listener.ietfQUICListener)
  1231  
  1232  	return listener, nil
  1233  }
  1234  
  1235  func (listener *muxListener) relayPackets() {
  1236  	defer listener.runWaitGroup.Done()
  1237  
  1238  	for {
  1239  
  1240  		var p *packet
  1241  		select {
  1242  		case p = <-listener.packets:
  1243  		case <-listener.stopBroadcast:
  1244  			return
  1245  		}
  1246  
  1247  		// Read network packets. The DPI functionality of the obfuscation layer
  1248  		// identifies the type of QUIC, gQUIC or IETF, in addition to identifying
  1249  		// and processing obfuscation. This type information determines which
  1250  		// quic-go receives the packet.
  1251  		//
  1252  		// Network errors are not relayed to quic-go, as it will shut down the
  1253  		// server on any error returned from ReadFrom, even net.Error.Temporary()
  1254  		// errors.
  1255  
  1256  		var isIETF bool
  1257  		var err error
  1258  		p.size, _, _, p.addr, isIETF, err = listener.conn.readPacketWithType(p.data, nil)
  1259  		if err != nil {
  1260  			if listener.logger != nil {
  1261  				message := "readFromWithType failed"
  1262  				if e, ok := err.(net.Error); ok && e.Temporary() {
  1263  					listener.logger.WithTraceFields(
  1264  						common.LogFields{"error": err}).Debug(message)
  1265  				} else {
  1266  					listener.logger.WithTraceFields(
  1267  						common.LogFields{"error": err}).Warning(message)
  1268  				}
  1269  			}
  1270  			// TODO: propagate non-temporary errors to Accept?
  1271  			listener.packets <- p
  1272  			continue
  1273  		}
  1274  
  1275  		// Send the packet to the correct quic-go. The packet is dropped if the
  1276  		// target quic-go packet queue is full.
  1277  
  1278  		if isIETF {
  1279  			select {
  1280  			case listener.ietfQUICConn.packets <- p:
  1281  			default:
  1282  				listener.packets <- p
  1283  			}
  1284  		} else {
  1285  			select {
  1286  			case listener.gQUICConn.packets <- p:
  1287  			default:
  1288  				listener.packets <- p
  1289  			}
  1290  		}
  1291  	}
  1292  }
  1293  
  1294  func (listener *muxListener) relayAcceptedSessions(l quicListener) {
  1295  	defer listener.runWaitGroup.Done()
  1296  	for {
  1297  		session, err := l.Accept()
  1298  		if err != nil {
  1299  			if listener.logger != nil {
  1300  				message := "Accept failed"
  1301  				if e, ok := err.(net.Error); ok && e.Temporary() {
  1302  					listener.logger.WithTraceFields(
  1303  						common.LogFields{"error": err}).Debug(message)
  1304  				} else {
  1305  					listener.logger.WithTraceFields(
  1306  						common.LogFields{"error": err}).Warning(message)
  1307  				}
  1308  			}
  1309  			// TODO: propagate non-temporary errors to Accept?
  1310  			select {
  1311  			case <-listener.stopBroadcast:
  1312  				return
  1313  			default:
  1314  			}
  1315  			continue
  1316  		}
  1317  		select {
  1318  		case listener.acceptedSessions <- session:
  1319  		case <-listener.stopBroadcast:
  1320  			return
  1321  		}
  1322  	}
  1323  }
  1324  
  1325  func (listener *muxListener) Accept() (quicSession, error) {
  1326  	select {
  1327  	case conn := <-listener.acceptedSessions:
  1328  		return conn, nil
  1329  	case <-listener.stopBroadcast:
  1330  		return nil, errors.TraceNew("closed")
  1331  	}
  1332  }
  1333  
  1334  func (listener *muxListener) Close() error {
  1335  
  1336  	// Ensure close channel only called once.
  1337  	if !atomic.CompareAndSwapInt32(&listener.isClosed, 0, 1) {
  1338  		return nil
  1339  	}
  1340  
  1341  	close(listener.stopBroadcast)
  1342  
  1343  	var retErr error
  1344  
  1345  	err := listener.gQUICListener.Close()
  1346  	if err != nil && retErr == nil {
  1347  		retErr = errors.Trace(err)
  1348  	}
  1349  
  1350  	err = listener.ietfQUICListener.Close()
  1351  	if err != nil && retErr == nil {
  1352  		retErr = errors.Trace(err)
  1353  	}
  1354  
  1355  	err = listener.conn.Close()
  1356  	if err != nil && retErr == nil {
  1357  		retErr = errors.Trace(err)
  1358  	}
  1359  
  1360  	listener.runWaitGroup.Wait()
  1361  
  1362  	return retErr
  1363  }
  1364  
  1365  func (listener *muxListener) Addr() net.Addr {
  1366  	return listener.conn.LocalAddr()
  1367  }