mirror of
https://github.com/DNSCrypt/dnscrypt-proxy.git
synced 2025-03-04 10:24:40 +01:00
80 lines
1.5 KiB
Go
80 lines
1.5 KiB
Go
package main
|
|
|
|
import (
|
|
"math/rand"
|
|
"net"
|
|
|
|
"github.com/jedisct1/dlog"
|
|
"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
|
|
dlog.Notice("ECS plugin enabled")
|
|
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
|
|
}
|