Skip to content

Commit fc6c04c

Browse files
author
mikitsu
committed
handler, cmd: add disable-ipv4 option
The new disable-ipv4 option operates completely analogously to the existing disable-ipv6 option: A records are discarded from answers. This feature is useful on IPv6-only hosts with misbehaving applications that only attempt one connection using the first DNS answer.
1 parent 95e7ffa commit fc6c04c

File tree

5 files changed

+46
-0
lines changed

5 files changed

+46
-0
lines changed

internal/cmd/args.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const (
5757
verboseIdx
5858
insecureIdx
5959
ipv6DisabledIdx
60+
ipv4DisabledIdx
6061
http3Idx
6162
cacheOptimisticIdx
6263
cacheIdx
@@ -340,6 +341,13 @@ var commandLineOptions = []*commandLineOption{
340341
short: "",
341342
valueType: "",
342343
},
344+
ipv4DisabledIdx: {
345+
description: "If specified, all A requests will be replied with NoError RCode and " +
346+
"empty answer.",
347+
long: "ipv4-disabled",
348+
short: "",
349+
valueType: "",
350+
},
343351
http3Idx: {
344352
description: "Enable HTTP/3 support.",
345353
long: "http3",
@@ -440,6 +448,7 @@ func parseCmdLineOptions(conf *configuration) (err error) {
440448
verboseIdx: &conf.Verbose,
441449
insecureIdx: &conf.Insecure,
442450
ipv6DisabledIdx: &conf.IPv6Disabled,
451+
ipv4DisabledIdx: &conf.IPv4Disabled,
443452
http3Idx: &conf.HTTP3,
444453
cacheOptimisticIdx: &conf.CacheOptimistic,
445454
cacheIdx: &conf.Cache,

internal/cmd/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,9 @@ type configuration struct {
162162
// IPv6Disabled makes the server to respond with NODATA to all AAAA queries.
163163
IPv6Disabled bool `yaml:"ipv6-disabled"`
164164

165+
// IPv4Disabled makes the server to respond with NODATA to all AAAA queries.
166+
IPv4Disabled bool `yaml:"ipv4-disabled"`
167+
165168
// HTTP3 controls whether HTTP/3 is enabled for this instance of dnsproxy.
166169
// It enables HTTP/3 support for both the DoH upstreams and the DoH server.
167170
HTTP3 bool `yaml:"http3"`

internal/cmd/proxy.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ func createProxyConfig(
4949
// TODO(e.burkov): Use the configured message constructor.
5050
MessageConstructor: dnsmsg.DefaultMessageConstructor{},
5151
HaltIPv6: conf.IPv6Disabled,
52+
HaltIPv4: conf.IPv4Disabled,
5253
HostsFiles: hosts,
5354
})
5455

internal/handler/default.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ type DefaultConfig struct {
2323
// HaltIPv6 halts the processing of AAAA requests and makes the handler
2424
// reply with NODATA to them, if true.
2525
HaltIPv6 bool
26+
27+
// HaltIPv4 halts the processing of A requests and makes the handler
28+
// reply with NODATA to them.
29+
HaltIPv4 bool
2630
}
2731

2832
// Default implements the default configurable [proxy.RequestHandler].
@@ -31,6 +35,7 @@ type Default struct {
3135
hosts hostsfile.Storage
3236
logger *slog.Logger
3337
isIPv6Halted bool
38+
isIPv4Halted bool
3439
}
3540

3641
// NewDefault creates a new [Default] handler.
@@ -45,6 +50,7 @@ func NewDefault(conf *DefaultConfig) (d *Default) {
4550
return &Default{
4651
logger: conf.Logger,
4752
isIPv6Halted: conf.HaltIPv6,
53+
isIPv4Halted: conf.HaltIPv4,
4854
messages: mc,
4955
hosts: conf.HostsFiles,
5056
}
@@ -64,6 +70,10 @@ func (h *Default) HandleRequest(p *proxy.Proxy, proxyCtx *proxy.DNSContext) (err
6470
return nil
6571
}
6672

73+
if proxyCtx.Res = h.haltA(ctx, proxyCtx.Req); proxyCtx.Res != nil {
74+
return nil
75+
}
76+
6777
if proxyCtx.Res = h.resolveFromHosts(ctx, proxyCtx.Req); proxyCtx.Res != nil {
6878
return nil
6979
}

internal/handler/ipv4halt.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package handler
2+
3+
import (
4+
"context"
5+
6+
"github.com/miekg/dns"
7+
)
8+
9+
// haltA halts the processing of A requests if IPv4 is disabled. req must
10+
// not be nil.
11+
func (h *Default) haltA(ctx context.Context, req *dns.Msg) (resp *dns.Msg) {
12+
if h.isIPv4Halted && req.Question[0].Qtype == dns.TypeA {
13+
h.logger.DebugContext(
14+
ctx,
15+
"ipv4 is disabled; replying with empty response",
16+
"req", req.Question[0].Name,
17+
)
18+
19+
return h.messages.NewMsgNODATA(req)
20+
}
21+
22+
return nil
23+
}

0 commit comments

Comments
 (0)