github.com/metacubex/mihomo@v1.18.5/listener/listener.go (about) 1 package listener 2 3 import ( 4 "fmt" 5 "golang.org/x/exp/slices" 6 "net" 7 "sort" 8 "strconv" 9 "strings" 10 "sync" 11 12 "github.com/metacubex/mihomo/component/ebpf" 13 C "github.com/metacubex/mihomo/constant" 14 "github.com/metacubex/mihomo/listener/autoredir" 15 LC "github.com/metacubex/mihomo/listener/config" 16 "github.com/metacubex/mihomo/listener/http" 17 "github.com/metacubex/mihomo/listener/mixed" 18 "github.com/metacubex/mihomo/listener/redir" 19 embedSS "github.com/metacubex/mihomo/listener/shadowsocks" 20 "github.com/metacubex/mihomo/listener/sing_shadowsocks" 21 "github.com/metacubex/mihomo/listener/sing_tun" 22 "github.com/metacubex/mihomo/listener/sing_vmess" 23 "github.com/metacubex/mihomo/listener/socks" 24 "github.com/metacubex/mihomo/listener/tproxy" 25 "github.com/metacubex/mihomo/listener/tuic" 26 LT "github.com/metacubex/mihomo/listener/tunnel" 27 "github.com/metacubex/mihomo/log" 28 29 "github.com/samber/lo" 30 ) 31 32 var ( 33 allowLan = false 34 bindAddress = "*" 35 36 socksListener *socks.Listener 37 socksUDPListener *socks.UDPListener 38 httpListener *http.Listener 39 redirListener *redir.Listener 40 redirUDPListener *tproxy.UDPListener 41 tproxyListener *tproxy.Listener 42 tproxyUDPListener *tproxy.UDPListener 43 mixedListener *mixed.Listener 44 mixedUDPLister *socks.UDPListener 45 tunnelTCPListeners = map[string]*LT.Listener{} 46 tunnelUDPListeners = map[string]*LT.PacketConn{} 47 inboundListeners = map[string]C.InboundListener{} 48 tunLister *sing_tun.Listener 49 shadowSocksListener C.MultiAddrListener 50 vmessListener *sing_vmess.Listener 51 tuicListener *tuic.Listener 52 autoRedirListener *autoredir.Listener 53 autoRedirProgram *ebpf.TcEBpfProgram 54 tcProgram *ebpf.TcEBpfProgram 55 56 // lock for recreate function 57 socksMux sync.Mutex 58 httpMux sync.Mutex 59 redirMux sync.Mutex 60 tproxyMux sync.Mutex 61 mixedMux sync.Mutex 62 tunnelMux sync.Mutex 63 inboundMux sync.Mutex 64 tunMux sync.Mutex 65 ssMux sync.Mutex 66 vmessMux sync.Mutex 67 tuicMux sync.Mutex 68 autoRedirMux sync.Mutex 69 tcMux sync.Mutex 70 71 LastTunConf LC.Tun 72 LastTuicConf LC.TuicServer 73 ) 74 75 type Ports struct { 76 Port int `json:"port"` 77 SocksPort int `json:"socks-port"` 78 RedirPort int `json:"redir-port"` 79 TProxyPort int `json:"tproxy-port"` 80 MixedPort int `json:"mixed-port"` 81 ShadowSocksConfig string `json:"ss-config"` 82 VmessConfig string `json:"vmess-config"` 83 } 84 85 func GetTunConf() LC.Tun { 86 if tunLister == nil { 87 return LastTunConf 88 } 89 return tunLister.Config() 90 } 91 92 func GetTuicConf() LC.TuicServer { 93 if tuicListener == nil { 94 return LC.TuicServer{Enable: false} 95 } 96 return tuicListener.Config() 97 } 98 99 func AllowLan() bool { 100 return allowLan 101 } 102 103 func BindAddress() string { 104 return bindAddress 105 } 106 107 func SetAllowLan(al bool) { 108 allowLan = al 109 } 110 111 func SetBindAddress(host string) { 112 bindAddress = host 113 } 114 115 func ReCreateHTTP(port int, tunnel C.Tunnel) { 116 httpMux.Lock() 117 defer httpMux.Unlock() 118 119 var err error 120 defer func() { 121 if err != nil { 122 log.Errorln("Start HTTP server error: %s", err.Error()) 123 } 124 }() 125 126 addr := genAddr(bindAddress, port, allowLan) 127 128 if httpListener != nil { 129 if httpListener.RawAddress() == addr { 130 return 131 } 132 httpListener.Close() 133 httpListener = nil 134 } 135 136 if portIsZero(addr) { 137 return 138 } 139 140 httpListener, err = http.New(addr, tunnel) 141 if err != nil { 142 log.Errorln("Start HTTP server error: %s", err.Error()) 143 return 144 } 145 146 log.Infoln("HTTP proxy listening at: %s", httpListener.Address()) 147 } 148 149 func ReCreateSocks(port int, tunnel C.Tunnel) { 150 socksMux.Lock() 151 defer socksMux.Unlock() 152 153 var err error 154 defer func() { 155 if err != nil { 156 log.Errorln("Start SOCKS server error: %s", err.Error()) 157 } 158 }() 159 160 addr := genAddr(bindAddress, port, allowLan) 161 162 shouldTCPIgnore := false 163 shouldUDPIgnore := false 164 165 if socksListener != nil { 166 if socksListener.RawAddress() != addr { 167 socksListener.Close() 168 socksListener = nil 169 } else { 170 shouldTCPIgnore = true 171 } 172 } 173 174 if socksUDPListener != nil { 175 if socksUDPListener.RawAddress() != addr { 176 socksUDPListener.Close() 177 socksUDPListener = nil 178 } else { 179 shouldUDPIgnore = true 180 } 181 } 182 183 if shouldTCPIgnore && shouldUDPIgnore { 184 return 185 } 186 187 if portIsZero(addr) { 188 return 189 } 190 191 tcpListener, err := socks.New(addr, tunnel) 192 if err != nil { 193 return 194 } 195 196 udpListener, err := socks.NewUDP(addr, tunnel) 197 if err != nil { 198 tcpListener.Close() 199 return 200 } 201 202 socksListener = tcpListener 203 socksUDPListener = udpListener 204 205 log.Infoln("SOCKS proxy listening at: %s", socksListener.Address()) 206 } 207 208 func ReCreateRedir(port int, tunnel C.Tunnel) { 209 redirMux.Lock() 210 defer redirMux.Unlock() 211 212 var err error 213 defer func() { 214 if err != nil { 215 log.Errorln("Start Redir server error: %s", err.Error()) 216 } 217 }() 218 219 addr := genAddr(bindAddress, port, allowLan) 220 221 if redirListener != nil { 222 if redirListener.RawAddress() == addr { 223 return 224 } 225 redirListener.Close() 226 redirListener = nil 227 } 228 229 if redirUDPListener != nil { 230 if redirUDPListener.RawAddress() == addr { 231 return 232 } 233 redirUDPListener.Close() 234 redirUDPListener = nil 235 } 236 237 if portIsZero(addr) { 238 return 239 } 240 241 redirListener, err = redir.New(addr, tunnel) 242 if err != nil { 243 return 244 } 245 246 redirUDPListener, err = tproxy.NewUDP(addr, tunnel) 247 if err != nil { 248 log.Warnln("Failed to start Redir UDP Listener: %s", err) 249 } 250 251 log.Infoln("Redirect proxy listening at: %s", redirListener.Address()) 252 } 253 254 func ReCreateShadowSocks(shadowSocksConfig string, tunnel C.Tunnel) { 255 ssMux.Lock() 256 defer ssMux.Unlock() 257 258 var err error 259 defer func() { 260 if err != nil { 261 log.Errorln("Start ShadowSocks server error: %s", err.Error()) 262 } 263 }() 264 265 var ssConfig LC.ShadowsocksServer 266 if addr, cipher, password, err := embedSS.ParseSSURL(shadowSocksConfig); err == nil { 267 ssConfig = LC.ShadowsocksServer{ 268 Enable: len(shadowSocksConfig) > 0, 269 Listen: addr, 270 Password: password, 271 Cipher: cipher, 272 Udp: true, 273 } 274 } 275 276 shouldIgnore := false 277 278 if shadowSocksListener != nil { 279 if shadowSocksListener.Config() != ssConfig.String() { 280 shadowSocksListener.Close() 281 shadowSocksListener = nil 282 } else { 283 shouldIgnore = true 284 } 285 } 286 287 if shouldIgnore { 288 return 289 } 290 291 if !ssConfig.Enable { 292 return 293 } 294 295 listener, err := sing_shadowsocks.New(ssConfig, tunnel) 296 if err != nil { 297 return 298 } 299 300 shadowSocksListener = listener 301 302 for _, addr := range shadowSocksListener.AddrList() { 303 log.Infoln("ShadowSocks proxy listening at: %s", addr.String()) 304 } 305 return 306 } 307 308 func ReCreateVmess(vmessConfig string, tunnel C.Tunnel) { 309 vmessMux.Lock() 310 defer vmessMux.Unlock() 311 312 var err error 313 defer func() { 314 if err != nil { 315 log.Errorln("Start Vmess server error: %s", err.Error()) 316 } 317 }() 318 319 var vsConfig LC.VmessServer 320 if addr, username, password, err := sing_vmess.ParseVmessURL(vmessConfig); err == nil { 321 vsConfig = LC.VmessServer{ 322 Enable: len(vmessConfig) > 0, 323 Listen: addr, 324 Users: []LC.VmessUser{{Username: username, UUID: password, AlterID: 1}}, 325 } 326 } 327 328 shouldIgnore := false 329 330 if vmessListener != nil { 331 if vmessListener.Config() != vsConfig.String() { 332 vmessListener.Close() 333 vmessListener = nil 334 } else { 335 shouldIgnore = true 336 } 337 } 338 339 if shouldIgnore { 340 return 341 } 342 343 if !vsConfig.Enable { 344 return 345 } 346 347 listener, err := sing_vmess.New(vsConfig, tunnel) 348 if err != nil { 349 return 350 } 351 352 vmessListener = listener 353 354 for _, addr := range vmessListener.AddrList() { 355 log.Infoln("Vmess proxy listening at: %s", addr.String()) 356 } 357 return 358 } 359 360 func ReCreateTuic(config LC.TuicServer, tunnel C.Tunnel) { 361 tuicMux.Lock() 362 defer func() { 363 LastTuicConf = config 364 tuicMux.Unlock() 365 }() 366 shouldIgnore := false 367 368 var err error 369 defer func() { 370 if err != nil { 371 log.Errorln("Start Tuic server error: %s", err.Error()) 372 } 373 }() 374 375 if tuicListener != nil { 376 if tuicListener.Config().String() != config.String() { 377 tuicListener.Close() 378 tuicListener = nil 379 } else { 380 shouldIgnore = true 381 } 382 } 383 384 if shouldIgnore { 385 return 386 } 387 388 if !config.Enable { 389 return 390 } 391 392 listener, err := tuic.New(config, tunnel) 393 if err != nil { 394 return 395 } 396 397 tuicListener = listener 398 399 for _, addr := range tuicListener.AddrList() { 400 log.Infoln("Tuic proxy listening at: %s", addr.String()) 401 } 402 return 403 } 404 405 func ReCreateTProxy(port int, tunnel C.Tunnel) { 406 tproxyMux.Lock() 407 defer tproxyMux.Unlock() 408 409 var err error 410 defer func() { 411 if err != nil { 412 log.Errorln("Start TProxy server error: %s", err.Error()) 413 } 414 }() 415 416 addr := genAddr(bindAddress, port, allowLan) 417 418 if tproxyListener != nil { 419 if tproxyListener.RawAddress() == addr { 420 return 421 } 422 tproxyListener.Close() 423 tproxyListener = nil 424 } 425 426 if tproxyUDPListener != nil { 427 if tproxyUDPListener.RawAddress() == addr { 428 return 429 } 430 tproxyUDPListener.Close() 431 tproxyUDPListener = nil 432 } 433 434 if portIsZero(addr) { 435 return 436 } 437 438 tproxyListener, err = tproxy.New(addr, tunnel) 439 if err != nil { 440 return 441 } 442 443 tproxyUDPListener, err = tproxy.NewUDP(addr, tunnel) 444 if err != nil { 445 log.Warnln("Failed to start TProxy UDP Listener: %s", err) 446 } 447 448 log.Infoln("TProxy server listening at: %s", tproxyListener.Address()) 449 } 450 451 func ReCreateMixed(port int, tunnel C.Tunnel) { 452 mixedMux.Lock() 453 defer mixedMux.Unlock() 454 455 var err error 456 defer func() { 457 if err != nil { 458 log.Errorln("Start Mixed(http+socks) server error: %s", err.Error()) 459 } 460 }() 461 462 addr := genAddr(bindAddress, port, allowLan) 463 464 shouldTCPIgnore := false 465 shouldUDPIgnore := false 466 467 if mixedListener != nil { 468 if mixedListener.RawAddress() != addr { 469 mixedListener.Close() 470 mixedListener = nil 471 } else { 472 shouldTCPIgnore = true 473 } 474 } 475 if mixedUDPLister != nil { 476 if mixedUDPLister.RawAddress() != addr { 477 mixedUDPLister.Close() 478 mixedUDPLister = nil 479 } else { 480 shouldUDPIgnore = true 481 } 482 } 483 484 if shouldTCPIgnore && shouldUDPIgnore { 485 return 486 } 487 488 if portIsZero(addr) { 489 return 490 } 491 492 mixedListener, err = mixed.New(addr, tunnel) 493 if err != nil { 494 return 495 } 496 497 mixedUDPLister, err = socks.NewUDP(addr, tunnel) 498 if err != nil { 499 mixedListener.Close() 500 return 501 } 502 503 log.Infoln("Mixed(http+socks) proxy listening at: %s", mixedListener.Address()) 504 } 505 506 func ReCreateTun(tunConf LC.Tun, tunnel C.Tunnel) { 507 tunMux.Lock() 508 defer func() { 509 LastTunConf = tunConf 510 tunMux.Unlock() 511 }() 512 513 var err error 514 defer func() { 515 if err != nil { 516 log.Errorln("Start TUN listening error: %s", err.Error()) 517 tunConf.Enable = false 518 } 519 }() 520 521 if !hasTunConfigChange(&tunConf) { 522 if tunLister != nil { 523 tunLister.FlushDefaultInterface() 524 } 525 return 526 } 527 528 closeTunListener() 529 530 if !tunConf.Enable { 531 return 532 } 533 534 lister, err := sing_tun.New(tunConf, tunnel) 535 if err != nil { 536 return 537 } 538 tunLister = lister 539 540 log.Infoln("[TUN] Tun adapter listening at: %s", tunLister.Address()) 541 } 542 543 func ReCreateRedirToTun(ifaceNames []string) { 544 tcMux.Lock() 545 defer tcMux.Unlock() 546 547 nicArr := ifaceNames 548 slices.Sort(nicArr) 549 nicArr = slices.Compact(nicArr) 550 551 if tcProgram != nil { 552 tcProgram.Close() 553 tcProgram = nil 554 } 555 556 if len(nicArr) == 0 { 557 return 558 } 559 560 tunConf := GetTunConf() 561 562 if !tunConf.Enable { 563 return 564 } 565 566 program, err := ebpf.NewTcEBpfProgram(nicArr, tunConf.Device) 567 if err != nil { 568 log.Errorln("Attached tc ebpf program error: %v", err) 569 return 570 } 571 tcProgram = program 572 573 log.Infoln("Attached tc ebpf program to interfaces %v", tcProgram.RawNICs()) 574 } 575 576 func ReCreateAutoRedir(ifaceNames []string, tunnel C.Tunnel) { 577 autoRedirMux.Lock() 578 defer autoRedirMux.Unlock() 579 580 var err error 581 defer func() { 582 if err != nil { 583 if autoRedirListener != nil { 584 _ = autoRedirListener.Close() 585 autoRedirListener = nil 586 } 587 if autoRedirProgram != nil { 588 autoRedirProgram.Close() 589 autoRedirProgram = nil 590 } 591 log.Errorln("Start auto redirect server error: %s", err.Error()) 592 } 593 }() 594 595 nicArr := ifaceNames 596 slices.Sort(nicArr) 597 nicArr = slices.Compact(nicArr) 598 599 if autoRedirListener != nil && autoRedirProgram != nil { 600 _ = autoRedirListener.Close() 601 autoRedirProgram.Close() 602 autoRedirListener = nil 603 autoRedirProgram = nil 604 } 605 606 if len(nicArr) == 0 { 607 return 608 } 609 610 defaultRouteInterfaceName, err := ebpf.GetAutoDetectInterface() 611 if err != nil { 612 return 613 } 614 615 addr := genAddr("*", C.TcpAutoRedirPort, true) 616 617 autoRedirListener, err = autoredir.New(addr, tunnel) 618 if err != nil { 619 return 620 } 621 622 autoRedirProgram, err = ebpf.NewRedirEBpfProgram(nicArr, autoRedirListener.TCPAddr().Port(), defaultRouteInterfaceName) 623 if err != nil { 624 return 625 } 626 627 autoRedirListener.SetLookupFunc(autoRedirProgram.Lookup) 628 629 log.Infoln("Auto redirect proxy listening at: %s, attached tc ebpf program to interfaces %v", autoRedirListener.Address(), autoRedirProgram.RawNICs()) 630 } 631 632 func PatchTunnel(tunnels []LC.Tunnel, tunnel C.Tunnel) { 633 tunnelMux.Lock() 634 defer tunnelMux.Unlock() 635 636 type addrProxy struct { 637 network string 638 addr string 639 target string 640 proxy string 641 } 642 643 tcpOld := lo.Map( 644 lo.Keys(tunnelTCPListeners), 645 func(key string, _ int) addrProxy { 646 parts := strings.Split(key, "/") 647 return addrProxy{ 648 network: "tcp", 649 addr: parts[0], 650 target: parts[1], 651 proxy: parts[2], 652 } 653 }, 654 ) 655 udpOld := lo.Map( 656 lo.Keys(tunnelUDPListeners), 657 func(key string, _ int) addrProxy { 658 parts := strings.Split(key, "/") 659 return addrProxy{ 660 network: "udp", 661 addr: parts[0], 662 target: parts[1], 663 proxy: parts[2], 664 } 665 }, 666 ) 667 oldElm := lo.Union(tcpOld, udpOld) 668 669 newElm := lo.FlatMap( 670 tunnels, 671 func(tunnel LC.Tunnel, _ int) []addrProxy { 672 return lo.Map( 673 tunnel.Network, 674 func(network string, _ int) addrProxy { 675 return addrProxy{ 676 network: network, 677 addr: tunnel.Address, 678 target: tunnel.Target, 679 proxy: tunnel.Proxy, 680 } 681 }, 682 ) 683 }, 684 ) 685 686 needClose, needCreate := lo.Difference(oldElm, newElm) 687 688 for _, elm := range needClose { 689 key := fmt.Sprintf("%s/%s/%s", elm.addr, elm.target, elm.proxy) 690 if elm.network == "tcp" { 691 tunnelTCPListeners[key].Close() 692 delete(tunnelTCPListeners, key) 693 } else { 694 tunnelUDPListeners[key].Close() 695 delete(tunnelUDPListeners, key) 696 } 697 } 698 699 for _, elm := range needCreate { 700 key := fmt.Sprintf("%s/%s/%s", elm.addr, elm.target, elm.proxy) 701 if elm.network == "tcp" { 702 l, err := LT.New(elm.addr, elm.target, elm.proxy, tunnel) 703 if err != nil { 704 log.Errorln("Start tunnel %s error: %s", elm.target, err.Error()) 705 continue 706 } 707 tunnelTCPListeners[key] = l 708 log.Infoln("Tunnel(tcp/%s) proxy %s listening at: %s", elm.target, elm.proxy, tunnelTCPListeners[key].Address()) 709 } else { 710 l, err := LT.NewUDP(elm.addr, elm.target, elm.proxy, tunnel) 711 if err != nil { 712 log.Errorln("Start tunnel %s error: %s", elm.target, err.Error()) 713 continue 714 } 715 tunnelUDPListeners[key] = l 716 log.Infoln("Tunnel(udp/%s) proxy %s listening at: %s", elm.target, elm.proxy, tunnelUDPListeners[key].Address()) 717 } 718 } 719 } 720 721 func PatchInboundListeners(newListenerMap map[string]C.InboundListener, tunnel C.Tunnel, dropOld bool) { 722 inboundMux.Lock() 723 defer inboundMux.Unlock() 724 725 for name, newListener := range newListenerMap { 726 if oldListener, ok := inboundListeners[name]; ok { 727 if !oldListener.Config().Equal(newListener.Config()) { 728 _ = oldListener.Close() 729 } else { 730 continue 731 } 732 } 733 if err := newListener.Listen(tunnel); err != nil { 734 log.Errorln("Listener %s listen err: %s", name, err.Error()) 735 continue 736 } 737 inboundListeners[name] = newListener 738 } 739 740 if dropOld { 741 for name, oldListener := range inboundListeners { 742 if _, ok := newListenerMap[name]; !ok { 743 _ = oldListener.Close() 744 delete(inboundListeners, name) 745 } 746 } 747 } 748 } 749 750 // GetPorts return the ports of proxy servers 751 func GetPorts() *Ports { 752 ports := &Ports{} 753 754 if httpListener != nil { 755 _, portStr, _ := net.SplitHostPort(httpListener.Address()) 756 port, _ := strconv.Atoi(portStr) 757 ports.Port = port 758 } 759 760 if socksListener != nil { 761 _, portStr, _ := net.SplitHostPort(socksListener.Address()) 762 port, _ := strconv.Atoi(portStr) 763 ports.SocksPort = port 764 } 765 766 if redirListener != nil { 767 _, portStr, _ := net.SplitHostPort(redirListener.Address()) 768 port, _ := strconv.Atoi(portStr) 769 ports.RedirPort = port 770 } 771 772 if tproxyListener != nil { 773 _, portStr, _ := net.SplitHostPort(tproxyListener.Address()) 774 port, _ := strconv.Atoi(portStr) 775 ports.TProxyPort = port 776 } 777 778 if mixedListener != nil { 779 _, portStr, _ := net.SplitHostPort(mixedListener.Address()) 780 port, _ := strconv.Atoi(portStr) 781 ports.MixedPort = port 782 } 783 784 if shadowSocksListener != nil { 785 ports.ShadowSocksConfig = shadowSocksListener.Config() 786 } 787 788 if vmessListener != nil { 789 ports.VmessConfig = vmessListener.Config() 790 } 791 792 return ports 793 } 794 795 func portIsZero(addr string) bool { 796 _, port, err := net.SplitHostPort(addr) 797 if port == "0" || port == "" || err != nil { 798 return true 799 } 800 return false 801 } 802 803 func genAddr(host string, port int, allowLan bool) string { 804 if allowLan { 805 if host == "*" { 806 return fmt.Sprintf(":%d", port) 807 } 808 return fmt.Sprintf("%s:%d", host, port) 809 } 810 811 return fmt.Sprintf("127.0.0.1:%d", port) 812 } 813 814 func hasTunConfigChange(tunConf *LC.Tun) bool { 815 if LastTunConf.Enable != tunConf.Enable || 816 LastTunConf.Device != tunConf.Device || 817 LastTunConf.Stack != tunConf.Stack || 818 LastTunConf.AutoRoute != tunConf.AutoRoute || 819 LastTunConf.AutoDetectInterface != tunConf.AutoDetectInterface || 820 LastTunConf.MTU != tunConf.MTU || 821 LastTunConf.GSO != tunConf.GSO || 822 LastTunConf.GSOMaxSize != tunConf.GSOMaxSize || 823 LastTunConf.StrictRoute != tunConf.StrictRoute || 824 LastTunConf.EndpointIndependentNat != tunConf.EndpointIndependentNat || 825 LastTunConf.UDPTimeout != tunConf.UDPTimeout || 826 LastTunConf.FileDescriptor != tunConf.FileDescriptor || 827 LastTunConf.TableIndex != tunConf.TableIndex { 828 return true 829 } 830 831 if len(LastTunConf.DNSHijack) != len(tunConf.DNSHijack) { 832 return true 833 } 834 835 sort.Slice(tunConf.DNSHijack, func(i, j int) bool { 836 return tunConf.DNSHijack[i] < tunConf.DNSHijack[j] 837 }) 838 839 sort.Slice(tunConf.Inet4Address, func(i, j int) bool { 840 return tunConf.Inet4Address[i].String() < tunConf.Inet4Address[j].String() 841 }) 842 843 sort.Slice(tunConf.Inet6Address, func(i, j int) bool { 844 return tunConf.Inet6Address[i].String() < tunConf.Inet6Address[j].String() 845 }) 846 847 sort.Slice(tunConf.Inet4RouteAddress, func(i, j int) bool { 848 return tunConf.Inet4RouteAddress[i].String() < tunConf.Inet4RouteAddress[j].String() 849 }) 850 851 sort.Slice(tunConf.Inet6RouteAddress, func(i, j int) bool { 852 return tunConf.Inet6RouteAddress[i].String() < tunConf.Inet6RouteAddress[j].String() 853 }) 854 855 sort.Slice(tunConf.Inet4RouteExcludeAddress, func(i, j int) bool { 856 return tunConf.Inet4RouteExcludeAddress[i].String() < tunConf.Inet4RouteExcludeAddress[j].String() 857 }) 858 859 sort.Slice(tunConf.Inet6RouteExcludeAddress, func(i, j int) bool { 860 return tunConf.Inet6RouteExcludeAddress[i].String() < tunConf.Inet6RouteExcludeAddress[j].String() 861 }) 862 863 sort.Slice(tunConf.IncludeInterface, func(i, j int) bool { 864 return tunConf.IncludeInterface[i] < tunConf.IncludeInterface[j] 865 }) 866 867 sort.Slice(tunConf.ExcludeInterface, func(i, j int) bool { 868 return tunConf.ExcludeInterface[i] < tunConf.ExcludeInterface[j] 869 }) 870 871 sort.Slice(tunConf.IncludeUID, func(i, j int) bool { 872 return tunConf.IncludeUID[i] < tunConf.IncludeUID[j] 873 }) 874 875 sort.Slice(tunConf.IncludeUIDRange, func(i, j int) bool { 876 return tunConf.IncludeUIDRange[i] < tunConf.IncludeUIDRange[j] 877 }) 878 879 sort.Slice(tunConf.ExcludeUID, func(i, j int) bool { 880 return tunConf.ExcludeUID[i] < tunConf.ExcludeUID[j] 881 }) 882 883 sort.Slice(tunConf.ExcludeUIDRange, func(i, j int) bool { 884 return tunConf.ExcludeUIDRange[i] < tunConf.ExcludeUIDRange[j] 885 }) 886 887 sort.Slice(tunConf.IncludeAndroidUser, func(i, j int) bool { 888 return tunConf.IncludeAndroidUser[i] < tunConf.IncludeAndroidUser[j] 889 }) 890 891 sort.Slice(tunConf.IncludePackage, func(i, j int) bool { 892 return tunConf.IncludePackage[i] < tunConf.IncludePackage[j] 893 }) 894 895 sort.Slice(tunConf.ExcludePackage, func(i, j int) bool { 896 return tunConf.ExcludePackage[i] < tunConf.ExcludePackage[j] 897 }) 898 899 if !slices.Equal(tunConf.DNSHijack, LastTunConf.DNSHijack) || 900 !slices.Equal(tunConf.Inet4Address, LastTunConf.Inet4Address) || 901 !slices.Equal(tunConf.Inet6Address, LastTunConf.Inet6Address) || 902 !slices.Equal(tunConf.Inet4RouteAddress, LastTunConf.Inet4RouteAddress) || 903 !slices.Equal(tunConf.Inet6RouteAddress, LastTunConf.Inet6RouteAddress) || 904 !slices.Equal(tunConf.Inet4RouteExcludeAddress, LastTunConf.Inet4RouteExcludeAddress) || 905 !slices.Equal(tunConf.Inet6RouteExcludeAddress, LastTunConf.Inet6RouteExcludeAddress) || 906 !slices.Equal(tunConf.IncludeInterface, LastTunConf.IncludeInterface) || 907 !slices.Equal(tunConf.ExcludeInterface, LastTunConf.ExcludeInterface) || 908 !slices.Equal(tunConf.IncludeUID, LastTunConf.IncludeUID) || 909 !slices.Equal(tunConf.IncludeUIDRange, LastTunConf.IncludeUIDRange) || 910 !slices.Equal(tunConf.ExcludeUID, LastTunConf.ExcludeUID) || 911 !slices.Equal(tunConf.ExcludeUIDRange, LastTunConf.ExcludeUIDRange) || 912 !slices.Equal(tunConf.IncludeAndroidUser, LastTunConf.IncludeAndroidUser) || 913 !slices.Equal(tunConf.IncludePackage, LastTunConf.IncludePackage) || 914 !slices.Equal(tunConf.ExcludePackage, LastTunConf.ExcludePackage) { 915 return true 916 } 917 918 return false 919 } 920 921 func closeTunListener() { 922 if tunLister != nil { 923 tunLister.Close() 924 tunLister = nil 925 } 926 } 927 928 func Cleanup() { 929 closeTunListener() 930 }