wireguard.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663
  1. package outbound
  2. import (
  3. "context"
  4. "encoding/base64"
  5. "encoding/hex"
  6. "errors"
  7. "fmt"
  8. "net"
  9. "net/netip"
  10. "runtime"
  11. "strconv"
  12. "strings"
  13. "sync"
  14. "time"
  15. "github.com/metacubex/mihomo/common/atomic"
  16. CN "github.com/metacubex/mihomo/common/net"
  17. "github.com/metacubex/mihomo/component/dialer"
  18. "github.com/metacubex/mihomo/component/proxydialer"
  19. "github.com/metacubex/mihomo/component/resolver"
  20. "github.com/metacubex/mihomo/component/slowdown"
  21. C "github.com/metacubex/mihomo/constant"
  22. "github.com/metacubex/mihomo/dns"
  23. "github.com/metacubex/mihomo/log"
  24. wireguard "github.com/metacubex/sing-wireguard"
  25. "github.com/sagernet/sing/common"
  26. "github.com/sagernet/sing/common/debug"
  27. E "github.com/sagernet/sing/common/exceptions"
  28. M "github.com/sagernet/sing/common/metadata"
  29. "github.com/sagernet/wireguard-go/device"
  30. )
  31. type WireGuard struct {
  32. *Base
  33. bind *wireguard.ClientBind
  34. device *device.Device
  35. tunDevice wireguard.Device
  36. dialer proxydialer.SingDialer
  37. resolver *dns.Resolver
  38. refP *refProxyAdapter
  39. initOk atomic.Bool
  40. initMutex sync.Mutex
  41. initErr error
  42. option WireGuardOption
  43. connectAddr M.Socksaddr
  44. localPrefixes []netip.Prefix
  45. serverAddrMap map[M.Socksaddr]netip.AddrPort
  46. serverAddrTime atomic.TypedValue[time.Time]
  47. serverAddrMutex sync.Mutex
  48. closeCh chan struct{} // for test
  49. }
  50. type WireGuardOption struct {
  51. BasicOption
  52. WireGuardPeerOption
  53. Name string `proxy:"name"`
  54. Ip string `proxy:"ip,omitempty"`
  55. Ipv6 string `proxy:"ipv6,omitempty"`
  56. PrivateKey string `proxy:"private-key"`
  57. Workers int `proxy:"workers,omitempty"`
  58. MTU int `proxy:"mtu,omitempty"`
  59. UDP bool `proxy:"udp,omitempty"`
  60. PersistentKeepalive int `proxy:"persistent-keepalive,omitempty"`
  61. Peers []WireGuardPeerOption `proxy:"peers,omitempty"`
  62. RemoteDnsResolve bool `proxy:"remote-dns-resolve,omitempty"`
  63. Dns []string `proxy:"dns,omitempty"`
  64. RefreshServerIPInterval int `proxy:"refresh-server-ip-interval,omitempty"`
  65. }
  66. type WireGuardPeerOption struct {
  67. Server string `proxy:"server"`
  68. Port int `proxy:"port"`
  69. PublicKey string `proxy:"public-key,omitempty"`
  70. PreSharedKey string `proxy:"pre-shared-key,omitempty"`
  71. Reserved []uint8 `proxy:"reserved,omitempty"`
  72. AllowedIPs []string `proxy:"allowed-ips,omitempty"`
  73. }
  74. type wgSingErrorHandler struct {
  75. name string
  76. }
  77. var _ E.Handler = (*wgSingErrorHandler)(nil)
  78. func (w wgSingErrorHandler) NewError(ctx context.Context, err error) {
  79. if E.IsClosedOrCanceled(err) {
  80. log.SingLogger.Debug(fmt.Sprintf("[WG](%s) connection closed: %s", w.name, err))
  81. return
  82. }
  83. log.SingLogger.Error(fmt.Sprintf("[WG](%s) %s", w.name, err))
  84. }
  85. type wgNetDialer struct {
  86. tunDevice wireguard.Device
  87. }
  88. var _ dialer.NetDialer = (*wgNetDialer)(nil)
  89. func (d wgNetDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
  90. return d.tunDevice.DialContext(ctx, network, M.ParseSocksaddr(address).Unwrap())
  91. }
  92. func (option WireGuardPeerOption) Addr() M.Socksaddr {
  93. return M.ParseSocksaddrHostPort(option.Server, uint16(option.Port))
  94. }
  95. func (option WireGuardOption) Prefixes() ([]netip.Prefix, error) {
  96. localPrefixes := make([]netip.Prefix, 0, 2)
  97. if len(option.Ip) > 0 {
  98. if !strings.Contains(option.Ip, "/") {
  99. option.Ip = option.Ip + "/32"
  100. }
  101. if prefix, err := netip.ParsePrefix(option.Ip); err == nil {
  102. localPrefixes = append(localPrefixes, prefix)
  103. } else {
  104. return nil, E.Cause(err, "ip address parse error")
  105. }
  106. }
  107. if len(option.Ipv6) > 0 {
  108. if !strings.Contains(option.Ipv6, "/") {
  109. option.Ipv6 = option.Ipv6 + "/128"
  110. }
  111. if prefix, err := netip.ParsePrefix(option.Ipv6); err == nil {
  112. localPrefixes = append(localPrefixes, prefix)
  113. } else {
  114. return nil, E.Cause(err, "ipv6 address parse error")
  115. }
  116. }
  117. if len(localPrefixes) == 0 {
  118. return nil, E.New("missing local address")
  119. }
  120. return localPrefixes, nil
  121. }
  122. func NewWireGuard(option WireGuardOption) (*WireGuard, error) {
  123. outbound := &WireGuard{
  124. Base: &Base{
  125. name: option.Name,
  126. addr: net.JoinHostPort(option.Server, strconv.Itoa(option.Port)),
  127. tp: C.WireGuard,
  128. udp: option.UDP,
  129. iface: option.Interface,
  130. rmark: option.RoutingMark,
  131. prefer: C.NewDNSPrefer(option.IPVersion),
  132. },
  133. dialer: proxydialer.NewSlowDownSingDialer(proxydialer.NewByNameSingDialer(option.DialerProxy, dialer.NewDialer()), slowdown.New()),
  134. }
  135. runtime.SetFinalizer(outbound, closeWireGuard)
  136. var reserved [3]uint8
  137. if len(option.Reserved) > 0 {
  138. if len(option.Reserved) != 3 {
  139. return nil, E.New("invalid reserved value, required 3 bytes, got ", len(option.Reserved))
  140. }
  141. copy(reserved[:], option.Reserved)
  142. }
  143. var isConnect bool
  144. if len(option.Peers) < 2 {
  145. isConnect = true
  146. if len(option.Peers) == 1 {
  147. outbound.connectAddr = option.Peers[0].Addr()
  148. } else {
  149. outbound.connectAddr = option.Addr()
  150. }
  151. }
  152. outbound.bind = wireguard.NewClientBind(context.Background(), wgSingErrorHandler{outbound.Name()}, outbound.dialer, isConnect, outbound.connectAddr.AddrPort(), reserved)
  153. var err error
  154. outbound.localPrefixes, err = option.Prefixes()
  155. if err != nil {
  156. return nil, err
  157. }
  158. {
  159. bytes, err := base64.StdEncoding.DecodeString(option.PrivateKey)
  160. if err != nil {
  161. return nil, E.Cause(err, "decode private key")
  162. }
  163. option.PrivateKey = hex.EncodeToString(bytes)
  164. }
  165. if len(option.Peers) > 0 {
  166. for i := range option.Peers {
  167. peer := &option.Peers[i] // we need modify option here
  168. bytes, err := base64.StdEncoding.DecodeString(peer.PublicKey)
  169. if err != nil {
  170. return nil, E.Cause(err, "decode public key for peer ", i)
  171. }
  172. peer.PublicKey = hex.EncodeToString(bytes)
  173. if peer.PreSharedKey != "" {
  174. bytes, err := base64.StdEncoding.DecodeString(peer.PreSharedKey)
  175. if err != nil {
  176. return nil, E.Cause(err, "decode pre shared key for peer ", i)
  177. }
  178. peer.PreSharedKey = hex.EncodeToString(bytes)
  179. }
  180. if len(peer.AllowedIPs) == 0 {
  181. return nil, E.New("missing allowed_ips for peer ", i)
  182. }
  183. if len(peer.Reserved) > 0 {
  184. if len(peer.Reserved) != 3 {
  185. return nil, E.New("invalid reserved value for peer ", i, ", required 3 bytes, got ", len(peer.Reserved))
  186. }
  187. }
  188. }
  189. } else {
  190. {
  191. bytes, err := base64.StdEncoding.DecodeString(option.PublicKey)
  192. if err != nil {
  193. return nil, E.Cause(err, "decode peer public key")
  194. }
  195. option.PublicKey = hex.EncodeToString(bytes)
  196. }
  197. if option.PreSharedKey != "" {
  198. bytes, err := base64.StdEncoding.DecodeString(option.PreSharedKey)
  199. if err != nil {
  200. return nil, E.Cause(err, "decode pre shared key")
  201. }
  202. option.PreSharedKey = hex.EncodeToString(bytes)
  203. }
  204. }
  205. outbound.option = option
  206. mtu := option.MTU
  207. if mtu == 0 {
  208. mtu = 1408
  209. }
  210. if len(outbound.localPrefixes) == 0 {
  211. return nil, E.New("missing local address")
  212. }
  213. outbound.tunDevice, err = wireguard.NewStackDevice(outbound.localPrefixes, uint32(mtu))
  214. if err != nil {
  215. return nil, E.Cause(err, "create WireGuard device")
  216. }
  217. outbound.device = device.NewDevice(context.Background(), outbound.tunDevice, outbound.bind, &device.Logger{
  218. Verbosef: func(format string, args ...interface{}) {
  219. log.SingLogger.Debug(fmt.Sprintf("[WG](%s) %s", option.Name, fmt.Sprintf(format, args...)))
  220. },
  221. Errorf: func(format string, args ...interface{}) {
  222. log.SingLogger.Error(fmt.Sprintf("[WG](%s) %s", option.Name, fmt.Sprintf(format, args...)))
  223. },
  224. }, option.Workers)
  225. var has6 bool
  226. for _, address := range outbound.localPrefixes {
  227. if !address.Addr().Unmap().Is4() {
  228. has6 = true
  229. break
  230. }
  231. }
  232. refP := &refProxyAdapter{}
  233. outbound.refP = refP
  234. if option.RemoteDnsResolve && len(option.Dns) > 0 {
  235. nss, err := dns.ParseNameServer(option.Dns)
  236. if err != nil {
  237. return nil, err
  238. }
  239. for i := range nss {
  240. nss[i].ProxyAdapter = refP
  241. }
  242. outbound.resolver = dns.NewResolver(dns.Config{
  243. Main: nss,
  244. IPv6: has6,
  245. })
  246. }
  247. return outbound, nil
  248. }
  249. func (w *WireGuard) resolve(ctx context.Context, address M.Socksaddr) (netip.AddrPort, error) {
  250. if address.Addr.IsValid() {
  251. return address.AddrPort(), nil
  252. }
  253. udpAddr, err := resolveUDPAddrWithPrefer(ctx, "udp", address.String(), w.prefer)
  254. if err != nil {
  255. return netip.AddrPort{}, err
  256. }
  257. // net.ResolveUDPAddr maybe return 4in6 address, so unmap at here
  258. addrPort := udpAddr.AddrPort()
  259. return netip.AddrPortFrom(addrPort.Addr().Unmap(), addrPort.Port()), nil
  260. }
  261. func (w *WireGuard) init(ctx context.Context) error {
  262. err := w.init0(ctx)
  263. if err != nil {
  264. return err
  265. }
  266. w.updateServerAddr(ctx)
  267. return nil
  268. }
  269. func (w *WireGuard) init0(ctx context.Context) error {
  270. if w.initOk.Load() {
  271. return nil
  272. }
  273. w.initMutex.Lock()
  274. defer w.initMutex.Unlock()
  275. // double check like sync.Once
  276. if w.initOk.Load() {
  277. return nil
  278. }
  279. if w.initErr != nil {
  280. return w.initErr
  281. }
  282. w.bind.ResetReservedForEndpoint()
  283. w.serverAddrMap = make(map[M.Socksaddr]netip.AddrPort)
  284. ipcConf, err := w.genIpcConf(ctx, false)
  285. if err != nil {
  286. // !!! do not set initErr here !!!
  287. // let us can retry domain resolve in next time
  288. return err
  289. }
  290. if debug.Enabled {
  291. log.SingLogger.Trace(fmt.Sprintf("[WG](%s) created wireguard ipc conf: \n %s", w.option.Name, ipcConf))
  292. }
  293. err = w.device.IpcSet(ipcConf)
  294. if err != nil {
  295. w.initErr = E.Cause(err, "setup wireguard")
  296. return w.initErr
  297. }
  298. w.serverAddrTime.Store(time.Now())
  299. err = w.tunDevice.Start()
  300. if err != nil {
  301. w.initErr = err
  302. return w.initErr
  303. }
  304. w.initOk.Store(true)
  305. return nil
  306. }
  307. func (w *WireGuard) updateServerAddr(ctx context.Context) {
  308. if w.option.RefreshServerIPInterval != 0 && time.Since(w.serverAddrTime.Load()) > time.Second*time.Duration(w.option.RefreshServerIPInterval) {
  309. if w.serverAddrMutex.TryLock() {
  310. defer w.serverAddrMutex.Unlock()
  311. ipcConf, err := w.genIpcConf(ctx, true)
  312. if err != nil {
  313. log.Warnln("[WG](%s)UpdateServerAddr failed to generate wireguard ipc conf: %s", w.option.Name, err)
  314. return
  315. }
  316. err = w.device.IpcSet(ipcConf)
  317. if err != nil {
  318. log.Warnln("[WG](%s)UpdateServerAddr failed to update wireguard ipc conf: %s", w.option.Name, err)
  319. return
  320. }
  321. w.serverAddrTime.Store(time.Now())
  322. }
  323. }
  324. }
  325. func (w *WireGuard) genIpcConf(ctx context.Context, updateOnly bool) (string, error) {
  326. ipcConf := ""
  327. if !updateOnly {
  328. ipcConf += "private_key=" + w.option.PrivateKey + "\n"
  329. }
  330. if len(w.option.Peers) > 0 {
  331. for i, peer := range w.option.Peers {
  332. peerAddr := peer.Addr()
  333. destination, err := w.resolve(ctx, peerAddr)
  334. if err != nil {
  335. return "", E.Cause(err, "resolve endpoint domain for peer ", i)
  336. }
  337. if w.serverAddrMap[peerAddr] != destination {
  338. w.serverAddrMap[peerAddr] = destination
  339. } else if updateOnly {
  340. continue
  341. }
  342. if len(w.option.Peers) == 1 { // must call SetConnectAddr if isConnect == true
  343. w.bind.SetConnectAddr(destination)
  344. }
  345. ipcConf += "public_key=" + peer.PublicKey + "\n"
  346. if updateOnly {
  347. ipcConf += "update_only=true\n"
  348. }
  349. ipcConf += "endpoint=" + destination.String() + "\n"
  350. if len(peer.Reserved) > 0 {
  351. var reserved [3]uint8
  352. copy(reserved[:], w.option.Reserved)
  353. w.bind.SetReservedForEndpoint(destination, reserved)
  354. }
  355. if updateOnly {
  356. continue
  357. }
  358. if peer.PreSharedKey != "" {
  359. ipcConf += "preshared_key=" + peer.PreSharedKey + "\n"
  360. }
  361. for _, allowedIP := range peer.AllowedIPs {
  362. ipcConf += "allowed_ip=" + allowedIP + "\n"
  363. }
  364. if w.option.PersistentKeepalive != 0 {
  365. ipcConf += fmt.Sprintf("persistent_keepalive_interval=%d\n", w.option.PersistentKeepalive)
  366. }
  367. }
  368. } else {
  369. destination, err := w.resolve(ctx, w.connectAddr)
  370. if err != nil {
  371. return "", E.Cause(err, "resolve endpoint domain")
  372. }
  373. if w.serverAddrMap[w.connectAddr] != destination {
  374. w.serverAddrMap[w.connectAddr] = destination
  375. } else if updateOnly {
  376. return "", nil
  377. }
  378. w.bind.SetConnectAddr(destination) // must call SetConnectAddr if isConnect == true
  379. ipcConf += "public_key=" + w.option.PublicKey + "\n"
  380. if updateOnly {
  381. ipcConf += "update_only=true\n"
  382. }
  383. ipcConf += "endpoint=" + destination.String() + "\n"
  384. if updateOnly {
  385. return ipcConf, nil
  386. }
  387. if w.option.PreSharedKey != "" {
  388. ipcConf += "preshared_key=" + w.option.PreSharedKey + "\n"
  389. }
  390. var has4, has6 bool
  391. for _, address := range w.localPrefixes {
  392. if address.Addr().Is4() {
  393. has4 = true
  394. } else {
  395. has6 = true
  396. }
  397. }
  398. if has4 {
  399. ipcConf += "allowed_ip=0.0.0.0/0\n"
  400. }
  401. if has6 {
  402. ipcConf += "allowed_ip=::/0\n"
  403. }
  404. if w.option.PersistentKeepalive != 0 {
  405. ipcConf += fmt.Sprintf("persistent_keepalive_interval=%d\n", w.option.PersistentKeepalive)
  406. }
  407. }
  408. return ipcConf, nil
  409. }
  410. func closeWireGuard(w *WireGuard) {
  411. if w.device != nil {
  412. w.device.Close()
  413. }
  414. _ = common.Close(w.tunDevice)
  415. if w.closeCh != nil {
  416. close(w.closeCh)
  417. }
  418. }
  419. func (w *WireGuard) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.Conn, err error) {
  420. options := w.Base.DialOptions(opts...)
  421. w.dialer.SetDialer(dialer.NewDialer(options...))
  422. var conn net.Conn
  423. if err = w.init(ctx); err != nil {
  424. return nil, err
  425. }
  426. if !metadata.Resolved() || w.resolver != nil {
  427. r := resolver.DefaultResolver
  428. if w.resolver != nil {
  429. w.refP.SetProxyAdapter(w)
  430. defer w.refP.ClearProxyAdapter()
  431. r = w.resolver
  432. }
  433. options = append(options, dialer.WithResolver(r))
  434. options = append(options, dialer.WithNetDialer(wgNetDialer{tunDevice: w.tunDevice}))
  435. conn, err = dialer.NewDialer(options...).DialContext(ctx, "tcp", metadata.RemoteAddress())
  436. } else {
  437. conn, err = w.tunDevice.DialContext(ctx, "tcp", M.SocksaddrFrom(metadata.DstIP, metadata.DstPort).Unwrap())
  438. }
  439. if err != nil {
  440. return nil, err
  441. }
  442. if conn == nil {
  443. return nil, E.New("conn is nil")
  444. }
  445. return NewConn(CN.NewRefConn(conn, w), w), nil
  446. }
  447. func (w *WireGuard) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (_ C.PacketConn, err error) {
  448. options := w.Base.DialOptions(opts...)
  449. w.dialer.SetDialer(dialer.NewDialer(options...))
  450. var pc net.PacketConn
  451. if err = w.init(ctx); err != nil {
  452. return nil, err
  453. }
  454. if (!metadata.Resolved() || w.resolver != nil) && metadata.Host != "" {
  455. r := resolver.DefaultResolver
  456. if w.resolver != nil {
  457. w.refP.SetProxyAdapter(w)
  458. defer w.refP.ClearProxyAdapter()
  459. r = w.resolver
  460. }
  461. ip, err := resolver.ResolveIPWithResolver(ctx, metadata.Host, r)
  462. if err != nil {
  463. return nil, errors.New("can't resolve ip")
  464. }
  465. metadata.DstIP = ip
  466. }
  467. pc, err = w.tunDevice.ListenPacket(ctx, M.SocksaddrFrom(metadata.DstIP, metadata.DstPort).Unwrap())
  468. if err != nil {
  469. return nil, err
  470. }
  471. if pc == nil {
  472. return nil, E.New("packetConn is nil")
  473. }
  474. return newPacketConn(CN.NewRefPacketConn(pc, w), w), nil
  475. }
  476. // IsL3Protocol implements C.ProxyAdapter
  477. func (w *WireGuard) IsL3Protocol(metadata *C.Metadata) bool {
  478. return true
  479. }
  480. type refProxyAdapter struct {
  481. proxyAdapter C.ProxyAdapter
  482. count int
  483. mutex sync.Mutex
  484. }
  485. func (r *refProxyAdapter) SetProxyAdapter(proxyAdapter C.ProxyAdapter) {
  486. r.mutex.Lock()
  487. defer r.mutex.Unlock()
  488. r.proxyAdapter = proxyAdapter
  489. r.count++
  490. }
  491. func (r *refProxyAdapter) ClearProxyAdapter() {
  492. r.mutex.Lock()
  493. defer r.mutex.Unlock()
  494. r.count--
  495. if r.count == 0 {
  496. r.proxyAdapter = nil
  497. }
  498. }
  499. func (r *refProxyAdapter) Name() string {
  500. if r.proxyAdapter != nil {
  501. return r.proxyAdapter.Name()
  502. }
  503. return ""
  504. }
  505. func (r *refProxyAdapter) Type() C.AdapterType {
  506. if r.proxyAdapter != nil {
  507. return r.proxyAdapter.Type()
  508. }
  509. return C.AdapterType(0)
  510. }
  511. func (r *refProxyAdapter) Addr() string {
  512. if r.proxyAdapter != nil {
  513. return r.proxyAdapter.Addr()
  514. }
  515. return ""
  516. }
  517. func (r *refProxyAdapter) SupportUDP() bool {
  518. if r.proxyAdapter != nil {
  519. return r.proxyAdapter.SupportUDP()
  520. }
  521. return false
  522. }
  523. func (r *refProxyAdapter) SupportXUDP() bool {
  524. if r.proxyAdapter != nil {
  525. return r.proxyAdapter.SupportXUDP()
  526. }
  527. return false
  528. }
  529. func (r *refProxyAdapter) SupportTFO() bool {
  530. if r.proxyAdapter != nil {
  531. return r.proxyAdapter.SupportTFO()
  532. }
  533. return false
  534. }
  535. func (r *refProxyAdapter) MarshalJSON() ([]byte, error) {
  536. if r.proxyAdapter != nil {
  537. return r.proxyAdapter.MarshalJSON()
  538. }
  539. return nil, C.ErrNotSupport
  540. }
  541. func (r *refProxyAdapter) StreamConnContext(ctx context.Context, c net.Conn, metadata *C.Metadata) (net.Conn, error) {
  542. if r.proxyAdapter != nil {
  543. return r.proxyAdapter.StreamConnContext(ctx, c, metadata)
  544. }
  545. return nil, C.ErrNotSupport
  546. }
  547. func (r *refProxyAdapter) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) {
  548. if r.proxyAdapter != nil {
  549. return r.proxyAdapter.DialContext(ctx, metadata, opts...)
  550. }
  551. return nil, C.ErrNotSupport
  552. }
  553. func (r *refProxyAdapter) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
  554. if r.proxyAdapter != nil {
  555. return r.proxyAdapter.ListenPacketContext(ctx, metadata, opts...)
  556. }
  557. return nil, C.ErrNotSupport
  558. }
  559. func (r *refProxyAdapter) SupportUOT() bool {
  560. if r.proxyAdapter != nil {
  561. return r.proxyAdapter.SupportUOT()
  562. }
  563. return false
  564. }
  565. func (r *refProxyAdapter) SupportWithDialer() C.NetWork {
  566. if r.proxyAdapter != nil {
  567. return r.proxyAdapter.SupportWithDialer()
  568. }
  569. return C.InvalidNet
  570. }
  571. func (r *refProxyAdapter) DialContextWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (C.Conn, error) {
  572. if r.proxyAdapter != nil {
  573. return r.proxyAdapter.DialContextWithDialer(ctx, dialer, metadata)
  574. }
  575. return nil, C.ErrNotSupport
  576. }
  577. func (r *refProxyAdapter) ListenPacketWithDialer(ctx context.Context, dialer C.Dialer, metadata *C.Metadata) (C.PacketConn, error) {
  578. if r.proxyAdapter != nil {
  579. return r.proxyAdapter.ListenPacketWithDialer(ctx, dialer, metadata)
  580. }
  581. return nil, C.ErrNotSupport
  582. }
  583. func (r *refProxyAdapter) IsL3Protocol(metadata *C.Metadata) bool {
  584. if r.proxyAdapter != nil {
  585. return r.proxyAdapter.IsL3Protocol(metadata)
  586. }
  587. return false
  588. }
  589. func (r *refProxyAdapter) Unwrap(metadata *C.Metadata, touch bool) C.Proxy {
  590. if r.proxyAdapter != nil {
  591. return r.proxyAdapter.Unwrap(metadata, touch)
  592. }
  593. return nil
  594. }
  595. var _ C.ProxyAdapter = (*refProxyAdapter)(nil)