github.com/sagernet/sing-box@v1.2.7/transport/v2rayquic/server.go (about)

     1  package v2rayquic
     2  
     3  import (
     4  	"context"
     5  	"net"
     6  	"os"
     7  
     8  	"github.com/sagernet/quic-go"
     9  	"github.com/sagernet/sing-box/adapter"
    10  	"github.com/sagernet/sing-box/common/tls"
    11  	C "github.com/sagernet/sing-box/constant"
    12  	"github.com/sagernet/sing-box/option"
    13  	"github.com/sagernet/sing-box/transport/hysteria"
    14  	"github.com/sagernet/sing/common"
    15  	E "github.com/sagernet/sing/common/exceptions"
    16  	M "github.com/sagernet/sing/common/metadata"
    17  	N "github.com/sagernet/sing/common/network"
    18  )
    19  
    20  var _ adapter.V2RayServerTransport = (*Server)(nil)
    21  
    22  type Server struct {
    23  	ctx          context.Context
    24  	tlsConfig    *tls.STDConfig
    25  	quicConfig   *quic.Config
    26  	handler      adapter.V2RayServerTransportHandler
    27  	errorHandler E.Handler
    28  	udpListener  net.PacketConn
    29  	quicListener quic.Listener
    30  }
    31  
    32  func NewServer(ctx context.Context, options option.V2RayQUICOptions, tlsConfig tls.ServerConfig, handler adapter.V2RayServerTransportHandler) (adapter.V2RayServerTransport, error) {
    33  	quicConfig := &quic.Config{
    34  		DisablePathMTUDiscovery: !C.IsLinux && !C.IsWindows,
    35  	}
    36  	stdConfig, err := tlsConfig.Config()
    37  	if err != nil {
    38  		return nil, err
    39  	}
    40  	if len(stdConfig.NextProtos) == 0 {
    41  		stdConfig.NextProtos = []string{"h2", "http/1.1"}
    42  	}
    43  	server := &Server{
    44  		ctx:        ctx,
    45  		tlsConfig:  stdConfig,
    46  		quicConfig: quicConfig,
    47  		handler:    handler,
    48  	}
    49  	return server, nil
    50  }
    51  
    52  func (s *Server) Network() []string {
    53  	return []string{N.NetworkUDP}
    54  }
    55  
    56  func (s *Server) Serve(listener net.Listener) error {
    57  	return os.ErrInvalid
    58  }
    59  
    60  func (s *Server) ServePacket(listener net.PacketConn) error {
    61  	quicListener, err := quic.Listen(listener, s.tlsConfig, s.quicConfig)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	s.udpListener = listener
    66  	s.quicListener = quicListener
    67  	go s.acceptLoop()
    68  	return nil
    69  }
    70  
    71  func (s *Server) acceptLoop() {
    72  	for {
    73  		conn, err := s.quicListener.Accept(s.ctx)
    74  		if err != nil {
    75  			return
    76  		}
    77  		go func() {
    78  			hErr := s.streamAcceptLoop(conn)
    79  			if hErr != nil {
    80  				s.errorHandler.NewError(conn.Context(), hErr)
    81  			}
    82  		}()
    83  	}
    84  }
    85  
    86  func (s *Server) streamAcceptLoop(conn quic.Connection) error {
    87  	for {
    88  		stream, err := conn.AcceptStream(s.ctx)
    89  		if err != nil {
    90  			return err
    91  		}
    92  		go s.handler.NewConnection(conn.Context(), &hysteria.StreamWrapper{Conn: conn, Stream: stream}, M.Metadata{})
    93  	}
    94  }
    95  
    96  func (s *Server) Close() error {
    97  	return common.Close(s.udpListener, s.quicListener)
    98  }