From 117228fa8c22f0673c1656959538b2d3de8953cb Mon Sep 17 00:00:00 2001 From: Larvan2 <78135608+Larvan2@users.noreply.github.com> Date: Sat, 18 Nov 2023 13:17:15 +0800 Subject: [PATCH] feat: support REJECT-DROP --- adapter/outbound/reject.go | 94 ++++++++++++++++++++++-------- adapter/outboundgroup/groupbase.go | 2 +- config/config.go | 1 + constant/adapters.go | 4 ++ 4 files changed, 77 insertions(+), 24 deletions(-) diff --git a/adapter/outbound/reject.go b/adapter/outbound/reject.go index 5625f932c..b564e28d6 100644 --- a/adapter/outbound/reject.go +++ b/adapter/outbound/reject.go @@ -13,6 +13,7 @@ import ( type Reject struct { *Base + drop bool } type RejectOption struct { @@ -21,12 +22,18 @@ type RejectOption struct { // DialContext implements C.ProxyAdapter func (r *Reject) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) { + if r.drop { + return NewConn(dropConn{}, 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 newPacketConn(nopPacketConn{}, r), nil + if r.drop { + return newPacketConn(&dropPacketConn{}, r), nil + } + return newPacketConn(&nopPacketConn{}, r), nil } func NewRejectWithOption(option RejectOption) *Reject { @@ -50,6 +57,18 @@ func NewReject() *Reject { } } +func NewRejectDrop() *Reject { + return &Reject{ + Base: &Base{ + name: "REJECT-DROP", + tp: C.RejectDrop, + udp: true, + prefer: C.DualStack, + }, + drop: true, + } +} + func NewPass() *Reject { return &Reject{ Base: &Base{ @@ -63,35 +82,29 @@ func NewPass() *Reject { type nopConn struct{} -func (rw nopConn) Read(b []byte) (int, error) { - return 0, io.EOF -} +func (rw nopConn) Read(b []byte) (int, error) { return 0, io.EOF } -func (rw nopConn) ReadBuffer(buffer *buf.Buffer) error { - return io.EOF -} +func (rw nopConn) ReadBuffer(buffer *buf.Buffer) error { return io.EOF } -func (rw nopConn) Write(b []byte) (int, error) { - return 0, io.EOF -} - -func (rw nopConn) WriteBuffer(buffer *buf.Buffer) error { - return io.EOF -} - -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 } +func (rw nopConn) Write(b []byte) (int, error) { return 0, io.EOF } +func (rw nopConn) WriteBuffer(buffer *buf.Buffer) error { return io.EOF } +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 } var udpAddrIPv4Unspecified = &net.UDPAddr{IP: net.IPv4zero, Port: 0} 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) 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) WaitReadFrom() ([]byte, func(), net.Addr, error) { return nil, nil, nil, io.EOF } @@ -100,3 +113,38 @@ func (npc nopPacketConn) LocalAddr() net.Addr { return udpAddrIPv4U 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 } + +type dropConn struct{} + +func (rw dropConn) Read(b []byte) (int, error) { return 0, io.EOF } +func (rw dropConn) ReadBuffer(buffer *buf.Buffer) error { + time.Sleep(C.DefaultDropTime) + return io.EOF +} +func (rw dropConn) Write(b []byte) (int, error) { return 0, io.EOF } +func (rw dropConn) WriteBuffer(buffer *buf.Buffer) error { return io.EOF } +func (rw dropConn) Close() error { return nil } +func (rw dropConn) LocalAddr() net.Addr { return nil } +func (rw dropConn) RemoteAddr() net.Addr { return nil } +func (rw dropConn) SetDeadline(time.Time) error { return nil } +func (rw dropConn) SetReadDeadline(time.Time) error { return nil } +func (rw dropConn) SetWriteDeadline(time.Time) error { return nil } + +type dropPacketConn struct{} + +func (npc dropPacketConn) WriteTo(b []byte, addr net.Addr) (n int, err error) { + time.Sleep(C.DefaultDropTime) + return len(b), nil +} +func (npc dropPacketConn) ReadFrom(b []byte) (int, net.Addr, error) { + time.Sleep(C.DefaultDropTime) + return 0, nil, io.EOF +} +func (npc dropPacketConn) WaitReadFrom() ([]byte, func(), net.Addr, error) { + return nil, nil, nil, io.EOF +} +func (npc dropPacketConn) Close() error { return nil } +func (npc dropPacketConn) LocalAddr() net.Addr { return udpAddrIPv4Unspecified } +func (npc dropPacketConn) SetDeadline(time.Time) error { return nil } +func (npc dropPacketConn) SetReadDeadline(time.Time) error { return nil } +func (npc dropPacketConn) SetWriteDeadline(time.Time) error { return nil } diff --git a/adapter/outboundgroup/groupbase.go b/adapter/outboundgroup/groupbase.go index d4a812f6a..8f5f92dfb 100644 --- a/adapter/outboundgroup/groupbase.go +++ b/adapter/outboundgroup/groupbase.go @@ -222,7 +222,7 @@ func (gb *GroupBase) URLTest(ctx context.Context, url string, expectedStatus uti } func (gb *GroupBase) onDialFailed(adapterType C.AdapterType, err error) { - if adapterType == C.Direct || adapterType == C.Compatible || adapterType == C.Reject || adapterType == C.Pass { + if adapterType == C.Direct || adapterType == C.Compatible || adapterType == C.Reject || adapterType == C.Pass || adapterType == C.RejectDrop { return } diff --git a/config/config.go b/config/config.go index c2b389c3c..0158ac714 100644 --- a/config/config.go +++ b/config/config.go @@ -673,6 +673,7 @@ func parseProxies(cfg *RawConfig) (proxies map[string]C.Proxy, providersMap map[ proxies["DIRECT"] = adapter.NewProxy(outbound.NewDirect()) proxies["REJECT"] = adapter.NewProxy(outbound.NewReject()) + proxies["REJECT-DROP"] = adapter.NewProxy(outbound.NewRejectDrop()) proxies["COMPATIBLE"] = adapter.NewProxy(outbound.NewCompatible()) proxies["PASS"] = adapter.NewProxy(outbound.NewPass()) proxyList = append(proxyList, "DIRECT", "REJECT") diff --git a/constant/adapters.go b/constant/adapters.go index 5cf6e07c9..757068f3d 100644 --- a/constant/adapters.go +++ b/constant/adapters.go @@ -18,6 +18,7 @@ import ( const ( Direct AdapterType = iota Reject + RejectDrop Compatible Pass @@ -43,6 +44,7 @@ const ( const ( DefaultTCPTimeout = 5 * time.Second + DefaultDropTime = 12 * DefaultTCPTimeout DefaultUDPTimeout = DefaultTCPTimeout DefaultTLSTimeout = DefaultTCPTimeout DefaultMaxHealthCheckUrlNum = 16 @@ -179,6 +181,8 @@ func (at AdapterType) String() string { return "Direct" case Reject: return "Reject" + case RejectDrop: + return "RejectDrop" case Compatible: return "Compatible" case Pass: