Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package clash for openSUSE:Factory checked 
in at 2022-01-04 19:37:52
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/clash (Old)
 and      /work/SRC/openSUSE:Factory/.clash.new.1896 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "clash"

Tue Jan  4 19:37:52 2022 rev:3 rq:943704 version:1.9.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/clash/clash.changes      2021-12-13 
20:51:15.652668104 +0100
+++ /work/SRC/openSUSE:Factory/.clash.new.1896/clash.changes    2022-01-04 
19:38:11.801985564 +0100
@@ -1,0 +2,20 @@
+Mon Jan 03 14:54:25 UTC 2022 - Orville Q. Song <orvi...@anislet.dev>
+
+- Update to version 1.9.0:
+  * Chore: update dependencies
+  * Fix: multiple port string parsing overflow (#1868)
+  * Chore: remove forward compatible code
+  * Chore: ReCreate* do side effect job (#1849)
+  * Chore: remove reduce regex compile (#1855)
+  * Fix: when both providers and proxies are present, use the health check 
configuration for proxies (#1821)
+  * Chore: builtin right mime of .js (#1808)
+  * Feature: add linux/arm/v6 for the container image (#1771)
+  * Fix: fakeip pool cycle used
+  * Fix: provider filter potential panic
+  * Feature: add filter on proxy provider (#1511)
+  * Fix: should return io.EOF immediately
+  * Change: use nop packet conn for reject
+  * Fix: revert ssr udp fix
+  * Fix: bind iface should throw control error
+
+-------------------------------------------------------------------

Old:
----
  clash-1.8.0.tar.xz

New:
----
  clash-1.9.0.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ clash.spec ++++++
--- /var/tmp/diff_new_pack.cfnbz5/_old  2022-01-04 19:38:12.533986521 +0100
+++ /var/tmp/diff_new_pack.cfnbz5/_new  2022-01-04 19:38:12.533986521 +0100
@@ -1,5 +1,7 @@
+#
 # spec file for package clash
 #
+# Copyright (c) 2022 SUSE LLC
 # Copyright (c) 2019 Xu Zhao (i...@xuzhao.net)
 # Copyright (c) 2021 Orville Q. Song <orvi...@anislet.dev>
 #
@@ -15,7 +17,9 @@
 # Please submit bugfixes or comments via https://bugs.opensuse.org/
 #
 
-%global build_time      %(date -u +'%Y-%m-%dT%H:%M:%SZ')
+
+%global build_time      2022-01-03T14:57:41Z
+# date -u +'%Y-%m-%dT%H:%M:%SZ'
 
 %global provider        github
 %global provider_tld    com
@@ -25,7 +29,7 @@
 %global import_path     %{provider_prefix}/%{repo}
 
 Name:           clash
-Version:        1.8.0
+Version:        1.9.0
 Release:        0
 Summary:        A rule-based tunnel in Go
 License:        GPL-3.0-only

++++++ _service ++++++
--- /var/tmp/diff_new_pack.cfnbz5/_old  2022-01-04 19:38:12.589986595 +0100
+++ /var/tmp/diff_new_pack.cfnbz5/_new  2022-01-04 19:38:12.593986600 +0100
@@ -2,7 +2,7 @@
   <service name="obs_scm" mode="disabled">
     <param name="url">https://github.com/Dreamacro/clash.git</param>
     <param name="scm">git</param>
-    <param name="revision">v1.8.0</param>
+    <param name="revision">v1.9.0</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
     <param name="filename">clash</param>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.cfnbz5/_old  2022-01-04 19:38:12.613986626 +0100
+++ /var/tmp/diff_new_pack.cfnbz5/_new  2022-01-04 19:38:12.617986631 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/Dreamacro/clash.git</param>
-              <param 
name="changesrevision">c9be614821d5c9b4cb3582c2eaebed89341c7f6e</param></service></servicedata>
+              <param 
name="changesrevision">cb95326aca85b89da6182d0f72ee215354f59cc2</param></service></servicedata>
 (No newline at EOF)
 

++++++ clash-1.8.0.tar.xz -> clash-1.9.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/.github/workflows/docker.yml 
new/clash-1.9.0/.github/workflows/docker.yml
--- old/clash-1.8.0/.github/workflows/docker.yml        2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/.github/workflows/docker.yml        2022-01-01 
18:15:49.000000000 +0100
@@ -46,7 +46,7 @@
         uses: docker/build-push-action@v2
         with:
           context: .
-          platforms: linux/amd64,linux/arm/v7,linux/arm64
+          platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64
           push: true
           tags: 'dreamacro/clash:dev,ghcr.io/dreamacro/clash:dev'
 
@@ -71,6 +71,6 @@
         uses: docker/build-push-action@v2
         with:
           context: .
-          platforms: linux/amd64,linux/arm/v7,linux/arm64
+          platforms: linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64
           push: true
           tags: ${{steps.tags.outputs.result}}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/adapter/outbound/reject.go 
new/clash-1.9.0/adapter/outbound/reject.go
--- old/clash-1.8.0/adapter/outbound/reject.go  2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/adapter/outbound/reject.go  2022-01-01 18:15:49.000000000 
+0100
@@ -2,7 +2,6 @@
 
 import (
        "context"
-       "errors"
        "io"
        "net"
        "time"
@@ -17,12 +16,12 @@
 
 // DialContext implements C.ProxyAdapter
 func (r *Reject) DialContext(ctx context.Context, metadata *C.Metadata, opts 
...dialer.Option) (C.Conn, error) {
-       return NewConn(&NopConn{}, r), nil
+       return NewConn(&nopConn{}, r), nil
 }
 
 // ListenPacketContext implements C.ProxyAdapter
 func (r *Reject) ListenPacketContext(ctx context.Context, metadata 
*C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
-       return nil, errors.New("match reject rule")
+       return newPacketConn(&nopPacketConn{}, r), nil
 }
 
 func NewReject() *Reject {
@@ -35,30 +34,29 @@
        }
 }
 
-type NopConn struct{}
+type nopConn struct{}
 
-func (rw *NopConn) Read(b []byte) (int, error) {
+func (rw *nopConn) Read(b []byte) (int, error) {
        return 0, io.EOF
 }
 
-func (rw *NopConn) Write(b []byte) (int, error) {
+func (rw *nopConn) Write(b []byte) (int, error) {
        return 0, io.EOF
 }
 
-// Close is fake function for net.Conn
-func (rw *NopConn) Close() error { return nil }
-
-// LocalAddr is fake function for net.Conn
-func (rw *NopConn) LocalAddr() net.Addr { return nil }
-
-// RemoteAddr is fake function for net.Conn
-func (rw *NopConn) RemoteAddr() net.Addr { return nil }
-
-// SetDeadline is fake function for net.Conn
-func (rw *NopConn) SetDeadline(time.Time) error { return nil }
-
-// SetReadDeadline is fake function for net.Conn
-func (rw *NopConn) SetReadDeadline(time.Time) error { return nil }
-
-// SetWriteDeadline is fake function for net.Conn
-func (rw *NopConn) SetWriteDeadline(time.Time) error { return nil }
+func (rw *nopConn) Close() error                     { return nil }
+func (rw *nopConn) LocalAddr() net.Addr              { return nil }
+func (rw *nopConn) RemoteAddr() net.Addr             { return nil }
+func (rw *nopConn) SetDeadline(time.Time) error      { return nil }
+func (rw *nopConn) SetReadDeadline(time.Time) error  { return nil }
+func (rw *nopConn) SetWriteDeadline(time.Time) error { return nil }
+
+type nopPacketConn struct{}
+
+func (npc *nopPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) 
{ return len(b), nil }
+func (npc *nopPacketConn) ReadFrom(b []byte) (int, net.Addr, error)           
{ return 0, nil, io.EOF }
+func (npc *nopPacketConn) Close() error                                       
{ return nil }
+func (npc *nopPacketConn) LocalAddr() net.Addr                                
{ return &net.UDPAddr{IP: net.IPv4zero, Port: 0} }
+func (npc *nopPacketConn) SetDeadline(time.Time) error                        
{ return nil }
+func (npc *nopPacketConn) SetReadDeadline(time.Time) error                    
{ return nil }
+func (npc *nopPacketConn) SetWriteDeadline(time.Time) error                   
{ return nil }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/adapter/outbound/snell.go 
new/clash-1.9.0/adapter/outbound/snell.go
--- old/clash-1.8.0/adapter/outbound/snell.go   2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/adapter/outbound/snell.go   2022-01-01 18:15:49.000000000 
+0100
@@ -52,7 +52,7 @@
 // StreamConn implements C.ProxyAdapter
 func (s *Snell) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) 
{
        c = streamConn(c, streamOption{s.psk, s.version, s.addr, s.obfsOption})
-       port, _ := strconv.ParseInt(metadata.DstPort, 10, 16)
+       port, _ := strconv.ParseUint(metadata.DstPort, 10, 16)
        err := snell.WriteHeader(c, metadata.String(), uint(port), s.version)
        return c, err
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/adapter/outbound/vmess.go 
new/clash-1.9.0/adapter/outbound/vmess.go
--- old/clash-1.8.0/adapter/outbound/vmess.go   2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/adapter/outbound/vmess.go   2022-01-01 18:15:49.000000000 
+0100
@@ -47,10 +47,6 @@
        HTTP2Opts      HTTP2Options `proxy:"h2-opts,omitempty"`
        GrpcOpts       GrpcOptions  `proxy:"grpc-opts,omitempty"`
        WSOpts         WSOptions    `proxy:"ws-opts,omitempty"`
-
-       // TODO: remove these until 2022
-       WSHeaders map[string]string `proxy:"ws-headers,omitempty"`
-       WSPath    string            `proxy:"ws-path,omitempty"`
 }
 
 type HTTPOptions struct {
@@ -80,13 +76,6 @@
        var err error
        switch v.option.Network {
        case "ws":
-               if v.option.WSOpts.Path == "" {
-                       v.option.WSOpts.Path = v.option.WSPath
-               }
-               if len(v.option.WSOpts.Headers) == 0 {
-                       v.option.WSOpts.Headers = v.option.WSHeaders
-               }
-
                host, port, _ := net.SplitHostPort(v.addr)
                wsOpts := &vmess.WebsocketConfig{
                        Host:                host,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/adapter/outboundgroup/parser.go 
new/clash-1.9.0/adapter/outboundgroup/parser.go
--- old/clash-1.8.0/adapter/outboundgroup/parser.go     2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/adapter/outboundgroup/parser.go     2022-01-01 
18:15:49.000000000 +0100
@@ -59,8 +59,12 @@
                        return nil, err
                }
 
-               // if Use not empty, drop health check options
-               if len(groupOption.Use) != 0 {
+               if _, ok := providersMap[groupName]; ok {
+                       return nil, errDuplicateProvider
+               }
+
+               // select don't need health check
+               if groupOption.Type == "select" || groupOption.Type == "relay" {
                        hc := provider.NewHealthCheck(ps, "", 0, true)
                        pd, err := provider.NewCompatibleProvider(groupName, 
ps, hc)
                        if err != nil {
@@ -68,35 +72,20 @@
                        }
 
                        providers = append(providers, pd)
+                       providersMap[groupName] = pd
                } else {
-                       if _, ok := providersMap[groupName]; ok {
-                               return nil, errDuplicateProvider
+                       if groupOption.URL == "" || groupOption.Interval == 0 {
+                               return nil, errMissHealthCheck
                        }
 
-                       // select don't need health check
-                       if groupOption.Type == "select" || groupOption.Type == 
"relay" {
-                               hc := provider.NewHealthCheck(ps, "", 0, true)
-                               pd, err := 
provider.NewCompatibleProvider(groupName, ps, hc)
-                               if err != nil {
-                                       return nil, err
-                               }
-
-                               providers = append(providers, pd)
-                               providersMap[groupName] = pd
-                       } else {
-                               if groupOption.URL == "" || 
groupOption.Interval == 0 {
-                                       return nil, errMissHealthCheck
-                               }
-
-                               hc := provider.NewHealthCheck(ps, 
groupOption.URL, uint(groupOption.Interval), groupOption.Lazy)
-                               pd, err := 
provider.NewCompatibleProvider(groupName, ps, hc)
-                               if err != nil {
-                                       return nil, err
-                               }
-
-                               providers = append(providers, pd)
-                               providersMap[groupName] = pd
+                       hc := provider.NewHealthCheck(ps, groupOption.URL, 
uint(groupOption.Interval), groupOption.Lazy)
+                       pd, err := provider.NewCompatibleProvider(groupName, 
ps, hc)
+                       if err != nil {
+                               return nil, err
                        }
+
+                       providers = append(providers, pd)
+                       providersMap[groupName] = pd
                }
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/adapter/provider/parser.go 
new/clash-1.9.0/adapter/provider/parser.go
--- old/clash-1.8.0/adapter/provider/parser.go  2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/adapter/provider/parser.go  2022-01-01 18:15:49.000000000 
+0100
@@ -24,6 +24,7 @@
        Path        string            `provider:"path"`
        URL         string            `provider:"url,omitempty"`
        Interval    int               `provider:"interval,omitempty"`
+       Filter      string            `provider:"filter,omitempty"`
        HealthCheck healthCheckSchema `provider:"health-check,omitempty"`
 }
 
@@ -58,5 +59,6 @@
        }
 
        interval := time.Duration(uint(schema.Interval)) * time.Second
-       return NewProxySetProvider(name, interval, vehicle, hc), nil
+       filter := schema.Filter
+       return NewProxySetProvider(name, interval, filter, vehicle, hc)
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/adapter/provider/provider.go 
new/clash-1.9.0/adapter/provider/provider.go
--- old/clash-1.8.0/adapter/provider/provider.go        2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/adapter/provider/provider.go        2022-01-01 
18:15:49.000000000 +0100
@@ -4,6 +4,7 @@
        "encoding/json"
        "errors"
        "fmt"
+       "regexp"
        "runtime"
        "time"
 
@@ -82,33 +83,6 @@
        return pp.Proxies()
 }
 
-func proxiesParse(buf []byte) (interface{}, error) {
-       schema := &ProxySchema{}
-
-       if err := yaml.Unmarshal(buf, schema); err != nil {
-               return nil, err
-       }
-
-       if schema.Proxies == nil {
-               return nil, errors.New("file must have a `proxies` field")
-       }
-
-       proxies := []C.Proxy{}
-       for idx, mapping := range schema.Proxies {
-               proxy, err := adapter.ParseProxy(mapping)
-               if err != nil {
-                       return nil, fmt.Errorf("proxy %d error: %w", idx, err)
-               }
-               proxies = append(proxies, proxy)
-       }
-
-       if len(proxies) == 0 {
-               return nil, errors.New("file doesn't have any valid proxy")
-       }
-
-       return proxies, nil
-}
-
 func (pp *proxySetProvider) setProxies(proxies []C.Proxy) {
        pp.proxies = proxies
        pp.healthCheck.setProxy(proxies)
@@ -122,7 +96,12 @@
        pd.fetcher.Destroy()
 }
 
-func NewProxySetProvider(name string, interval time.Duration, vehicle 
types.Vehicle, hc *HealthCheck) *ProxySetProvider {
+func NewProxySetProvider(name string, interval time.Duration, filter string, 
vehicle types.Vehicle, hc *HealthCheck) (*ProxySetProvider, error) {
+       filterReg, err := regexp.Compile(filter)
+       if err != nil {
+               return nil, fmt.Errorf("invalid filter regex: %w", err)
+       }
+
        if hc.auto() {
                go hc.process()
        }
@@ -137,12 +116,45 @@
                pd.setProxies(ret)
        }
 
-       fetcher := newFetcher(name, interval, vehicle, proxiesParse, onUpdate)
+       proxiesParseAndFilter := func(buf []byte) (interface{}, error) {
+               schema := &ProxySchema{}
+
+               if err := yaml.Unmarshal(buf, schema); err != nil {
+                       return nil, err
+               }
+
+               if schema.Proxies == nil {
+                       return nil, errors.New("file must have a `proxies` 
field")
+               }
+
+               proxies := []C.Proxy{}
+               for idx, mapping := range schema.Proxies {
+                       if name, ok := mapping["name"]; ok && len(filter) > 0 
&& !filterReg.MatchString(name.(string)) {
+                               continue
+                       }
+                       proxy, err := adapter.ParseProxy(mapping)
+                       if err != nil {
+                               return nil, fmt.Errorf("proxy %d error: %w", 
idx, err)
+                       }
+                       proxies = append(proxies, proxy)
+               }
+
+               if len(proxies) == 0 {
+                       if len(filter) > 0 {
+                               return nil, errors.New("doesn't match any 
proxy, please check your filter")
+                       }
+                       return nil, errors.New("file doesn't have any proxy")
+               }
+
+               return proxies, nil
+       }
+
+       fetcher := newFetcher(name, interval, vehicle, proxiesParseAndFilter, 
onUpdate)
        pd.fetcher = fetcher
 
        wrapper := &ProxySetProvider{pd}
        runtime.SetFinalizer(wrapper, stopProxyProvider)
-       return wrapper
+       return wrapper, nil
 }
 
 // for auto gc
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/dialer/bind_darwin.go 
new/clash-1.9.0/component/dialer/bind_darwin.go
--- old/clash-1.8.0/component/dialer/bind_darwin.go     2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/component/dialer/bind_darwin.go     2022-01-01 
18:15:49.000000000 +0100
@@ -27,14 +27,21 @@
                        }
                }
 
-               return c.Control(func(fd uintptr) {
+               var innerErr error
+               err = c.Control(func(fd uintptr) {
                        switch network {
                        case "tcp4", "udp4":
-                               unix.SetsockoptInt(int(fd), unix.IPPROTO_IP, 
unix.IP_BOUND_IF, ifaceIdx)
+                               innerErr = unix.SetsockoptInt(int(fd), 
unix.IPPROTO_IP, unix.IP_BOUND_IF, ifaceIdx)
                        case "tcp6", "udp6":
-                               unix.SetsockoptInt(int(fd), unix.IPPROTO_IPV6, 
unix.IPV6_BOUND_IF, ifaceIdx)
+                               innerErr = unix.SetsockoptInt(int(fd), 
unix.IPPROTO_IPV6, unix.IPV6_BOUND_IF, ifaceIdx)
                        }
                })
+
+               if innerErr != nil {
+                       err = innerErr
+               }
+
+               return
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/dialer/bind_linux.go 
new/clash-1.9.0/component/dialer/bind_linux.go
--- old/clash-1.8.0/component/dialer/bind_linux.go      2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/component/dialer/bind_linux.go      2022-01-01 
18:15:49.000000000 +0100
@@ -25,9 +25,16 @@
                        }
                }
 
-               return c.Control(func(fd uintptr) {
-                       unix.BindToDevice(int(fd), ifaceName)
+               var innerErr error
+               err = c.Control(func(fd uintptr) {
+                       innerErr = unix.BindToDevice(int(fd), ifaceName)
                })
+
+               if innerErr != nil {
+                       err = innerErr
+               }
+
+               return
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/dialer/bind_others.go 
new/clash-1.9.0/component/dialer/bind_others.go
--- old/clash-1.8.0/component/dialer/bind_others.go     2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/component/dialer/bind_others.go     2022-01-01 
18:15:49.000000000 +0100
@@ -58,11 +58,11 @@
                return nil
        }
 
-       local := int64(0)
+       local := uint64(0)
        if dialer.LocalAddr != nil {
                _, port, err := net.SplitHostPort(dialer.LocalAddr.String())
                if err == nil {
-                       local, _ = strconv.ParseInt(port, 10, 16)
+                       local, _ = strconv.ParseUint(port, 10, 16)
                }
        }
 
@@ -82,7 +82,7 @@
                port = "0"
        }
 
-       local, _ := strconv.ParseInt(port, 10, 16)
+       local, _ := strconv.ParseUint(port, 10, 16)
 
        addr, err := lookupLocalAddr(ifaceName, network, nil, int(local))
        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/fakeip/cachefile.go 
new/clash-1.9.0/component/fakeip/cachefile.go
--- old/clash-1.8.0/component/fakeip/cachefile.go       2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/component/fakeip/cachefile.go       2022-01-01 
18:15:49.000000000 +0100
@@ -38,6 +38,12 @@
        c.cache.PutFakeip(ip.To4(), []byte(host))
 }
 
+// DelByIP implements store.DelByIP
+func (c *cachefileStore) DelByIP(ip net.IP) {
+       ip = ip.To4()
+       c.cache.DelFakeipPair(ip, c.cache.GetFakeip(ip.To4()))
+}
+
 // Exist implements store.Exist
 func (c *cachefileStore) Exist(ip net.IP) bool {
        _, exist := c.GetByIP(ip)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/fakeip/memory.go 
new/clash-1.9.0/component/fakeip/memory.go
--- old/clash-1.8.0/component/fakeip/memory.go  2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/component/fakeip/memory.go  2022-01-01 18:15:49.000000000 
+0100
@@ -46,6 +46,15 @@
        m.cache.Set(ipToUint(ip.To4()), host)
 }
 
+// DelByIP implements store.DelByIP
+func (m *memoryStore) DelByIP(ip net.IP) {
+       ipNum := ipToUint(ip.To4())
+       if elm, exist := m.cache.Get(ipNum); exist {
+               m.cache.Delete(elm.(string))
+       }
+       m.cache.Delete(ipNum)
+}
+
 // Exist implements store.Exist
 func (m *memoryStore) Exist(ip net.IP) bool {
        return m.cache.Exist(ipToUint(ip.To4()))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/fakeip/pool.go 
new/clash-1.9.0/component/fakeip/pool.go
--- old/clash-1.8.0/component/fakeip/pool.go    2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/component/fakeip/pool.go    2022-01-01 18:15:49.000000000 
+0100
@@ -15,6 +15,7 @@
        PutByHost(host string, ip net.IP)
        GetByIP(ip net.IP) (string, bool)
        PutByIP(ip net.IP, host string)
+       DelByIP(ip net.IP)
        Exist(ip net.IP) bool
        CloneTo(store)
 }
@@ -97,6 +98,9 @@
                p.offset = (p.offset + 1) % (p.max - p.min)
                // Avoid infinite loops
                if p.offset == current {
+                       p.offset = (p.offset + 1) % (p.max - p.min)
+                       ip := uintToIP(p.min + p.offset - 1)
+                       p.store.DelByIP(ip)
                        break
                }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/fakeip/pool_test.go 
new/clash-1.9.0/component/fakeip/pool_test.go
--- old/clash-1.8.0/component/fakeip/pool_test.go       2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/component/fakeip/pool_test.go       2022-01-01 
18:15:49.000000000 +0100
@@ -1,6 +1,7 @@
 package fakeip
 
 import (
+       "fmt"
        "net"
        "os"
        "testing"
@@ -75,7 +76,7 @@
 }
 
 func TestPool_CycleUsed(t *testing.T) {
-       _, ipnet, _ := net.ParseCIDR("192.168.0.1/30")
+       _, ipnet, _ := net.ParseCIDR("192.168.0.1/29")
        pools, tempfile, err := createPools(Options{
                IPNet: ipnet,
                Size:  10,
@@ -84,9 +85,15 @@
        defer os.Remove(tempfile)
 
        for _, pool := range pools {
-               first := pool.Lookup("foo.com")
-               same := pool.Lookup("baz.com")
-               assert.True(t, first.Equal(same))
+               foo := pool.Lookup("foo.com")
+               bar := pool.Lookup("bar.com")
+               for i := 0; i < 3; i++ {
+                       pool.Lookup(fmt.Sprintf("%d.com", i))
+               }
+               baz := pool.Lookup("baz.com")
+               next := pool.Lookup("foo.com")
+               assert.True(t, foo.Equal(baz))
+               assert.True(t, next.Equal(bar))
        }
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/component/profile/cachefile/cache.go 
new/clash-1.9.0/component/profile/cachefile/cache.go
--- old/clash-1.8.0/component/profile/cachefile/cache.go        2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/component/profile/cachefile/cache.go        2022-01-01 
18:15:49.000000000 +0100
@@ -1,8 +1,6 @@
 package cachefile
 
 import (
-       "bytes"
-       "encoding/gob"
        "os"
        "sync"
        "time"
@@ -90,6 +88,31 @@
        return err
 }
 
+func (c *CacheFile) DelFakeipPair(ip, host []byte) error {
+       if c.DB == nil {
+               return nil
+       }
+
+       err := c.DB.Batch(func(t *bbolt.Tx) error {
+               bucket, err := t.CreateBucketIfNotExists(bucketFakeip)
+               if err != nil {
+                       return err
+               }
+               err = bucket.Delete(ip)
+               if len(host) > 0 {
+                       if err := bucket.Delete(host); err != nil {
+                               return err
+                       }
+               }
+               return err
+       })
+       if err != nil {
+               log.Warnln("[CacheFile] write cache to %s failed: %s", 
c.DB.Path(), err.Error())
+       }
+
+       return err
+}
+
 func (c *CacheFile) GetFakeip(key []byte) []byte {
        if c.DB == nil {
                return nil
@@ -113,69 +136,30 @@
        return c.DB.Close()
 }
 
-// TODO: remove migrateCache until 2022
-func migrateCache() {
-       defer func() {
-               options := bbolt.Options{Timeout: time.Second}
-               db, err := bbolt.Open(C.Path.Cache(), fileMode, &options)
-               switch err {
-               case bbolt.ErrInvalid, bbolt.ErrChecksum, 
bbolt.ErrVersionMismatch:
-                       if err = os.Remove(C.Path.Cache()); err != nil {
-                               log.Warnln("[CacheFile] remove invalid cache 
file error: %s", err.Error())
-                               break
-                       }
-                       log.Infoln("[CacheFile] remove invalid cache file and 
create new one")
-                       db, err = bbolt.Open(C.Path.Cache(), fileMode, &options)
+func initCache() {
+       options := bbolt.Options{Timeout: time.Second}
+       db, err := bbolt.Open(C.Path.Cache(), fileMode, &options)
+       switch err {
+       case bbolt.ErrInvalid, bbolt.ErrChecksum, bbolt.ErrVersionMismatch:
+               if err = os.Remove(C.Path.Cache()); err != nil {
+                       log.Warnln("[CacheFile] remove invalid cache file 
error: %s", err.Error())
+                       break
                }
-               if err != nil {
-                       log.Warnln("[CacheFile] can't open cache file: %s", 
err.Error())
-               }
-
-               defaultCache = &CacheFile{
-                       DB: db,
-               }
-       }()
-
-       buf, err := os.ReadFile(C.Path.OldCache())
-       if err != nil {
-               return
+               log.Infoln("[CacheFile] remove invalid cache file and create 
new one")
+               db, err = bbolt.Open(C.Path.Cache(), fileMode, &options)
        }
-       defer os.Remove(C.Path.OldCache())
-
-       // read old cache file
-       type cache struct {
-               Selected map[string]string
-       }
-       model := &cache{
-               Selected: map[string]string{},
-       }
-       bufReader := bytes.NewBuffer(buf)
-       gob.NewDecoder(bufReader).Decode(model)
-
-       // write to new cache file
-       db, err := bbolt.Open(C.Path.Cache(), fileMode, nil)
        if err != nil {
-               return
+               log.Warnln("[CacheFile] can't open cache file: %s", err.Error())
        }
-       defer db.Close()
 
-       db.Batch(func(t *bbolt.Tx) error {
-               bucket, err := t.CreateBucketIfNotExists(bucketSelected)
-               if err != nil {
-                       return err
-               }
-               for group, selected := range model.Selected {
-                       if err := bucket.Put([]byte(group), []byte(selected)); 
err != nil {
-                               return err
-                       }
-               }
-               return nil
-       })
+       defaultCache = &CacheFile{
+               DB: db,
+       }
 }
 
 // Cache return singleton of CacheFile
 func Cache() *CacheFile {
-       initOnce.Do(migrateCache)
+       initOnce.Do(initCache)
 
        return defaultCache
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/constant/adapters.go 
new/clash-1.9.0/constant/adapters.go
--- old/clash-1.8.0/constant/adapters.go        2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/constant/adapters.go        2022-01-01 18:15:49.000000000 
+0100
@@ -93,7 +93,6 @@
        // DialContext return a C.Conn with protocol which
        // contains multiplexing-related reuse logic (if any)
        DialContext(ctx context.Context, metadata *Metadata, opts 
...dialer.Option) (Conn, error)
-
        ListenPacketContext(ctx context.Context, metadata *Metadata, opts 
...dialer.Option) (PacketConn, error)
 
        // Unwrap extracts the proxy from a proxy-group. It returns nil when 
nothing to extract.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/constant/metadata.go 
new/clash-1.9.0/constant/metadata.go
--- old/clash-1.8.0/constant/metadata.go        2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/constant/metadata.go        2022-01-01 18:15:49.000000000 
+0100
@@ -107,7 +107,7 @@
        if m.NetWork != UDP || m.DstIP == nil {
                return nil
        }
-       port, _ := strconv.ParseInt(m.DstPort, 10, 16)
+       port, _ := strconv.ParseUint(m.DstPort, 10, 16)
        return &net.UDPAddr{
                IP:   m.DstIP,
                Port: int(port),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/constant/mime/mime.go 
new/clash-1.9.0/constant/mime/mime.go
--- old/clash-1.8.0/constant/mime/mime.go       1970-01-01 01:00:00.000000000 
+0100
+++ new/clash-1.9.0/constant/mime/mime.go       2022-01-01 18:15:49.000000000 
+0100
@@ -0,0 +1,16 @@
+package mime
+
+import (
+       "mime"
+)
+
+var consensusMimes = map[string]string{
+       // rfc4329: text/javascript is obsolete, so we need to overwrite mime's 
builtin
+       ".js": "application/javascript; charset=utf-8",
+}
+
+func init() {
+       for ext, typ := range consensusMimes {
+               mime.AddExtensionType(ext, typ)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/dns/server.go 
new/clash-1.9.0/dns/server.go
--- old/clash-1.8.0/dns/server.go       2021-11-08 14:24:39.000000000 +0100
+++ new/clash-1.9.0/dns/server.go       2022-01-01 18:15:49.000000000 +0100
@@ -47,11 +47,11 @@
        s.handler = handler
 }
 
-func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) 
error {
+func ReCreateServer(addr string, resolver *Resolver, mapper *ResolverEnhancer) 
{
        if addr == address && resolver != nil {
                handler := newHandler(resolver, mapper)
                server.setHandler(handler)
-               return nil
+               return
        }
 
        if server.Server != nil {
@@ -60,24 +60,33 @@
                address = ""
        }
 
+       var err error
+       defer func() {
+               if err != nil {
+                       log.Errorln("Start DNS server error: %s", err.Error())
+               }
+       }()
+
        _, port, err := net.SplitHostPort(addr)
        if port == "0" || port == "" || err != nil {
-               return nil
+               return
        }
 
        udpAddr, err := net.ResolveUDPAddr("udp", addr)
        if err != nil {
-               return err
+               return
        }
 
        p, err := net.ListenUDP("udp", udpAddr)
        if err != nil {
-               return err
+               return
        }
 
        err = sockopt.UDPReuseaddr(p)
        if err != nil {
                log.Warnln("Failed to Reuse UDP Address: %s", err)
+
+               err = nil
        }
 
        address = addr
@@ -88,5 +97,6 @@
        go func() {
                server.ActivateAndServe()
        }()
-       return nil
+
+       log.Infoln("DNS server listening at: %s", p.LocalAddr().String())
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/go.mod new/clash-1.9.0/go.mod
--- old/clash-1.8.0/go.mod      2021-11-08 14:24:39.000000000 +0100
+++ new/clash-1.9.0/go.mod      2022-01-01 18:15:49.000000000 +0100
@@ -4,23 +4,23 @@
 
 require (
        github.com/Dreamacro/go-shadowsocks2 v0.1.7
-       github.com/go-chi/chi/v5 v5.0.5
+       github.com/go-chi/chi/v5 v5.0.7
        github.com/go-chi/cors v1.2.0
        github.com/go-chi/render v1.0.1
-       github.com/gofrs/uuid v4.1.0+incompatible
+       github.com/gofrs/uuid v4.2.0+incompatible
        github.com/gorilla/websocket v1.4.2
-       github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd
-       github.com/miekg/dns v1.1.43
+       github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489
+       github.com/miekg/dns v1.1.45
        github.com/oschwald/geoip2-golang v1.5.0
        github.com/sirupsen/logrus v1.8.1
        github.com/stretchr/testify v1.7.0
        go.etcd.io/bbolt v1.3.6
        go.uber.org/atomic v1.9.0
        go.uber.org/automaxprocs v1.4.0
-       golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
-       golang.org/x/net v0.0.0-20211105192438-b53810dc28af
+       golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
+       golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
        golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
-       golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42
+       golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e
        gopkg.in/yaml.v2 v2.4.0
 )
 
@@ -29,6 +29,9 @@
        github.com/oschwald/maxminddb-golang v1.8.0 // indirect
        github.com/pmezard/go-difflib v1.0.0 // indirect
        github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
+       golang.org/x/mod v0.4.2 // indirect
        golang.org/x/text v0.3.6 // indirect
+       golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
+       golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
        gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
 )
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/go.sum new/clash-1.9.0/go.sum
--- old/clash-1.8.0/go.sum      2021-11-08 14:24:39.000000000 +0100
+++ new/clash-1.9.0/go.sum      2022-01-01 18:15:49.000000000 +0100
@@ -4,14 +4,14 @@
 github.com/davecgh/go-spew v1.1.1 
h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod 
h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod 
h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc=
-github.com/go-chi/chi/v5 v5.0.5 h1:l3RJ8T8TAqLsXFfah+RA6N4pydMbPwSdvNM+AFWvLUM=
-github.com/go-chi/chi/v5 v5.0.5/go.mod 
h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/chi/v5 v5.0.7 h1:rDTPXLDHGATaeHvVlLcR4Qe0zftYethFucbjVQ1PxU8=
+github.com/go-chi/chi/v5 v5.0.7/go.mod 
h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 github.com/go-chi/cors v1.2.0 h1:tV1g1XENQ8ku4Bq3K9ub2AtgG+p16SmzeMSGTwrOKdE=
 github.com/go-chi/cors v1.2.0/go.mod 
h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
 github.com/go-chi/render v1.0.1 h1:4/5tis2cKaNdnv9zFLfXzcquC9HbeZgCnxGnKrltBS8=
 github.com/go-chi/render v1.0.1/go.mod 
h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
-github.com/gofrs/uuid v4.1.0+incompatible 
h1:sIa2eCvUTwgjbqXrPLfNwUf9S3i3mpH1O1atV+iL/Wk=
-github.com/gofrs/uuid v4.1.0+incompatible/go.mod 
h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.2.0+incompatible 
h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
+github.com/gofrs/uuid v4.2.0+incompatible/go.mod 
h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/google/go-cmp v0.2.0/go.mod 
h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod 
h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
 github.com/google/go-cmp v0.3.1/go.mod 
h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -21,8 +21,8 @@
 github.com/gorilla/websocket v1.4.2 
h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
 github.com/gorilla/websocket v1.4.2/go.mod 
h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod 
h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
-github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd 
h1:jupbuQFZtwOBg/3EmK91/rGaYFkqCb9bwHOnwn7Cav0=
-github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd/go.mod 
h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
+github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 
h1:jhdHqd7DxBrzfuFSoPxjD6nUVaV/1RIn9aHA0WCf/as=
+github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489/go.mod 
h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
 github.com/jsimonetti/rtnetlink v0.0.0-20190606172950-9527aa82566a/go.mod 
h1:Oz+70psSo5OFh8DBl0Zv2ACw7Esh6pPUphlvZG9x7uw=
 github.com/jsimonetti/rtnetlink v0.0.0-20200117123717-f846d4f6c1f4/go.mod 
h1:WGuG/smIU4J/54PblvSbh+xvCZmpJnFgr3ds6Z55XMQ=
 github.com/jsimonetti/rtnetlink v0.0.0-20201009170750-9c6f07d100c1/go.mod 
h1:hqoO/u39cqLeBLebZ8fWdE96O7FxrAsRYhnVOdgHxok=
@@ -40,8 +40,8 @@
 github.com/mdlayher/netlink v1.1.1/go.mod 
h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
 github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod 
h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
 github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod 
h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
-github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
-github.com/miekg/dns v1.1.43/go.mod 
h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
+github.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk=
+github.com/miekg/dns v1.1.45/go.mod 
h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
 github.com/oschwald/geoip2-golang v1.5.0 
h1:igg2yQIrrcRccB1ytFXqBfOHCjXWIoMv85lVJ1ONZzw=
 github.com/oschwald/geoip2-golang v1.5.0/go.mod 
h1:xdvYt5xQzB8ORWFqPnqMwZpCpgNagttWdoZLlJQzg7s=
 github.com/oschwald/maxminddb-golang v1.8.0 
h1:Uh/DSnGoxsyp/KYbY1AuP0tYEwfs0sCph9p/UMXK/Hk=
@@ -61,6 +61,7 @@
 github.com/stretchr/testify v1.7.0/go.mod 
h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/u-root/uio v0.0.0-20210528114334-82958018845c 
h1:BFvcl34IGnw8yvJi8hlqLFo9EshRInwWBs2M5fGWzQA=
 github.com/u-root/uio v0.0.0-20210528114334-82958018845c/go.mod 
h1:LpEX5FO/cB+WF4TYGY1V5qktpaZLkKkSegbr0V4eYXA=
+github.com/yuin/goldmark v1.3.5/go.mod 
h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU=
 go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4=
 go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE=
@@ -68,22 +69,30 @@
 go.uber.org/automaxprocs v1.4.0 h1:CpDZl6aOlLhReez+8S3eEotD7Jx0Os++lemPlMULQP0=
 go.uber.org/automaxprocs v1.4.0/go.mod 
h1:/mTEdr7LvHhs0v7mjdxDreTz1OG5zdZGqgOnhWiR/+Q=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod 
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod 
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod 
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod 
h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 
h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 
h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
+golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod 
h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod 
h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod 
h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190419010253-1f3472d942ba/go.mod 
h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod 
h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191007182048-72f939374954/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod 
h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod 
h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20211105192438-b53810dc28af 
h1:SMeNJG/vclJ5wyBBd4xupMsSJIHTd1coW9g7q6KOjmY=
-golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod 
h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211216030914-fe4d6282115f 
h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
+golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c 
h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod 
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -102,12 +111,14 @@
 golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201101102859-da207088b7d1/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 
h1:G2DDmludOQZoWbpCr7OKDxnl478ZBGMcOhrv+ooX/Q4=
-golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e 
h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@@ -115,7 +126,14 @@
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod 
h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 
h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
+golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod 
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 
h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 
h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod 
h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/hub/executor/executor.go 
new/clash-1.9.0/hub/executor/executor.go
--- old/clash-1.8.0/hub/executor/executor.go    2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/hub/executor/executor.go    2022-01-01 18:15:49.000000000 
+0100
@@ -141,14 +141,7 @@
        resolver.DefaultResolver = r
        resolver.DefaultHostMapper = m
 
-       if err := dns.ReCreateServer(c.Listen, r, m); err != nil {
-               log.Errorln("Start DNS server error: %s", err.Error())
-               return
-       }
-
-       if c.Listen != "" {
-               log.Infoln("DNS server listening at: %s", c.Listen)
-       }
+       dns.ReCreateServer(c.Listen, r, m)
 }
 
 func updateHosts(tree *trie.DomainTrie) {
@@ -185,25 +178,11 @@
        tcpIn := tunnel.TCPIn()
        udpIn := tunnel.UDPIn()
 
-       if err := P.ReCreateHTTP(general.Port, tcpIn); err != nil {
-               log.Errorln("Start HTTP server error: %s", err.Error())
-       }
-
-       if err := P.ReCreateSocks(general.SocksPort, tcpIn, udpIn); err != nil {
-               log.Errorln("Start SOCKS server error: %s", err.Error())
-       }
-
-       if err := P.ReCreateRedir(general.RedirPort, tcpIn, udpIn); err != nil {
-               log.Errorln("Start Redir server error: %s", err.Error())
-       }
-
-       if err := P.ReCreateTProxy(general.TProxyPort, tcpIn, udpIn); err != 
nil {
-               log.Errorln("Start TProxy server error: %s", err.Error())
-       }
-
-       if err := P.ReCreateMixed(general.MixedPort, tcpIn, udpIn); err != nil {
-               log.Errorln("Start Mixed(http and socks) server error: %s", 
err.Error())
-       }
+       P.ReCreateHTTP(general.Port, tcpIn)
+       P.ReCreateSocks(general.SocksPort, tcpIn, udpIn)
+       P.ReCreateRedir(general.RedirPort, tcpIn, udpIn)
+       P.ReCreateTProxy(general.TProxyPort, tcpIn, udpIn)
+       P.ReCreateMixed(general.MixedPort, tcpIn, udpIn)
 }
 
 func updateUsers(users []auth.AuthUser) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/hub/route/server.go 
new/clash-1.9.0/hub/route/server.go
--- old/clash-1.8.0/hub/route/server.go 2021-11-08 14:24:39.000000000 +0100
+++ new/clash-1.9.0/hub/route/server.go 2022-01-01 18:15:49.000000000 +0100
@@ -9,6 +9,7 @@
        "time"
 
        C "github.com/Dreamacro/clash/constant"
+       _ "github.com/Dreamacro/clash/constant/mime"
        "github.com/Dreamacro/clash/log"
        "github.com/Dreamacro/clash/tunnel/statistic"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/listener/listener.go 
new/clash-1.9.0/listener/listener.go
--- old/clash-1.8.0/listener/listener.go        2021-11-08 14:24:39.000000000 
+0100
+++ new/clash-1.9.0/listener/listener.go        2022-01-01 18:15:49.000000000 
+0100
@@ -62,38 +62,50 @@
        bindAddress = host
 }
 
-func ReCreateHTTP(port int, tcpIn chan<- C.ConnContext) error {
+func ReCreateHTTP(port int, tcpIn chan<- C.ConnContext) {
        httpMux.Lock()
        defer httpMux.Unlock()
 
+       var err error
+       defer func() {
+               if err != nil {
+                       log.Errorln("Start HTTP server error: %s", err.Error())
+               }
+       }()
+
        addr := genAddr(bindAddress, port, allowLan)
 
        if httpListener != nil {
                if httpListener.RawAddress() == addr {
-                       return nil
+                       return
                }
                httpListener.Close()
                httpListener = nil
        }
 
        if portIsZero(addr) {
-               return nil
+               return
        }
 
-       var err error
        httpListener, err = http.New(addr, tcpIn)
        if err != nil {
-               return err
+               return
        }
 
        log.Infoln("HTTP proxy listening at: %s", httpListener.Address())
-       return nil
 }
 
-func ReCreateSocks(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) error {
+func ReCreateSocks(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) {
        socksMux.Lock()
        defer socksMux.Unlock()
 
+       var err error
+       defer func() {
+               if err != nil {
+                       log.Errorln("Start SOCKS server error: %s", err.Error())
+               }
+       }()
+
        addr := genAddr(bindAddress, port, allowLan)
 
        shouldTCPIgnore := false
@@ -118,40 +130,46 @@
        }
 
        if shouldTCPIgnore && shouldUDPIgnore {
-               return nil
+               return
        }
 
        if portIsZero(addr) {
-               return nil
+               return
        }
 
        tcpListener, err := socks.New(addr, tcpIn)
        if err != nil {
-               return err
+               return
        }
 
        udpListener, err := socks.NewUDP(addr, udpIn)
        if err != nil {
                tcpListener.Close()
-               return err
+               return
        }
 
        socksListener = tcpListener
        socksUDPListener = udpListener
 
        log.Infoln("SOCKS proxy listening at: %s", socksListener.Address())
-       return nil
 }
 
-func ReCreateRedir(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) error {
+func ReCreateRedir(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) {
        redirMux.Lock()
        defer redirMux.Unlock()
 
+       var err error
+       defer func() {
+               if err != nil {
+                       log.Errorln("Start Redir server error: %s", err.Error())
+               }
+       }()
+
        addr := genAddr(bindAddress, port, allowLan)
 
        if redirListener != nil {
                if redirListener.RawAddress() == addr {
-                       return nil
+                       return
                }
                redirListener.Close()
                redirListener = nil
@@ -159,20 +177,19 @@
 
        if redirUDPListener != nil {
                if redirUDPListener.RawAddress() == addr {
-                       return nil
+                       return
                }
                redirUDPListener.Close()
                redirUDPListener = nil
        }
 
        if portIsZero(addr) {
-               return nil
+               return
        }
 
-       var err error
        redirListener, err = redir.New(addr, tcpIn)
        if err != nil {
-               return err
+               return
        }
 
        redirUDPListener, err = tproxy.NewUDP(addr, udpIn)
@@ -181,18 +198,24 @@
        }
 
        log.Infoln("Redirect proxy listening at: %s", redirListener.Address())
-       return nil
 }
 
-func ReCreateTProxy(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) error {
+func ReCreateTProxy(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) {
        tproxyMux.Lock()
        defer tproxyMux.Unlock()
 
+       var err error
+       defer func() {
+               if err != nil {
+                       log.Errorln("Start TProxy server error: %s", 
err.Error())
+               }
+       }()
+
        addr := genAddr(bindAddress, port, allowLan)
 
        if tproxyListener != nil {
                if tproxyListener.RawAddress() == addr {
-                       return nil
+                       return
                }
                tproxyListener.Close()
                tproxyListener = nil
@@ -200,20 +223,19 @@
 
        if tproxyUDPListener != nil {
                if tproxyUDPListener.RawAddress() == addr {
-                       return nil
+                       return
                }
                tproxyUDPListener.Close()
                tproxyUDPListener = nil
        }
 
        if portIsZero(addr) {
-               return nil
+               return
        }
 
-       var err error
        tproxyListener, err = tproxy.New(addr, tcpIn)
        if err != nil {
-               return err
+               return
        }
 
        tproxyUDPListener, err = tproxy.NewUDP(addr, udpIn)
@@ -222,13 +244,19 @@
        }
 
        log.Infoln("TProxy server listening at: %s", tproxyListener.Address())
-       return nil
 }
 
-func ReCreateMixed(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) error {
+func ReCreateMixed(port int, tcpIn chan<- C.ConnContext, udpIn chan<- 
*inbound.PacketAdapter) {
        mixedMux.Lock()
        defer mixedMux.Unlock()
 
+       var err error
+       defer func() {
+               if err != nil {
+                       log.Errorln("Start Mixed(http+socks) server error: %s", 
err.Error())
+               }
+       }()
+
        addr := genAddr(bindAddress, port, allowLan)
 
        shouldTCPIgnore := false
@@ -252,27 +280,25 @@
        }
 
        if shouldTCPIgnore && shouldUDPIgnore {
-               return nil
+               return
        }
 
        if portIsZero(addr) {
-               return nil
+               return
        }
 
-       var err error
        mixedListener, err = mixed.New(addr, tcpIn)
        if err != nil {
-               return err
+               return
        }
 
        mixedUDPLister, err = socks.NewUDP(addr, udpIn)
        if err != nil {
                mixedListener.Close()
-               return err
+               return
        }
 
        log.Infoln("Mixed(http+socks) proxy listening at: %s", 
mixedListener.Address())
-       return nil
 }
 
 // GetPorts return the ports of proxy servers
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/test/go.mod new/clash-1.9.0/test/go.mod
--- old/clash-1.8.0/test/go.mod 2021-11-08 14:24:39.000000000 +0100
+++ new/clash-1.9.0/test/go.mod 2022-01-01 18:15:49.000000000 +0100
@@ -4,11 +4,11 @@
 
 require (
        github.com/Dreamacro/clash v1.7.2-0.20211108085948-bd2ea2b917aa
-       github.com/docker/docker v20.10.10+incompatible
+       github.com/docker/docker v20.10.12+incompatible
        github.com/docker/go-connections v0.4.0
-       github.com/miekg/dns v1.1.43
+       github.com/miekg/dns v1.1.45
        github.com/stretchr/testify v1.7.0
-       golang.org/x/net v0.0.0-20211105192438-b53810dc28af
+       golang.org/x/net v0.0.0-20211216030914-fe4d6282115f
 )
 
 replace github.com/Dreamacro/clash => ../
@@ -20,12 +20,12 @@
        github.com/davecgh/go-spew v1.1.1 // indirect
        github.com/docker/distribution v2.7.1+incompatible // indirect
        github.com/docker/go-units v0.4.0 // indirect
-       github.com/gofrs/uuid v4.1.0+incompatible // indirect
+       github.com/gofrs/uuid v4.2.0+incompatible // indirect
        github.com/gogo/protobuf v1.3.2 // indirect
        github.com/golang/protobuf v1.5.0 // indirect
        github.com/gorilla/mux v1.8.0 // indirect
        github.com/gorilla/websocket v1.4.2 // indirect
-       github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd // 
indirect
+       github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 // 
indirect
        github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6 // indirect
        github.com/morikuni/aec v1.0.0 // indirect
        github.com/opencontainers/go-digest v1.0.0 // indirect
@@ -38,11 +38,14 @@
        github.com/u-root/uio v0.0.0-20210528114334-82958018845c // indirect
        go.etcd.io/bbolt v1.3.6 // indirect
        go.uber.org/atomic v1.9.0 // indirect
-       golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
+       golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 // indirect
+       golang.org/x/mod v0.4.2 // indirect
        golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
-       golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 // indirect
+       golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
        golang.org/x/text v0.3.6 // indirect
        golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
+       golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 // indirect
+       golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
        google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a // 
indirect
        google.golang.org/grpc v1.42.0 // indirect
        google.golang.org/protobuf v1.26.0 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/clash-1.8.0/test/go.sum new/clash-1.9.0/test/go.sum
--- old/clash-1.8.0/test/go.sum 2021-11-08 14:24:39.000000000 +0100
+++ new/clash-1.9.0/test/go.sum 2022-01-01 18:15:49.000000000 +0100
@@ -229,8 +229,8 @@
 github.com/docker/distribution 
v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod 
h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/distribution v2.7.1+incompatible 
h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
 github.com/docker/distribution v2.7.1+incompatible/go.mod 
h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v20.10.10+incompatible 
h1:GKkP0T7U4ks6X3lmmHKC2QDprnpRJor2Z5a8m62R9ZM=
-github.com/docker/docker v20.10.10+incompatible/go.mod 
h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker v20.10.12+incompatible 
h1:CEeNmFM0QZIsJCZKMkZx0ZcahTiewkrgiwfYD+dfl1U=
+github.com/docker/docker v20.10.12+incompatible/go.mod 
h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/go-connections v0.4.0 
h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
 github.com/docker/go-connections v0.4.0/go.mod 
h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod 
h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
@@ -264,7 +264,7 @@
 github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod 
h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod 
h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/ghodss/yaml v1.0.0/go.mod 
h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-chi/chi/v5 v5.0.5/go.mod 
h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/go-chi/chi/v5 v5.0.7/go.mod 
h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
 github.com/go-chi/cors v1.2.0/go.mod 
h1:sSbTewc+6wYHBBCW7ytsFSn836hqM7JxpglAy2Vzc58=
 github.com/go-chi/render v1.0.1/go.mod 
h1:pq4Rr7HbnsdaeHagklXub+p6Wd16Af5l9koip1OvJns=
 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod 
h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
@@ -290,8 +290,8 @@
 github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod 
h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
 github.com/godbus/dbus/v5 v5.0.3/go.mod 
h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.0.4/go.mod 
h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
-github.com/gofrs/uuid v4.1.0+incompatible 
h1:sIa2eCvUTwgjbqXrPLfNwUf9S3i3mpH1O1atV+iL/Wk=
-github.com/gofrs/uuid v4.1.0+incompatible/go.mod 
h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
+github.com/gofrs/uuid v4.2.0+incompatible 
h1:yyYWMnhkhrKwwr8gAOcOCYxOOscHgDS9yZgBrnJfGa0=
+github.com/gofrs/uuid v4.2.0+incompatible/go.mod 
h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
 github.com/gogo/googleapis v1.2.0/go.mod 
h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
 github.com/gogo/googleapis v1.4.0/go.mod 
h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c=
 github.com/gogo/protobuf v1.1.1/go.mod 
h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
@@ -388,8 +388,8 @@
 github.com/imdario/mergo v0.3.11/go.mod 
h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/imdario/mergo v0.3.12/go.mod 
h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod 
h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
-github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd 
h1:jupbuQFZtwOBg/3EmK91/rGaYFkqCb9bwHOnwn7Cav0=
-github.com/insomniacslk/dhcp v0.0.0-20211026125128-ad197bcd36fd/go.mod 
h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
+github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489 
h1:jhdHqd7DxBrzfuFSoPxjD6nUVaV/1RIn9aHA0WCf/as=
+github.com/insomniacslk/dhcp v0.0.0-20211214070828-5297eed8f489/go.mod 
h1:h+MxyHxRg9NH3terB1nfRIUaQEcI0XOVkdR9LNBlp8E=
 github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod 
h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA=
 github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod 
h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
 github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod 
h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
@@ -441,8 +441,8 @@
 github.com/mdlayher/netlink v1.1.1/go.mod 
h1:WTYpFb/WTvlRJAyKhZL5/uy69TDDpHHu2VZmb2XgV7o=
 github.com/mdlayher/raw v0.0.0-20190606142536-fef19f00fc18/go.mod 
h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
 github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod 
h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
-github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
-github.com/miekg/dns v1.1.43/go.mod 
h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
+github.com/miekg/dns v1.1.45 h1:g5fRIhm9nx7g8osrAvgb16QJfmyMsyOCb+J7LSv+Qzk=
+github.com/miekg/dns v1.1.45/go.mod 
h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
 github.com/miekg/pkcs11 v1.0.3/go.mod 
h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
 github.com/mistifyio/go-zfs 
v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod 
h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
 github.com/mitchellh/go-homedir v1.1.0/go.mod 
h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -627,6 +627,7 @@
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod 
h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 github.com/yuin/goldmark v1.1.27/go.mod 
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.2.1/go.mod 
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
+github.com/yuin/goldmark v1.3.5/go.mod 
h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod 
h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
 github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod 
h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
 github.com/yvasiyarov/newrelic_platform_go 
v0.0.0-20140908184405-b21fdbd4370f/go.mod 
h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
@@ -663,8 +664,8 @@
 golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod 
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20210317152858-513c2a44f670/go.mod 
h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod 
h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 
h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
-golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod 
h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 
h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
+golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod 
h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod 
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod 
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod 
h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -695,6 +696,8 @@
 golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod 
h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
+golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod 
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod 
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod 
h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -733,8 +736,11 @@
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod 
h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod 
h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20211105192438-b53810dc28af 
h1:SMeNJG/vclJ5wyBBd4xupMsSJIHTd1coW9g7q6KOjmY=
-golang.org/x/net v0.0.0-20211105192438-b53810dc28af/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod 
h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
+golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20211216030914-fe4d6282115f 
h1:hEYJvxw1lSnWIl8X9ofsYMklzaDs90JI2az5YMd4fPM=
+golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod 
h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod 
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod 
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod 
h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -817,15 +823,17 @@
 golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210525143221-35b2ab0089ea/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42 
h1:G2DDmludOQZoWbpCr7OKDxnl478ZBGMcOhrv+ooX/Q4=
-golang.org/x/sys v0.0.0-20211107104306-e0b2ad06fe42/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e 
h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
+golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod 
h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod 
h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod 
h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -879,6 +887,8 @@
 golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod 
h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod 
h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod 
h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
+golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2 
h1:BonxutuHCTL0rBDnZlKjpGIQFTjyUVTexFOdWkB6Fg0=
+golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod 
h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/clash-1.8.0/transport/ssr/protocol/auth_aes128_sha1.go 
new/clash-1.9.0/transport/ssr/protocol/auth_aes128_sha1.go
--- old/clash-1.8.0/transport/ssr/protocol/auth_aes128_sha1.go  2021-11-08 
14:24:39.000000000 +0100
+++ new/clash-1.9.0/transport/ssr/protocol/auth_aes128_sha1.go  2022-01-01 
18:15:49.000000000 +0100
@@ -154,7 +154,7 @@
 }
 
 func (a *authAES128) DecodePacket(b []byte) ([]byte, error) {
-       if !bytes.Equal(a.hmac(a.userKey, b[:len(b)-4])[:4], b[len(b)-4:]) {
+       if !bytes.Equal(a.hmac(a.Key, b[:len(b)-4])[:4], b[len(b)-4:]) {
                return nil, errAuthAES128ChksumError
        }
        return b[:len(b)-4], nil

++++++ clash-vendor.tar.xz ++++++
++++ 37926 lines of diff (skipped)

Reply via email to