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
This commit is contained in:
Frank Denis 2025-03-10 12:12:55 +01:00
parent c1d8e5cc57
commit 9ab4c0b339
2 changed files with 41 additions and 8 deletions

View file

@ -38,6 +38,10 @@
## Forward queries to a resolver using IPv6
# ipv6.example.com [2001:DB8::42]
## Forward to a non-standard port number
# x.example.com 192.168.0.1:1053
# y.example.com [2001:DB8::42]:1053
## Forward queries for .onion names to a local Tor client
## Tor must be configured with the following in the torrc file:
## DNSPort 9053

View file

@ -102,14 +102,9 @@ func (plugin *PluginForward) Init(proxy *Proxy) error {
dlog.Criticalf("Unknown keyword [%s] at line %d", server, 1+lineNo)
continue
}
server = strings.TrimPrefix(server, "[")
server = strings.TrimSuffix(server, "]")
if ip := net.ParseIP(server); ip != nil {
if ip.To4() != nil {
server = fmt.Sprintf("%s:%d", server, 53)
} else {
server = fmt.Sprintf("[%s]:%d", server, 53)
}
if server, err = normalizeIPAndOptionalPort(server, "53"); err != nil {
dlog.Criticalf("Syntax error for a forwarding rule at line %d: %s", 1+lineNo, err)
continue
}
idxServers := -1
for i, item := range sequence {
@ -252,3 +247,37 @@ func (plugin *PluginForward) Eval(pluginsState *PluginsState, msg *dns.Msg) erro
}
return err
}
func normalizeIPAndOptionalPort(addr string, defaultPort string) (string, error) {
var host, port string
var err error
if strings.HasPrefix(addr, "[") {
if !strings.Contains(addr, "]:") {
if addr[len(addr)-1] != ']' {
return "", fmt.Errorf("invalid IPv6 format: missing closing ']'")
}
host = addr[1 : len(addr)-1]
port = defaultPort
} else {
host, port, err = net.SplitHostPort(addr)
if err != nil {
return "", err
}
}
} else {
host, port, err = net.SplitHostPort(addr)
if err != nil {
host = addr
port = defaultPort
}
}
ip := net.ParseIP(host)
if ip == nil {
return "", fmt.Errorf("invalid IP address: [%s]", host)
}
if ip.To4() != nil {
return fmt.Sprintf("%s:%s", ip.String(), port), nil
}
return fmt.Sprintf("[%s]:%s", ip.String(), port), nil
}