parser.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. package adapter
  2. import (
  3. "fmt"
  4. tlsC "github.com/metacubex/mihomo/component/tls"
  5. "github.com/metacubex/mihomo/adapter/outbound"
  6. "github.com/metacubex/mihomo/common/structure"
  7. C "github.com/metacubex/mihomo/constant"
  8. )
  9. func ParseProxy(mapping map[string]any) (C.Proxy, error) {
  10. decoder := structure.NewDecoder(structure.Option{TagName: "proxy", WeaklyTypedInput: true, KeyReplacer: structure.DefaultKeyReplacer})
  11. proxyType, existType := mapping["type"].(string)
  12. if !existType {
  13. return nil, fmt.Errorf("missing type")
  14. }
  15. var (
  16. proxy C.ProxyAdapter
  17. err error
  18. )
  19. switch proxyType {
  20. case "ss":
  21. ssOption := &outbound.ShadowSocksOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
  22. err = decoder.Decode(mapping, ssOption)
  23. if err != nil {
  24. break
  25. }
  26. proxy, err = outbound.NewShadowSocks(*ssOption)
  27. case "ssr":
  28. ssrOption := &outbound.ShadowSocksROption{}
  29. err = decoder.Decode(mapping, ssrOption)
  30. if err != nil {
  31. break
  32. }
  33. proxy, err = outbound.NewShadowSocksR(*ssrOption)
  34. case "socks5":
  35. socksOption := &outbound.Socks5Option{}
  36. err = decoder.Decode(mapping, socksOption)
  37. if err != nil {
  38. break
  39. }
  40. proxy, err = outbound.NewSocks5(*socksOption)
  41. case "http":
  42. httpOption := &outbound.HttpOption{}
  43. err = decoder.Decode(mapping, httpOption)
  44. if err != nil {
  45. break
  46. }
  47. proxy, err = outbound.NewHttp(*httpOption)
  48. case "vmess":
  49. vmessOption := &outbound.VmessOption{
  50. HTTPOpts: outbound.HTTPOptions{
  51. Method: "GET",
  52. Path: []string{"/"},
  53. },
  54. ClientFingerprint: tlsC.GetGlobalFingerprint(),
  55. }
  56. err = decoder.Decode(mapping, vmessOption)
  57. if err != nil {
  58. break
  59. }
  60. proxy, err = outbound.NewVmess(*vmessOption)
  61. case "vless":
  62. vlessOption := &outbound.VlessOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
  63. err = decoder.Decode(mapping, vlessOption)
  64. if err != nil {
  65. break
  66. }
  67. proxy, err = outbound.NewVless(*vlessOption)
  68. case "snell":
  69. snellOption := &outbound.SnellOption{}
  70. err = decoder.Decode(mapping, snellOption)
  71. if err != nil {
  72. break
  73. }
  74. proxy, err = outbound.NewSnell(*snellOption)
  75. case "trojan":
  76. trojanOption := &outbound.TrojanOption{ClientFingerprint: tlsC.GetGlobalFingerprint()}
  77. err = decoder.Decode(mapping, trojanOption)
  78. if err != nil {
  79. break
  80. }
  81. proxy, err = outbound.NewTrojan(*trojanOption)
  82. case "hysteria":
  83. hyOption := &outbound.HysteriaOption{}
  84. err = decoder.Decode(mapping, hyOption)
  85. if err != nil {
  86. break
  87. }
  88. proxy, err = outbound.NewHysteria(*hyOption)
  89. case "hysteria2":
  90. hyOption := &outbound.Hysteria2Option{}
  91. err = decoder.Decode(mapping, hyOption)
  92. if err != nil {
  93. break
  94. }
  95. proxy, err = outbound.NewHysteria2(*hyOption)
  96. case "wireguard":
  97. wgOption := &outbound.WireGuardOption{}
  98. err = decoder.Decode(mapping, wgOption)
  99. if err != nil {
  100. break
  101. }
  102. proxy, err = outbound.NewWireGuard(*wgOption)
  103. case "tuic":
  104. tuicOption := &outbound.TuicOption{}
  105. err = decoder.Decode(mapping, tuicOption)
  106. if err != nil {
  107. break
  108. }
  109. proxy, err = outbound.NewTuic(*tuicOption)
  110. case "direct":
  111. directOption := &outbound.DirectOption{}
  112. err = decoder.Decode(mapping, directOption)
  113. if err != nil {
  114. break
  115. }
  116. proxy = outbound.NewDirectWithOption(*directOption)
  117. case "dns":
  118. dnsOptions := &outbound.DnsOption{}
  119. err = decoder.Decode(mapping, dnsOptions)
  120. if err != nil {
  121. break
  122. }
  123. proxy = outbound.NewDnsWithOption(*dnsOptions)
  124. case "reject":
  125. rejectOption := &outbound.RejectOption{}
  126. err = decoder.Decode(mapping, rejectOption)
  127. if err != nil {
  128. break
  129. }
  130. proxy = outbound.NewRejectWithOption(*rejectOption)
  131. case "ssh":
  132. sshOption := &outbound.SshOption{}
  133. err = decoder.Decode(mapping, sshOption)
  134. if err != nil {
  135. break
  136. }
  137. proxy, err = outbound.NewSsh(*sshOption)
  138. default:
  139. return nil, fmt.Errorf("unsupport proxy type: %s", proxyType)
  140. }
  141. if err != nil {
  142. return nil, err
  143. }
  144. if muxMapping, muxExist := mapping["smux"].(map[string]any); muxExist {
  145. muxOption := &outbound.SingMuxOption{}
  146. err = decoder.Decode(muxMapping, muxOption)
  147. if err != nil {
  148. return nil, err
  149. }
  150. if muxOption.Enabled {
  151. proxy, err = outbound.NewSingMux(*muxOption, proxy, proxy.(outbound.ProxyBase))
  152. if err != nil {
  153. return nil, err
  154. }
  155. }
  156. }
  157. return NewProxy(proxy), nil
  158. }