diff --git a/dnscrypt-proxy/coldstart.go b/dnscrypt-proxy/coldstart.go index 35aa8afa..6d71abba 100644 --- a/dnscrypt-proxy/coldstart.go +++ b/dnscrypt-proxy/coldstart.go @@ -22,7 +22,7 @@ type CaptivePortalHandler struct { cancelChannels []chan struct{} } -func (captivePortalHandler *CaptivePortalHandler) Stop() { +func (captivePortalHandler *CaptivePortalHandler) Stop() { for _, cancelChannel := range captivePortalHandler.cancelChannels { cancelChannel <- struct{}{} _ = <-cancelChannel diff --git a/dnscrypt-proxy/plugin_dns64.go b/dnscrypt-proxy/plugin_dns64.go index 96240c10..67b4abb2 100644 --- a/dnscrypt-proxy/plugin_dns64.go +++ b/dnscrypt-proxy/plugin_dns64.go @@ -30,7 +30,7 @@ func (plugin *PluginDNS64) Name() string { } func (plugin *PluginDNS64) Description() string { - return "Synth DNS64 AAAA responses" + return "Synthesize DNS64 AAAA responses" } func (plugin *PluginDNS64) Init(proxy *Proxy) error { diff --git a/dnscrypt-proxy/plugin_ecs.go b/dnscrypt-proxy/plugin_ecs.go new file mode 100644 index 00000000..60c817e0 --- /dev/null +++ b/dnscrypt-proxy/plugin_ecs.go @@ -0,0 +1,78 @@ +package main + +import ( + "math/rand" + "net" + + "github.com/miekg/dns" +) + +type PluginECS struct { + nets []*net.IPNet +} + +func (plugin *PluginECS) Name() string { + return "ecs" +} + +func (plugin *PluginECS) Description() string { + return "Set EDNS-client-subnet information in outgoing queries." +} + +func (plugin *PluginECS) Init(proxy *Proxy) error { + plugin.nets = proxy.ednsClientSubnets + return nil +} + +func (plugin *PluginECS) Drop() error { + return nil +} + +func (plugin *PluginECS) Reload() error { + return nil +} + +func (plugin *PluginECS) Eval(pluginsState *PluginsState, msg *dns.Msg) error { + var options *[]dns.EDNS0 + + for _, extra := range msg.Extra { + if extra.Header().Rrtype == dns.TypeOPT { + options = &extra.(*dns.OPT).Option + for _, option := range *options { + if option.Option() == dns.EDNS0SUBNET { + return nil + } + } + break + } + } + if options == nil { + msg.SetEdns0(uint16(pluginsState.maxPayloadSize), false) + for _, extra := range msg.Extra { + if extra.Header().Rrtype == dns.TypeOPT { + options = &extra.(*dns.OPT).Option + break + } + } + } + if options == nil { + return nil + } + prr := dns.EDNS0_SUBNET{} + prr.Code = dns.EDNS0SUBNET + net := plugin.nets[rand.Intn(len(plugin.nets))] + bits, totalSize := net.Mask.Size() + if totalSize == 32 { + prr.Family = 1 + } else if totalSize == 128 { + prr.Family = 2 + } else { + return nil + } + prr.SourceNetmask = uint8(bits) + prr.SourceScope = 0 + prr.Address = net.IP + *options = append(*options, &prr) + + return nil +}