diff --git a/common/utils/range.go b/common/utils/range.go new file mode 100644 index 00000000..c569d6a2 --- /dev/null +++ b/common/utils/range.go @@ -0,0 +1,44 @@ +package utils + +import ( + "golang.org/x/exp/constraints" +) + +type Range[T constraints.Ordered] struct { + start T + end T +} + +func NewRange[T constraints.Ordered](start, end T) *Range[T] { + if start > end { + return &Range[T]{ + start: end, + end: start, + } + } + + return &Range[T]{ + start: start, + end: end, + } +} + +func (r *Range[T]) Contains(t T) bool { + return t >= r.start && t <= r.end +} + +func (r *Range[T]) LeftContains(t T) bool { + return t >= r.start && t < r.end +} + +func (r *Range[T]) RightContains(t T) bool { + return t > r.start && t <= r.end +} + +func (r *Range[T]) Start() T { + return r.start +} + +func (r *Range[T]) End() T { + return r.end +} diff --git a/component/sniffer/dispatcher.go b/component/sniffer/dispatcher.go index 545a141c..4734bda1 100644 --- a/component/sniffer/dispatcher.go +++ b/component/sniffer/dispatcher.go @@ -2,11 +2,15 @@ package sniffer import ( "errors" - "github.com/Dreamacro/clash/component/trie" "net" "net/netip" + "strconv" + "time" + + "github.com/Dreamacro/clash/component/trie" CN "github.com/Dreamacro/clash/common/net" + "github.com/Dreamacro/clash/common/utils" "github.com/Dreamacro/clash/component/resolver" C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/log" @@ -26,6 +30,7 @@ type SnifferDispatcher struct { foreDomain *trie.DomainTrie[bool] skipSNI *trie.DomainTrie[bool] + portRanges *[]utils.Range[uint16] } func (sd *SnifferDispatcher) TCPSniff(conn net.Conn, metadata *C.Metadata) { @@ -35,6 +40,18 @@ func (sd *SnifferDispatcher) TCPSniff(conn net.Conn, metadata *C.Metadata) { } if metadata.Host == "" || sd.foreDomain.Search(metadata.Host) != nil { + port, err := strconv.ParseUint(metadata.DstPort, 10, 16) + if err != nil { + log.Debugln("[Sniffer] Dst port is error") + return + } + + for _, portRange := range *sd.portRanges { + if !portRange.Contains(uint16(port)) { + return + } + } + if host, err := sd.sniffDomain(bufConn, metadata); err != nil { log.Debugln("[Sniffer] All sniffing sniff failed with from [%s:%s] to [%s:%s]", metadata.SrcIP, metadata.SrcPort, metadata.String(), metadata.DstPort) return @@ -69,8 +86,16 @@ func (sd *SnifferDispatcher) Enable() bool { func (sd *SnifferDispatcher) sniffDomain(conn *CN.BufferedConn, metadata *C.Metadata) (string, error) { for _, sniffer := range sd.sniffers { if sniffer.SupportNetwork() == C.TCP { + conn.SetReadDeadline(time.Now().Add(3 * time.Second)) _, err := conn.Peek(1) if err != nil { + _, ok := err.(*net.OpError) + if ok { + log.Errorln("[Sniffer] [%s] Maybe read timeout, Consider adding skip", metadata.DstIP.String()) + conn.Close() + } + + log.Errorln("[Sniffer] %v", err) return "", err } @@ -102,11 +127,13 @@ func NewCloseSnifferDispatcher() (*SnifferDispatcher, error) { return &dispatcher, nil } -func NewSnifferDispatcher(needSniffer []C.SnifferType, forceDomain *trie.DomainTrie[bool], skipSNI *trie.DomainTrie[bool]) (*SnifferDispatcher, error) { +func NewSnifferDispatcher(needSniffer []C.SnifferType, forceDomain *trie.DomainTrie[bool], + skipSNI *trie.DomainTrie[bool], ports *[]utils.Range[uint16]) (*SnifferDispatcher, error) { dispatcher := SnifferDispatcher{ enable: true, foreDomain: forceDomain, skipSNI: skipSNI, + portRanges: ports, } for _, snifferName := range needSniffer { diff --git a/config/config.go b/config/config.go index a30c8c25..168d37a0 100644 --- a/config/config.go +++ b/config/config.go @@ -4,16 +4,19 @@ import ( "container/list" "errors" "fmt" - R "github.com/Dreamacro/clash/rule" - RP "github.com/Dreamacro/clash/rule/provider" "net" "net/netip" "net/url" "os" "runtime" + "strconv" "strings" "time" + "github.com/Dreamacro/clash/common/utils" + R "github.com/Dreamacro/clash/rule" + RP "github.com/Dreamacro/clash/rule/provider" + "github.com/Dreamacro/clash/adapter" "github.com/Dreamacro/clash/adapter/outbound" "github.com/Dreamacro/clash/adapter/outboundgroup" @@ -127,6 +130,7 @@ type Sniffer struct { Reverses *trie.DomainTrie[bool] ForceDomain *trie.DomainTrie[bool] SkipSNI *trie.DomainTrie[bool] + Ports *[]utils.Range[uint16] } // Experimental config @@ -224,6 +228,7 @@ type SnifferRaw struct { Reverse []string `yaml:"reverses" json:"reverses"` ForceDomain []string `yaml:"force-domain" json:"force-domain"` SkipSNI []string `yaml:"skip-sni" json:"skip-sni"` + Ports []string `yaml:"port-whitelist" json:"port-whitelist"` } // Parse config @@ -298,6 +303,7 @@ func UnmarshalRawConfig(buf []byte) (*RawConfig, error) { Reverse: []string{}, ForceDomain: []string{}, SkipSNI: []string{}, + Ports: []string{}, }, Profile: Profile{ StoreSelected: true, @@ -890,7 +896,7 @@ func parseTun(rawTun RawTun, general *General) (*Tun, error) { if _, after, ok := strings.Cut(d, "://"); ok { d = after } - + d = strings.Replace(d, "any", "0.0.0.0", 1) addrPort, err := netip.ParseAddrPort(d) if err != nil { return nil, fmt.Errorf("parse dns-hijack url error: %w", err) @@ -914,6 +920,33 @@ func parseSniffer(snifferRaw SnifferRaw) (*Sniffer, error) { Force: snifferRaw.Force, } + ports := []utils.Range[uint16]{} + if len(snifferRaw.Ports) == 0 { + ports = append(ports, *utils.NewRange[uint16](0, 65535)) + } else { + for _, portRange := range snifferRaw.Ports { + portRaws := strings.Split(portRange, "-") + if len(portRaws) > 1 { + p, err := strconv.ParseUint(portRaws[0], 10, 16) + if err != nil { + return nil, fmt.Errorf("%s format error", portRange) + } + + start := uint16(p) + + p, err = strconv.ParseUint(portRaws[0], 10, 16) + if err != nil { + return nil, fmt.Errorf("%s format error", portRange) + } + + end := uint16(p) + ports = append(ports, *utils.NewRange(start, end)) + } + } + } + + sniffer.Ports = &ports + loadSniffer := make(map[C.SnifferType]struct{}) for _, snifferName := range snifferRaw.Sniffing { diff --git a/constant/metadata.go b/constant/metadata.go index b716a6e2..5a91fe96 100644 --- a/constant/metadata.go +++ b/constant/metadata.go @@ -88,11 +88,7 @@ type Metadata struct { } func (m *Metadata) RemoteAddress() string { - if m.DstIP.IsValid() { - return net.JoinHostPort(m.DstIP.String(), m.DstPort) - } else { - return net.JoinHostPort(m.String(), m.DstPort) - } + return net.JoinHostPort(m.String(), m.DstPort) } func (m *Metadata) SourceAddress() string { diff --git a/go.mod b/go.mod index 769dbe66..360bf21b 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,8 @@ require ( go.uber.org/atomic v1.9.0 go.uber.org/automaxprocs v1.5.1 golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 - golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 + golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd + golang.org/x/net v0.0.0-20220412020605-290c469a71a5 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c golang.org/x/sys v0.0.0-20220412211240-33da011f77ad golang.org/x/time v0.0.0-20220411224347-583f2d630306 diff --git a/go.sum b/go.sum index e159f21a..8ac11ca2 100644 --- a/go.sum +++ b/go.sum @@ -224,6 +224,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4 h1:kUhD7nTDoI3fVd9G4ORWrbV5NY0liEs/Jg2pv5f+bBA= golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4/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-20220414153411-bcd21879b8fd h1:zVFyTKZN/Q7mNRWSs1GOYnHM9NiFSJ54YVRsD0rNWT4= +golang.org/x/exp v0.0.0-20220414153411-bcd21879b8fd/go.mod h1:lgLbSvA5ygNOMpwM/9anMpWVlVJ7Z+cHWq/eFuinpGE= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -255,8 +257,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2 h1:6mzvA99KwZxbOrxww4EvWVQUnN1+xEu9tafK5ZxkYeA= -golang.org/x/net v0.0.0-20220418201149-a630d4f3e7a2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5 h1:bRb386wvrE+oBNdF1d/Xh9mQrfQ4ecYhW5qJ5GvTGT4= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= diff --git a/hub/executor/executor.go b/hub/executor/executor.go index 09d72ccf..e70aac3d 100644 --- a/hub/executor/executor.go +++ b/hub/executor/executor.go @@ -222,7 +222,7 @@ func updateTun(tun *config.Tun, dns *config.DNS) { func updateSniffer(sniffer *config.Sniffer) { if sniffer.Enable { - dispatcher, err := SNI.NewSnifferDispatcher(sniffer.Sniffers, sniffer.ForceDomain, sniffer.SkipSNI) + dispatcher, err := SNI.NewSnifferDispatcher(sniffer.Sniffers, sniffer.ForceDomain, sniffer.SkipSNI, sniffer.Ports) if err != nil { log.Warnln("initial sniffer failed, err:%v", err) } diff --git a/listener/tun/ipstack/gvisor/handler.go b/listener/tun/ipstack/gvisor/handler.go index 8c43a64d..8d93ce3a 100644 --- a/listener/tun/ipstack/gvisor/handler.go +++ b/listener/tun/ipstack/gvisor/handler.go @@ -16,16 +16,17 @@ import ( "github.com/Dreamacro/clash/transport/socks5" ) -var _ adapter.Handler = (*GVHandler)(nil) +var _ adapter.Handler = (*gvHandler)(nil) -type GVHandler struct { - DNSAdds []netip.AddrPort +type gvHandler struct { + gateway netip.Addr + dnsHijack []netip.AddrPort - TCPIn chan<- C.ConnContext - UDPIn chan<- *inbound.PacketAdapter + tcpIn chan<- C.ConnContext + udpIn chan<- *inbound.PacketAdapter } -func (gh *GVHandler) HandleTCP(tunConn adapter.TCPConn) { +func (gh *gvHandler) HandleTCP(tunConn adapter.TCPConn) { id := tunConn.ID() rAddr := &net.TCPAddr{ @@ -34,11 +35,11 @@ func (gh *GVHandler) HandleTCP(tunConn adapter.TCPConn) { Zone: "", } - addrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort) + rAddrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort) - if D.ShouldHijackDns(gh.DNSAdds, addrPort) { + if D.ShouldHijackDns(gh.dnsHijack, rAddrPort) { go func() { - log.Debugln("[TUN] hijack dns tcp: %s", addrPort.String()) + log.Debugln("[TUN] hijack dns tcp: %s", rAddrPort.String()) buf := pool.Get(pool.UDPBufferSize) defer func() { @@ -77,10 +78,10 @@ func (gh *GVHandler) HandleTCP(tunConn adapter.TCPConn) { return } - gh.TCPIn <- inbound.NewSocket(socks5.ParseAddrToSocksAddr(rAddr), tunConn, C.TUN) + gh.tcpIn <- inbound.NewSocket(socks5.ParseAddrToSocksAddr(rAddr), tunConn, C.TUN) } -func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) { +func (gh *gvHandler) HandleUDP(tunConn adapter.UDPConn) { id := tunConn.ID() rAddr := &net.UDPAddr{ @@ -89,7 +90,13 @@ func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) { Zone: "", } - addrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort) + rAddrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), id.LocalPort) + + if rAddrPort.Addr() == gh.gateway { + _ = tunConn.Close() + return + } + target := socks5.ParseAddrToSocksAddr(rAddr) go func() { @@ -104,7 +111,7 @@ func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) { payload := buf[:n] - if D.ShouldHijackDns(gh.DNSAdds, addrPort) { + if D.ShouldHijackDns(gh.dnsHijack, rAddrPort) { go func() { defer func() { _ = pool.Put(buf) @@ -130,7 +137,7 @@ func (gh *GVHandler) HandleUDP(tunConn adapter.UDPConn) { } select { - case gh.UDPIn <- inbound.NewPacket(target, gvPacket, C.TUN): + case gh.udpIn <- inbound.NewPacket(target, gvPacket, C.TUN): default: } } diff --git a/listener/tun/ipstack/gvisor/stack.go b/listener/tun/ipstack/gvisor/stack.go index c762e6a2..1307bc71 100644 --- a/listener/tun/ipstack/gvisor/stack.go +++ b/listener/tun/ipstack/gvisor/stack.go @@ -2,9 +2,12 @@ package gvisor import ( + "net/netip" + + "github.com/Dreamacro/clash/adapter/inbound" + C "github.com/Dreamacro/clash/constant" "github.com/Dreamacro/clash/listener/tun/device" "github.com/Dreamacro/clash/listener/tun/ipstack" - "github.com/Dreamacro/clash/listener/tun/ipstack/gvisor/adapter" "github.com/Dreamacro/clash/listener/tun/ipstack/gvisor/option" "gvisor.dev/gvisor/pkg/tcpip" @@ -34,7 +37,7 @@ func (s *gvStack) Close() error { } // New allocates a new *gvStack with given options. -func New(device device.Device, handler adapter.Handler, opts ...option.Option) (ipstack.Stack, error) { +func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Prefix, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter, opts ...option.Option) (ipstack.Stack, error) { s := &gvStack{ Stack: stack.New(stack.Options{ NetworkProtocols: []stack.NetworkProtocolFactory{ @@ -52,6 +55,13 @@ func New(device device.Device, handler adapter.Handler, opts ...option.Option) ( device: device, } + handler := &gvHandler{ + gateway: tunAddress.Masked().Addr().Next(), + dnsHijack: dnsHijack, + tcpIn: tcpIn, + udpIn: udpIn, + } + // Generate unique NIC id. nicID := tcpip.NICID(s.Stack.UniqueID()) diff --git a/listener/tun/ipstack/system/mars/mars.go b/listener/tun/ipstack/system/mars/mars.go index e150437e..a553c2d6 100644 --- a/listener/tun/ipstack/system/mars/mars.go +++ b/listener/tun/ipstack/system/mars/mars.go @@ -27,10 +27,8 @@ func StartListener(device io.ReadWriteCloser, gateway, portal, broadcast netip.A } func (t *StackListener) Close() error { - _ = t.tcp.Close() _ = t.udp.Close() - - return t.device.Close() + return t.tcp.Close() } func (t *StackListener) TCP() *nat.TCP { diff --git a/listener/tun/ipstack/system/stack.go b/listener/tun/ipstack/system/stack.go index 16fd37d0..803e5db0 100644 --- a/listener/tun/ipstack/system/stack.go +++ b/listener/tun/ipstack/system/stack.go @@ -7,6 +7,7 @@ import ( "net/netip" "runtime" "strconv" + "sync" "time" "github.com/Dreamacro/clash/adapter/inbound" @@ -28,6 +29,8 @@ type sysStack struct { device device.Device closed bool + once sync.Once + wg sync.WaitGroup } func (s *sysStack) Close() error { @@ -38,10 +41,12 @@ func (s *sysStack) Close() error { }() s.closed = true - if s.stack != nil { - return s.stack.Close() - } - return nil + + err := s.stack.Close() + + s.wg.Wait() + + return err } func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Prefix, tcpIn chan<- C.ConnContext, udpIn chan<- *inbound.PacketAdapter) (ipstack.Stack, error) { @@ -67,16 +72,10 @@ func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Pref _ = tcp.Close() }(stack.TCP()) - defer log.Debugln("TCP: closed") - for !ipStack.closed { - if err = stack.TCP().SetDeadline(time.Time{}); err != nil { - break - } - conn, err := stack.TCP().Accept() if err != nil { - log.Debugln("Accept connection: %v", err) + log.Debugln("[STACK] accept connection error: %v", err) continue } @@ -146,6 +145,8 @@ func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Pref tcpIn <- context.NewConnContext(conn, metadata) } + + ipStack.wg.Done() } udp := func() { @@ -153,14 +154,13 @@ func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Pref _ = udp.Close() }(stack.UDP()) - defer log.Debugln("UDP: closed") - for !ipStack.closed { buf := pool.Get(pool.UDPBufferSize) n, lRAddr, rRAddr, err := stack.UDP().ReadFrom(buf) if err != nil { - return + _ = pool.Put(buf) + break } raw := buf[:n] @@ -169,7 +169,7 @@ func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Pref rAddrPort := netip.AddrPortFrom(nnip.IpToAddr(rAddr.IP), uint16(rAddr.Port)) - if rAddrPort.Addr().IsLoopback() { + if rAddrPort.Addr().IsLoopback() || rAddrPort.Addr() == gateway { _ = pool.Put(buf) continue @@ -209,17 +209,23 @@ func New(device device.Device, dnsHijack []netip.AddrPort, tunAddress netip.Pref default: } } + + ipStack.wg.Done() } - go tcp() + ipStack.once.Do(func() { + ipStack.wg.Add(1) + go tcp() - numUDPWorkers := 4 - if num := runtime.GOMAXPROCS(0); num > numUDPWorkers { - numUDPWorkers = num - } - for i := 0; i < numUDPWorkers; i++ { - go udp() - } + numUDPWorkers := 4 + if num := runtime.GOMAXPROCS(0); num > numUDPWorkers { + numUDPWorkers = num + } + for i := 0; i < numUDPWorkers; i++ { + ipStack.wg.Add(1) + go udp() + } + }) return ipStack, nil } diff --git a/listener/tun/tun_adapter.go b/listener/tun/tun_adapter.go index 3cd20da2..eed95333 100644 --- a/listener/tun/tun_adapter.go +++ b/listener/tun/tun_adapter.go @@ -67,13 +67,7 @@ func New(tunConf *config.Tun, dnsConf *config.DNS, tcpIn chan<- C.ConnContext, u return nil, fmt.Errorf("can't attach endpoint to tun: %w", err) } - tunStack, err = gvisor.New(tunDevice, - &gvisor.GVHandler{ - DNSAdds: tunConf.DNSHijack, - TCPIn: tcpIn, UDPIn: udpIn, - }, - option.WithDefault(), - ) + tunStack, err = gvisor.New(tunDevice, tunConf.DNSHijack, tunAddress, tcpIn, udpIn, option.WithDefault()) if err != nil { _ = tunDevice.Close() diff --git a/rule/common/port.go b/rule/common/port.go index 0e46649b..06fde6c2 100644 --- a/rule/common/port.go +++ b/rule/common/port.go @@ -5,20 +5,16 @@ import ( "strconv" "strings" + "github.com/Dreamacro/clash/common/utils" C "github.com/Dreamacro/clash/constant" ) -type portReal struct { - portStart int - portEnd int -} - type Port struct { *Base adapter string port string isSource bool - portList []portReal + portList []utils.Range[uint16] } func (p *Port) RuleType() C.RuleType { @@ -45,17 +41,13 @@ func (p *Port) Payload() string { func (p *Port) matchPortReal(portRef string) bool { port, _ := strconv.Atoi(portRef) - var rs bool + for _, pr := range p.portList { - if pr.portEnd == -1 { - rs = port == pr.portStart - } else { - rs = port >= pr.portStart && port <= pr.portEnd - } - if rs { + if pr.Contains(uint16(port)) { return true } } + return false } @@ -65,7 +57,7 @@ func NewPort(port string, adapter string, isSource bool) (*Port, error) { return nil, fmt.Errorf("%s, too many ports to use, maximum support 28 ports", errPayload.Error()) } - var portList []portReal + var portRange []utils.Range[uint16] for _, p := range ports { if p == "" { continue @@ -84,23 +76,18 @@ func NewPort(port string, adapter string, isSource bool) (*Port, error) { switch subPortsLen { case 1: - portList = append(portList, portReal{int(portStart), -1}) + portRange = append(portRange, *utils.NewRange(uint16(portStart), uint16(portStart))) case 2: portEnd, err := strconv.ParseUint(strings.Trim(subPorts[1], "[ ]"), 10, 16) if err != nil { return nil, errPayload } - shouldReverse := portStart > portEnd - if shouldReverse { - portList = append(portList, portReal{int(portEnd), int(portStart)}) - } else { - portList = append(portList, portReal{int(portStart), int(portEnd)}) - } + portRange = append(portRange, *utils.NewRange(uint16(portStart), uint16(portEnd))) } } - if len(portList) == 0 { + if len(portRange) == 0 { return nil, errPayload } @@ -109,7 +96,7 @@ func NewPort(port string, adapter string, isSource bool) (*Port, error) { adapter: adapter, port: port, isSource: isSource, - portList: portList, + portList: portRange, }, nil } diff --git a/tunnel/tunnel.go b/tunnel/tunnel.go index 0cfc823a..e720dff9 100644 --- a/tunnel/tunnel.go +++ b/tunnel/tunnel.go @@ -37,9 +37,9 @@ var ( mode = Rule // default timeout for UDP session - udpTimeout = 60 * time.Second - - snifferDispatcher *sniffer.SnifferDispatcher + udpTimeout = 60 * time.Second + procesCache string + failTotal int ) func init() { @@ -171,11 +171,17 @@ func preHandleMetadata(metadata *C.Metadata) error { if err == nil && P.ShouldFindProcess(metadata) { path, err := P.FindProcessName(metadata.NetWork.String(), metadata.SrcIP, srcPort) if err != nil { - log.Debugln("[Process] find process %s: %v", metadata.String(), err) + if failTotal < 20 { + log.Debugln("[Process] find process %s: %v", metadata.String(), err) + failTotal++ + } } else { - log.Debugln("[Process] %s from process %s", metadata.String(), path) metadata.Process = filepath.Base(path) metadata.ProcessPath = path + if procesCache == metadata.Process { + log.Debugln("[Process] %s from process %s", metadata.String(), path) + } + procesCache = metadata.Process } } return nil