server.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. //go:build with_quic
  2. package v2rayquic
  3. import (
  4. "context"
  5. "net"
  6. "os"
  7. "github.com/sagernet/quic-go"
  8. "github.com/sagernet/quic-go/http3"
  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-quic"
  14. "github.com/sagernet/sing/common"
  15. E "github.com/sagernet/sing/common/exceptions"
  16. "github.com/sagernet/sing/common/logger"
  17. M "github.com/sagernet/sing/common/metadata"
  18. N "github.com/sagernet/sing/common/network"
  19. )
  20. var _ adapter.V2RayServerTransport = (*Server)(nil)
  21. type Server struct {
  22. ctx context.Context
  23. logger logger.ContextLogger
  24. tlsConfig tls.ServerConfig
  25. quicConfig *quic.Config
  26. handler adapter.V2RayServerTransportHandler
  27. udpListener net.PacketConn
  28. quicListener qtls.Listener
  29. }
  30. func NewServer(ctx context.Context, logger logger.ContextLogger, options option.V2RayQUICOptions, tlsConfig tls.ServerConfig, handler adapter.V2RayServerTransportHandler) (adapter.V2RayServerTransport, error) {
  31. quicConfig := &quic.Config{
  32. DisablePathMTUDiscovery: !C.IsLinux && !C.IsWindows,
  33. }
  34. if len(tlsConfig.NextProtos()) == 0 {
  35. tlsConfig.SetNextProtos([]string{http3.NextProtoH3})
  36. }
  37. server := &Server{
  38. ctx: ctx,
  39. logger: logger,
  40. tlsConfig: tlsConfig,
  41. quicConfig: quicConfig,
  42. handler: handler,
  43. }
  44. return server, nil
  45. }
  46. func (s *Server) Network() []string {
  47. return []string{N.NetworkUDP}
  48. }
  49. func (s *Server) Serve(listener net.Listener) error {
  50. return os.ErrInvalid
  51. }
  52. func (s *Server) ServePacket(listener net.PacketConn) error {
  53. quicListener, err := qtls.Listen(listener, s.tlsConfig, s.quicConfig)
  54. if err != nil {
  55. return err
  56. }
  57. s.udpListener = listener
  58. s.quicListener = quicListener
  59. go s.acceptLoop()
  60. return nil
  61. }
  62. func (s *Server) acceptLoop() {
  63. for {
  64. conn, err := s.quicListener.Accept(s.ctx)
  65. if err != nil {
  66. return
  67. }
  68. go func() {
  69. hErr := s.streamAcceptLoop(conn)
  70. if hErr != nil && !E.IsClosedOrCanceled(hErr) {
  71. s.logger.ErrorContext(conn.Context(), hErr)
  72. }
  73. }()
  74. }
  75. }
  76. func (s *Server) streamAcceptLoop(conn *quic.Conn) error {
  77. for {
  78. stream, err := conn.AcceptStream(s.ctx)
  79. if err != nil {
  80. return err
  81. }
  82. go s.handler.NewConnectionEx(conn.Context(), &StreamWrapper{Conn: conn, Stream: stream}, M.SocksaddrFromNet(conn.RemoteAddr()), M.Socksaddr{}, nil)
  83. }
  84. }
  85. func (s *Server) Close() error {
  86. return common.Close(s.udpListener, s.quicListener)
  87. }