wrapper.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package qtls
  2. import (
  3. "context"
  4. "crypto/tls"
  5. "net"
  6. "net/http"
  7. "github.com/sagernet/quic-go"
  8. "github.com/sagernet/quic-go/http3"
  9. M "github.com/sagernet/sing/common/metadata"
  10. aTLS "github.com/sagernet/sing/common/tls"
  11. )
  12. type QUICConfig interface {
  13. Dial(ctx context.Context, conn net.PacketConn, addr net.Addr, config *quic.Config) (quic.Connection, error)
  14. DialEarly(ctx context.Context, conn net.PacketConn, addr net.Addr, config *quic.Config) (quic.EarlyConnection, error)
  15. CreateTransport(conn net.PacketConn, quicConnPtr *quic.EarlyConnection, serverAddr M.Socksaddr, quicConfig *quic.Config, enableDatagrams bool) http.RoundTripper
  16. }
  17. type QUICServerConfig interface {
  18. Listen(conn net.PacketConn, config *quic.Config) (QUICListener, error)
  19. ListenEarly(conn net.PacketConn, config *quic.Config) (QUICEarlyListener, error)
  20. ConfigureHTTP3()
  21. }
  22. type QUICListener interface {
  23. Accept(ctx context.Context) (quic.Connection, error)
  24. Close() error
  25. Addr() net.Addr
  26. }
  27. type QUICEarlyListener interface {
  28. Accept(ctx context.Context) (quic.EarlyConnection, error)
  29. Close() error
  30. Addr() net.Addr
  31. }
  32. func Dial(ctx context.Context, conn net.PacketConn, addr net.Addr, config aTLS.Config, quicConfig *quic.Config) (quic.Connection, error) {
  33. if quicTLSConfig, isQUICConfig := config.(QUICConfig); isQUICConfig {
  34. return quicTLSConfig.Dial(ctx, conn, addr, quicConfig)
  35. }
  36. tlsConfig, err := config.Config()
  37. if err != nil {
  38. return nil, err
  39. }
  40. return quic.Dial(ctx, conn, addr, tlsConfig, quicConfig)
  41. }
  42. func DialEarly(ctx context.Context, conn net.PacketConn, addr net.Addr, config aTLS.Config, quicConfig *quic.Config) (quic.EarlyConnection, error) {
  43. if quicTLSConfig, isQUICConfig := config.(QUICConfig); isQUICConfig {
  44. return quicTLSConfig.DialEarly(ctx, conn, addr, quicConfig)
  45. }
  46. tlsConfig, err := config.Config()
  47. if err != nil {
  48. return nil, err
  49. }
  50. return quic.DialEarly(ctx, conn, addr, tlsConfig, quicConfig)
  51. }
  52. func CreateTransport(conn net.PacketConn, quicConnPtr *quic.EarlyConnection, serverAddr M.Socksaddr, config aTLS.Config, quicConfig *quic.Config, enableDatagrams bool) (http.RoundTripper, error) {
  53. if quicTLSConfig, isQUICConfig := config.(QUICConfig); isQUICConfig {
  54. return quicTLSConfig.CreateTransport(conn, quicConnPtr, serverAddr, quicConfig, enableDatagrams), nil
  55. }
  56. tlsConfig, err := config.Config()
  57. if err != nil {
  58. return nil, err
  59. }
  60. return &http3.RoundTripper{
  61. TLSClientConfig: tlsConfig,
  62. QuicConfig: quicConfig,
  63. EnableDatagrams: enableDatagrams,
  64. Dial: func(ctx context.Context, addr string, tlsCfg *tls.Config, cfg *quic.Config) (quic.EarlyConnection, error) {
  65. quicConn, err := quic.DialEarly(ctx, conn, serverAddr.UDPAddr(), tlsCfg, cfg)
  66. if err != nil {
  67. return nil, err
  68. }
  69. *quicConnPtr = quicConn
  70. return quicConn, nil
  71. },
  72. }, nil
  73. }
  74. func Listen(conn net.PacketConn, config aTLS.ServerConfig, quicConfig *quic.Config) (QUICListener, error) {
  75. if quicTLSConfig, isQUICConfig := config.(QUICServerConfig); isQUICConfig {
  76. return quicTLSConfig.Listen(conn, quicConfig)
  77. }
  78. tlsConfig, err := config.Config()
  79. if err != nil {
  80. return nil, err
  81. }
  82. return quic.Listen(conn, tlsConfig, quicConfig)
  83. }
  84. func ListenEarly(conn net.PacketConn, config aTLS.ServerConfig, quicConfig *quic.Config) (QUICEarlyListener, error) {
  85. if quicTLSConfig, isQUICConfig := config.(QUICServerConfig); isQUICConfig {
  86. return quicTLSConfig.ListenEarly(conn, quicConfig)
  87. }
  88. tlsConfig, err := config.Config()
  89. if err != nil {
  90. return nil, err
  91. }
  92. return quic.ListenEarly(conn, tlsConfig, quicConfig)
  93. }
  94. func ConfigureHTTP3(config aTLS.ServerConfig) error {
  95. if len(config.NextProtos()) == 0 {
  96. config.SetNextProtos([]string{http3.NextProtoH3})
  97. }
  98. if quicTLSConfig, isQUICConfig := config.(QUICServerConfig); isQUICConfig {
  99. quicTLSConfig.ConfigureHTTP3()
  100. return nil
  101. }
  102. tlsConfig, err := config.Config()
  103. if err != nil {
  104. return err
  105. }
  106. http3.ConfigureTLSConfig(tlsConfig)
  107. return nil
  108. }