github.com/metacubex/mihomo@v1.18.5/transport/tuic/server.go (about)

     1  package tuic
     2  
     3  import (
     4  	"bufio"
     5  	"context"
     6  	"crypto/tls"
     7  	"net"
     8  	"time"
     9  
    10  	"github.com/metacubex/mihomo/adapter/inbound"
    11  	N "github.com/metacubex/mihomo/common/net"
    12  	"github.com/metacubex/mihomo/common/utils"
    13  	C "github.com/metacubex/mihomo/constant"
    14  	"github.com/metacubex/mihomo/transport/socks5"
    15  	"github.com/metacubex/mihomo/transport/tuic/common"
    16  	v4 "github.com/metacubex/mihomo/transport/tuic/v4"
    17  	v5 "github.com/metacubex/mihomo/transport/tuic/v5"
    18  
    19  	"github.com/gofrs/uuid/v5"
    20  	"github.com/metacubex/quic-go"
    21  )
    22  
    23  type ServerOption struct {
    24  	HandleTcpFn func(conn net.Conn, addr socks5.Addr, additions ...inbound.Addition) error
    25  	HandleUdpFn func(addr socks5.Addr, packet C.UDPPacket, additions ...inbound.Addition) error
    26  
    27  	TlsConfig             *tls.Config
    28  	QuicConfig            *quic.Config
    29  	Tokens                [][32]byte          // V4 special
    30  	Users                 map[[16]byte]string // V5 special
    31  	CongestionController  string
    32  	AuthenticationTimeout time.Duration
    33  	MaxUdpRelayPacketSize int
    34  	CWND                  int
    35  }
    36  
    37  type Server struct {
    38  	*ServerOption
    39  	optionV4 *v4.ServerOption
    40  	optionV5 *v5.ServerOption
    41  	listener *quic.EarlyListener
    42  }
    43  
    44  func (s *Server) Serve() error {
    45  	for {
    46  		conn, err := s.listener.Accept(context.Background())
    47  		if err != nil {
    48  			return err
    49  		}
    50  		common.SetCongestionController(conn, s.CongestionController, s.CWND)
    51  		h := &serverHandler{
    52  			Server:   s,
    53  			quicConn: conn,
    54  			uuid:     utils.NewUUIDV4(),
    55  		}
    56  		if h.optionV4 != nil {
    57  			h.v4Handler = v4.NewServerHandler(h.optionV4, conn, h.uuid)
    58  		}
    59  		if h.optionV5 != nil {
    60  			h.v5Handler = v5.NewServerHandler(h.optionV5, conn, h.uuid)
    61  		}
    62  		go h.handle()
    63  	}
    64  }
    65  
    66  func (s *Server) Close() error {
    67  	return s.listener.Close()
    68  }
    69  
    70  type serverHandler struct {
    71  	*Server
    72  	quicConn quic.EarlyConnection
    73  	uuid     uuid.UUID
    74  
    75  	v4Handler common.ServerHandler
    76  	v5Handler common.ServerHandler
    77  }
    78  
    79  func (s *serverHandler) handle() {
    80  	go func() {
    81  		_ = s.handleUniStream()
    82  	}()
    83  	go func() {
    84  		_ = s.handleStream()
    85  	}()
    86  	go func() {
    87  		_ = s.handleMessage()
    88  	}()
    89  
    90  	<-s.quicConn.HandshakeComplete()
    91  	time.AfterFunc(s.AuthenticationTimeout, func() {
    92  		if s.v4Handler != nil {
    93  			if s.v4Handler.AuthOk() {
    94  				return
    95  			}
    96  		}
    97  
    98  		if s.v5Handler != nil {
    99  			if s.v5Handler.AuthOk() {
   100  				return
   101  			}
   102  		}
   103  
   104  		if s.v4Handler != nil {
   105  			s.v4Handler.HandleTimeout()
   106  		}
   107  
   108  		if s.v5Handler != nil {
   109  			s.v5Handler.HandleTimeout()
   110  		}
   111  	})
   112  }
   113  
   114  func (s *serverHandler) handleMessage() (err error) {
   115  	for {
   116  		var message []byte
   117  		message, err = s.quicConn.ReceiveDatagram(context.Background())
   118  		if err != nil {
   119  			return err
   120  		}
   121  		go func() (err error) {
   122  			if len(message) > 0 {
   123  				switch message[0] {
   124  				case v4.VER:
   125  					if s.v4Handler != nil {
   126  						return s.v4Handler.HandleMessage(message)
   127  					}
   128  				case v5.VER:
   129  					if s.v5Handler != nil {
   130  						return s.v5Handler.HandleMessage(message)
   131  					}
   132  				}
   133  			}
   134  			return
   135  		}()
   136  	}
   137  }
   138  
   139  func (s *serverHandler) handleStream() (err error) {
   140  	for {
   141  		var quicStream quic.Stream
   142  		quicStream, err = s.quicConn.AcceptStream(context.Background())
   143  		if err != nil {
   144  			return err
   145  		}
   146  		go func() (err error) {
   147  			stream := common.NewQuicStreamConn(
   148  				quicStream,
   149  				s.quicConn.LocalAddr(),
   150  				s.quicConn.RemoteAddr(),
   151  				nil,
   152  			)
   153  			conn := N.NewBufferedConn(stream)
   154  
   155  			verBytes, err := conn.Peek(1)
   156  			if err != nil {
   157  				_ = conn.Close()
   158  				return err
   159  			}
   160  
   161  			switch verBytes[0] {
   162  			case v4.VER:
   163  				if s.v4Handler != nil {
   164  					return s.v4Handler.HandleStream(conn)
   165  				}
   166  			case v5.VER:
   167  				if s.v5Handler != nil {
   168  					return s.v5Handler.HandleStream(conn)
   169  				}
   170  			}
   171  			return
   172  		}()
   173  	}
   174  }
   175  
   176  func (s *serverHandler) handleUniStream() (err error) {
   177  	for {
   178  		var stream quic.ReceiveStream
   179  		stream, err = s.quicConn.AcceptUniStream(context.Background())
   180  		if err != nil {
   181  			return err
   182  		}
   183  		go func() (err error) {
   184  			defer func() {
   185  				stream.CancelRead(0)
   186  			}()
   187  			reader := bufio.NewReader(stream)
   188  			verBytes, err := reader.Peek(1)
   189  			if err != nil {
   190  				return err
   191  			}
   192  
   193  			switch verBytes[0] {
   194  			case v4.VER:
   195  				if s.v4Handler != nil {
   196  					return s.v4Handler.HandleUniStream(reader)
   197  				}
   198  			case v5.VER:
   199  				if s.v5Handler != nil {
   200  					return s.v5Handler.HandleUniStream(reader)
   201  				}
   202  			}
   203  			return
   204  		}()
   205  	}
   206  }
   207  
   208  func NewServer(option *ServerOption, pc net.PacketConn) (*Server, error) {
   209  	listener, err := quic.ListenEarly(pc, option.TlsConfig, option.QuicConfig)
   210  	if err != nil {
   211  		return nil, err
   212  	}
   213  	server := &Server{
   214  		ServerOption: option,
   215  		listener:     listener,
   216  	}
   217  	if len(option.Tokens) > 0 {
   218  		server.optionV4 = &v4.ServerOption{
   219  			HandleTcpFn:           option.HandleTcpFn,
   220  			HandleUdpFn:           option.HandleUdpFn,
   221  			Tokens:                option.Tokens,
   222  			MaxUdpRelayPacketSize: option.MaxUdpRelayPacketSize,
   223  		}
   224  	}
   225  	if len(option.Users) > 0 {
   226  		maxUdpRelayPacketSize := option.MaxUdpRelayPacketSize
   227  		if maxUdpRelayPacketSize > MaxFragSizeV5 {
   228  			maxUdpRelayPacketSize = MaxFragSizeV5
   229  		}
   230  		server.optionV5 = &v5.ServerOption{
   231  			HandleTcpFn:           option.HandleTcpFn,
   232  			HandleUdpFn:           option.HandleUdpFn,
   233  			Users:                 option.Users,
   234  			MaxUdpRelayPacketSize: option.MaxUdpRelayPacketSize,
   235  		}
   236  	}
   237  	return server, nil
   238  }