github.com/yaling888/clash@v1.53.0/adapter/outbound/reject.go (about)

     1  package outbound
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  	"net"
     7  	"time"
     8  
     9  	"github.com/yaling888/clash/common/cache"
    10  	"github.com/yaling888/clash/component/dialer"
    11  	C "github.com/yaling888/clash/constant"
    12  )
    13  
    14  const (
    15  	rejectCountLimit = 50
    16  	rejectDelay      = time.Second * 35
    17  )
    18  
    19  var rejectCounter = cache.New[string, int](cache.WithAge[string, int](15), cache.WithStale[string, int](false), cache.WithSize[string, int](512))
    20  
    21  var _ C.ProxyAdapter = (*Reject)(nil)
    22  
    23  type Reject struct {
    24  	*Base
    25  }
    26  
    27  // DialContext implements C.ProxyAdapter
    28  func (r *Reject) DialContext(_ context.Context, metadata *C.Metadata, _ ...dialer.Option) (C.Conn, error) {
    29  	key := metadata.RemoteAddress()
    30  
    31  	count, existed := rejectCounter.Get(key)
    32  	if !existed {
    33  		count = 0
    34  	}
    35  
    36  	count = count + 1
    37  
    38  	rejectCounter.Set(key, count)
    39  
    40  	if count > rejectCountLimit {
    41  		c, _ := net.Pipe()
    42  
    43  		_ = c.SetDeadline(time.Now().Add(rejectDelay))
    44  
    45  		return NewConn(c, r), nil
    46  	}
    47  
    48  	return NewConn(&nopConn{}, r), nil
    49  }
    50  
    51  // ListenPacketContext implements C.ProxyAdapter
    52  func (r *Reject) ListenPacketContext(_ context.Context, _ *C.Metadata, _ ...dialer.Option) (C.PacketConn, error) {
    53  	return NewPacketConn(&nopPacketConn{}, r), nil
    54  }
    55  
    56  // DisableDnsResolve implements C.DisableDnsResolve
    57  func (r *Reject) DisableDnsResolve() bool {
    58  	return true
    59  }
    60  
    61  func NewReject() *Reject {
    62  	return NewRejectByName("REJECT")
    63  }
    64  
    65  func NewRejectByName(name string) *Reject {
    66  	return &Reject{
    67  		Base: &Base{
    68  			name: name,
    69  			tp:   C.Reject,
    70  			udp:  true,
    71  		},
    72  	}
    73  }
    74  
    75  type nopConn struct{}
    76  
    77  func (rw *nopConn) Read(_ []byte) (int, error) {
    78  	return 0, io.EOF
    79  }
    80  
    81  func (rw *nopConn) Write(_ []byte) (int, error) {
    82  	return 0, io.EOF
    83  }
    84  
    85  func (rw *nopConn) Close() error                     { return nil }
    86  func (rw *nopConn) LocalAddr() net.Addr              { return nil }
    87  func (rw *nopConn) RemoteAddr() net.Addr             { return nil }
    88  func (rw *nopConn) SetDeadline(time.Time) error      { return nil }
    89  func (rw *nopConn) SetReadDeadline(time.Time) error  { return nil }
    90  func (rw *nopConn) SetWriteDeadline(time.Time) error { return nil }
    91  
    92  type nopPacketConn struct{}
    93  
    94  func (npc *nopPacketConn) WriteTo(b []byte, _ net.Addr) (n int, err error) { return len(b), nil }
    95  func (npc *nopPacketConn) ReadFrom(_ []byte) (int, net.Addr, error)        { return 0, nil, io.EOF }
    96  func (npc *nopPacketConn) Close() error                                    { return nil }
    97  func (npc *nopPacketConn) LocalAddr() net.Addr                             { return &net.UDPAddr{IP: net.IPv4zero, Port: 0} }
    98  func (npc *nopPacketConn) SetDeadline(time.Time) error                     { return nil }
    99  func (npc *nopPacketConn) SetReadDeadline(time.Time) error                 { return nil }
   100  func (npc *nopPacketConn) SetWriteDeadline(time.Time) error                { return nil }