
* The client seems to always use the first IP address in the response, using a random algorithm to scramble multiple IP addresses so that the client can use all IP addresses as much as possible.
57 lines
1.5 KiB
Diff
57 lines
1.5 KiB
Diff
From 6c00597904ba487615e3a49626ccbb7d5623283f Mon Sep 17 00:00:00 2001
|
|
From: sbwml <admin@cooluc.com>
|
|
Date: Wed, 20 Sep 2023 14:51:19 +0800
|
|
Subject: [PATCH] black_hole: apply Fisher-Yates shuffle algorithm to randomize
|
|
IP order
|
|
|
|
---
|
|
plugin/executable/black_hole/black_hole.go | 15 +++++++++++++++
|
|
1 file changed, 15 insertions(+)
|
|
|
|
diff --git a/plugin/executable/black_hole/black_hole.go b/plugin/executable/black_hole/black_hole.go
|
|
index 775253d..f955019 100644
|
|
--- a/plugin/executable/black_hole/black_hole.go
|
|
+++ b/plugin/executable/black_hole/black_hole.go
|
|
@@ -27,6 +27,8 @@ import (
|
|
"github.com/miekg/dns"
|
|
"net/netip"
|
|
"strings"
|
|
+ "math/rand"
|
|
+ "sync"
|
|
)
|
|
|
|
const PluginType = "black_hole"
|
|
@@ -40,6 +42,7 @@ var _ sequence.Executable = (*BlackHole)(nil)
|
|
type BlackHole struct {
|
|
ipv4 []netip.Addr
|
|
ipv6 []netip.Addr
|
|
+ shuffleMutex sync.Mutex
|
|
}
|
|
|
|
// QuickSetup format: [ipv4|ipv6] ...
|
|
@@ -65,9 +68,21 @@ func NewBlackHole(ips []string) (*BlackHole, error) {
|
|
return b, nil
|
|
}
|
|
|
|
+func (b *BlackHole) shuffleIPs() {
|
|
+ b.shuffleMutex.Lock()
|
|
+ defer b.shuffleMutex.Unlock()
|
|
+ rand.Shuffle(len(b.ipv4), func(i, j int) {
|
|
+ b.ipv4[i], b.ipv4[j] = b.ipv4[j], b.ipv4[i]
|
|
+ })
|
|
+ rand.Shuffle(len(b.ipv6), func(i, j int) {
|
|
+ b.ipv6[i], b.ipv6[j] = b.ipv6[j], b.ipv6[i]
|
|
+ })
|
|
+}
|
|
+
|
|
// Exec implements sequence.Executable. It set a response with given ips if
|
|
// query has corresponding qtypes.
|
|
func (b *BlackHole) Exec(_ context.Context, qCtx *query_context.Context) error {
|
|
+ b.shuffleIPs()
|
|
if r := b.Response(qCtx.Q()); r != nil {
|
|
qCtx.SetResponse(r)
|
|
}
|
|
--
|
|
2.34.8
|
|
|