From b8b7d64ba9bcf499ad228bfc1b9c2342d7d49a96 Mon Sep 17 00:00:00 2001 From: sbwml Date: Wed, 20 Sep 2023 15:49:17 +0800 Subject: [PATCH] mosdns: black_hole: apply Fisher-Yates shuffle algorithm to randomize IP order * 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. --- ...-Fisher-Yates-shuffle-algorithm-to-r.patch | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 mosdns/patches/201-black_hole-apply-Fisher-Yates-shuffle-algorithm-to-r.patch diff --git a/mosdns/patches/201-black_hole-apply-Fisher-Yates-shuffle-algorithm-to-r.patch b/mosdns/patches/201-black_hole-apply-Fisher-Yates-shuffle-algorithm-to-r.patch new file mode 100644 index 0000000..48401bd --- /dev/null +++ b/mosdns/patches/201-black_hole-apply-Fisher-Yates-shuffle-algorithm-to-r.patch @@ -0,0 +1,56 @@ +From 6c00597904ba487615e3a49626ccbb7d5623283f Mon Sep 17 00:00:00 2001 +From: sbwml +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 +