Skip to content

Commit 9ab4c0b

Browse files
committed
Restore the ability to forward to non-standard ports
Older versions of dnscrypt-proxy allowed to include an optional port number to forward to, but this was not supported any more since version 2.1.6. Restore this ability. Fixes #2802
1 parent c1d8e5c commit 9ab4c0b

2 files changed

Lines changed: 41 additions & 8 deletions

File tree

dnscrypt-proxy/example-forwarding-rules.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
## Forward queries to a resolver using IPv6
3939
# ipv6.example.com [2001:DB8::42]
4040

41+
## Forward to a non-standard port number
42+
# x.example.com 192.168.0.1:1053
43+
# y.example.com [2001:DB8::42]:1053
44+
4145
## Forward queries for .onion names to a local Tor client
4246
## Tor must be configured with the following in the torrc file:
4347
## DNSPort 9053

dnscrypt-proxy/plugin_forward.go

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -102,14 +102,9 @@ func (plugin *PluginForward) Init(proxy *Proxy) error {
102102
dlog.Criticalf("Unknown keyword [%s] at line %d", server, 1+lineNo)
103103
continue
104104
}
105-
server = strings.TrimPrefix(server, "[")
106-
server = strings.TrimSuffix(server, "]")
107-
if ip := net.ParseIP(server); ip != nil {
108-
if ip.To4() != nil {
109-
server = fmt.Sprintf("%s:%d", server, 53)
110-
} else {
111-
server = fmt.Sprintf("[%s]:%d", server, 53)
112-
}
105+
if server, err = normalizeIPAndOptionalPort(server, "53"); err != nil {
106+
dlog.Criticalf("Syntax error for a forwarding rule at line %d: %s", 1+lineNo, err)
107+
continue
113108
}
114109
idxServers := -1
115110
for i, item := range sequence {
@@ -252,3 +247,37 @@ func (plugin *PluginForward) Eval(pluginsState *PluginsState, msg *dns.Msg) erro
252247
}
253248
return err
254249
}
250+
251+
func normalizeIPAndOptionalPort(addr string, defaultPort string) (string, error) {
252+
var host, port string
253+
var err error
254+
255+
if strings.HasPrefix(addr, "[") {
256+
if !strings.Contains(addr, "]:") {
257+
if addr[len(addr)-1] != ']' {
258+
return "", fmt.Errorf("invalid IPv6 format: missing closing ']'")
259+
}
260+
host = addr[1 : len(addr)-1]
261+
port = defaultPort
262+
} else {
263+
host, port, err = net.SplitHostPort(addr)
264+
if err != nil {
265+
return "", err
266+
}
267+
}
268+
} else {
269+
host, port, err = net.SplitHostPort(addr)
270+
if err != nil {
271+
host = addr
272+
port = defaultPort
273+
}
274+
}
275+
ip := net.ParseIP(host)
276+
if ip == nil {
277+
return "", fmt.Errorf("invalid IP address: [%s]", host)
278+
}
279+
if ip.To4() != nil {
280+
return fmt.Sprintf("%s:%s", ip.String(), port), nil
281+
}
282+
return fmt.Sprintf("[%s]:%s", ip.String(), port), nil
283+
}

0 commit comments

Comments
 (0)