v2ray.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package sip003
  2. import (
  3. "context"
  4. "net"
  5. "strconv"
  6. "github.com/sagernet/sing-box/adapter"
  7. "github.com/sagernet/sing-box/common/tls"
  8. C "github.com/sagernet/sing-box/constant"
  9. "github.com/sagernet/sing-box/option"
  10. "github.com/sagernet/sing-box/transport/v2ray"
  11. "github.com/sagernet/sing-vmess"
  12. E "github.com/sagernet/sing/common/exceptions"
  13. "github.com/sagernet/sing/common/json/badoption"
  14. "github.com/sagernet/sing/common/logger"
  15. M "github.com/sagernet/sing/common/metadata"
  16. N "github.com/sagernet/sing/common/network"
  17. )
  18. func init() {
  19. RegisterPlugin("v2ray-plugin", newV2RayPlugin)
  20. }
  21. func newV2RayPlugin(ctx context.Context, pluginOpts Args, router adapter.Router, dialer N.Dialer, serverAddr M.Socksaddr) (Plugin, error) {
  22. var tlsOptions option.OutboundTLSOptions
  23. if _, loaded := pluginOpts.Get("tls"); loaded {
  24. tlsOptions.Enabled = true
  25. }
  26. if certPath, certLoaded := pluginOpts.Get("cert"); certLoaded {
  27. tlsOptions.CertificatePath = certPath
  28. }
  29. if certRaw, certLoaded := pluginOpts.Get("certRaw"); certLoaded {
  30. certHead := "-----BEGIN CERTIFICATE-----"
  31. certTail := "-----END CERTIFICATE-----"
  32. fixedCert := certHead + "\n" + certRaw + "\n" + certTail
  33. tlsOptions.Certificate = []string{fixedCert}
  34. }
  35. mode := "websocket"
  36. if modeOpt, loaded := pluginOpts.Get("mode"); loaded {
  37. mode = modeOpt
  38. }
  39. host := "cloudfront.com"
  40. path := "/"
  41. if hostOpt, loaded := pluginOpts.Get("host"); loaded {
  42. host = hostOpt
  43. tlsOptions.ServerName = hostOpt
  44. }
  45. if pathOpt, loaded := pluginOpts.Get("path"); loaded {
  46. path = pathOpt
  47. }
  48. var tlsClient tls.Config
  49. var err error
  50. if tlsOptions.Enabled {
  51. tlsClient, err = tls.NewClient(ctx, logger.NOP(), serverAddr.AddrString(), tlsOptions)
  52. if err != nil {
  53. return nil, err
  54. }
  55. }
  56. var mux int
  57. var transportOptions option.V2RayTransportOptions
  58. switch mode {
  59. case "websocket":
  60. transportOptions = option.V2RayTransportOptions{
  61. Type: C.V2RayTransportTypeWebsocket,
  62. WebsocketOptions: option.V2RayWebsocketOptions{
  63. Headers: map[string]badoption.Listable[string]{
  64. "Host": []string{host},
  65. },
  66. Path: path,
  67. },
  68. }
  69. if muxOpt, loaded := pluginOpts.Get("mux"); loaded {
  70. muxVal, err := strconv.Atoi(muxOpt)
  71. if err != nil {
  72. return nil, E.Cause(err, "parse mux value")
  73. }
  74. mux = muxVal
  75. } else {
  76. mux = 1
  77. }
  78. case "quic":
  79. transportOptions = option.V2RayTransportOptions{
  80. Type: C.V2RayTransportTypeQUIC,
  81. }
  82. default:
  83. return nil, E.New("v2ray-plugin: unknown mode: " + mode)
  84. }
  85. transport, err := v2ray.NewClientTransport(context.Background(), dialer, serverAddr, transportOptions, tlsClient)
  86. if err != nil {
  87. return nil, err
  88. }
  89. if mux > 0 {
  90. return &v2rayMuxWrapper{transport}, nil
  91. }
  92. return transport, nil
  93. }
  94. var _ Plugin = (*v2rayMuxWrapper)(nil)
  95. type v2rayMuxWrapper struct {
  96. adapter.V2RayClientTransport
  97. }
  98. func (w *v2rayMuxWrapper) DialContext(ctx context.Context) (net.Conn, error) {
  99. conn, err := w.V2RayClientTransport.DialContext(ctx)
  100. if err != nil {
  101. return nil, err
  102. }
  103. return vmess.NewMuxConnWrapper(conn, vmess.MuxDestination), nil
  104. }