diff --git a/cmd/routedns/config.go b/cmd/routedns/config.go index 1726caad..2cf59592 100644 --- a/cmd/routedns/config.go +++ b/cmd/routedns/config.go @@ -22,6 +22,7 @@ type config struct { type listener struct { Address string Protocol string + IPVersion int `toml:"ip-version"` // 4 = IPv4, 6 = IPv6 Transport string Resolver string CA string diff --git a/cmd/routedns/main.go b/cmd/routedns/main.go index f99529f2..ec859404 100644 --- a/cmd/routedns/main.go +++ b/cmd/routedns/main.go @@ -196,15 +196,21 @@ func start(opt options, args []string) error { return err } + if l.IPVersion != 4 && l.IPVersion != 6 && l.IPVersion != 0 { + return errors.New("ip-version must be 4 or 6") + } + opt := rdns.ListenOptions{AllowedNet: allowedNet} switch l.Protocol { case "tcp": + network := networkForIPVersion("tcp", l.IPVersion) l.Address = rdns.AddressWithDefault(l.Address, rdns.PlainDNSPort) - listeners = append(listeners, rdns.NewDNSListener(id, l.Address, "tcp", opt, resolver)) + listeners = append(listeners, rdns.NewDNSListener(id, l.Address, network, opt, resolver)) case "udp": + network := networkForIPVersion("udp", l.IPVersion) l.Address = rdns.AddressWithDefault(l.Address, rdns.PlainDNSPort) - listeners = append(listeners, rdns.NewDNSListener(id, l.Address, "udp", opt, resolver)) + listeners = append(listeners, rdns.NewDNSListener(id, l.Address, network, opt, resolver)) case "admin": tlsConfig, err := rdns.TLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS) if err != nil { @@ -221,12 +227,13 @@ func start(opt options, args []string) error { } listeners = append(listeners, ln) case "dot": + network := networkForIPVersion("tcp", l.IPVersion) l.Address = rdns.AddressWithDefault(l.Address, rdns.DoTPort) tlsConfig, err := rdns.TLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS) if err != nil { return err } - ln := rdns.NewDoTListener(id, l.Address, rdns.DoTListenerOptions{TLSConfig: tlsConfig, ListenOptions: opt}, resolver) + ln := rdns.NewDoTListener(id, l.Address, network, rdns.DoTListenerOptions{TLSConfig: tlsConfig, ListenOptions: opt}, resolver) listeners = append(listeners, ln) case "dtls": l.Address = rdns.AddressWithDefault(l.Address, rdns.DTLSPort) @@ -248,7 +255,6 @@ func start(opt options, args []string) error { return errors.New("no-tls is not supported for doh servers with quic transport") } } else { - fmt.Println("p4") tlsConfig, err = rdns.TLSServerConfig(l.CA, l.ServerCrt, l.ServerKey, l.MutualTLS) if err != nil { return err @@ -892,6 +898,13 @@ func newIPBlocklistDB(l list, locationDB string, rules []string) (rdns.IPBlockli } } +func networkForIPVersion(base string, ipVersion int) string { + if ipVersion == 0 { + return base + } + return base + strconv.Itoa(ipVersion) +} + func printVersion() { fmt.Println("Build: ", rdns.BuildNumber) fmt.Println("Build Time: ", rdns.BuildTime) diff --git a/doc/configuration.md b/doc/configuration.md index 8eed4cb1..b3d77899 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -119,6 +119,7 @@ Common options for all listeners: - `address` - Listen address. - `protocol` - The DNS protocol used to receive queries, can be `udp`, `tcp`, `dot`, `doh`, `doq`. +- `ip-version` - IP version (4 or 6) to use for the listener. Optional, defaults to both. - `resolver` - Name/identifier of the next element in the pipeline. Can be a router, group, modifier or resolver. - `allowed-net` - Array of network addresses that are allowed to send queries to this listener, in CIDR notation, such as `["192.167.1.0/24", "::1/128"]`. If not set, no filter is applied, all clients can send queries. diff --git a/dotlistener.go b/dotlistener.go index c21bbac8..2c3a0e91 100644 --- a/dotlistener.go +++ b/dotlistener.go @@ -23,12 +23,15 @@ type DoTListenerOptions struct { } // NewDoTListener returns an instance of a DNS-over-TLS listener. -func NewDoTListener(id, addr string, opt DoTListenerOptions, resolver Resolver) *DoTListener { +func NewDoTListener(id, addr, network string, opt DoTListenerOptions, resolver Resolver) *DoTListener { + if network == "" { + network = "tcp-tls" + } return &DoTListener{ id: id, Server: &dns.Server{ Addr: addr, - Net: "tcp-tls", + Net: network, TLSConfig: opt.TLSConfig, Handler: listenHandler(id, "dot", addr, resolver, opt.AllowedNet), },