cherry-pick: aghnet: imp host validation for system resolvers
Updates #3022. Squashed commit of the following: commit 2f63b4e1765d9c9bfeadafcfa42c9d8741b628e1 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Wed Apr 28 21:29:28 2021 +0300 aghnet: fix doc commit efdc1bb2c8959a9f888d558c32c415e6f3678b0c Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Wed Apr 28 21:19:54 2021 +0300 all: doc changes commit 8154797095874771bcf04d109644e6ae33fcb470 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Wed Apr 28 21:15:42 2021 +0300 aghnet: imp host validation for system resolvers
This commit is contained in:
committed by
Ainar Garipov
parent
5b9bbce55d
commit
d59938d254
@@ -7,6 +7,7 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -35,7 +36,7 @@ func (sr *systemResolvers) refresh() (err error) {
|
||||
|
||||
_, err = sr.resolver.LookupHost(context.Background(), sr.hostGenFunc())
|
||||
dnserr := &net.DNSError{}
|
||||
if errors.As(err, &dnserr) && dnserr.Err == fakeDialErr.Error() {
|
||||
if errors.As(err, &dnserr) && dnserr.Err == errFakeDial.Error() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -58,19 +59,43 @@ func newSystemResolvers(refreshIvl time.Duration, hostGenFunc HostGenFunc) (sr S
|
||||
return s
|
||||
}
|
||||
|
||||
// validateDialedHost validated the host used by resolvers in dialFunc.
|
||||
func validateDialedHost(host string) (err error) {
|
||||
defer agherr.Annotate("parsing %q: %w", &err, host)
|
||||
|
||||
var ipStr string
|
||||
parts := strings.Split(host, "%")
|
||||
switch len(parts) {
|
||||
case 1:
|
||||
ipStr = host
|
||||
case 2:
|
||||
// Remove the zone and check the IP address part.
|
||||
ipStr = parts[0]
|
||||
default:
|
||||
return errUnexpectedHostFormat
|
||||
}
|
||||
|
||||
if net.ParseIP(ipStr) == nil {
|
||||
return errBadAddrPassed
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// dialFunc gets the resolver's address and puts it into internal cache.
|
||||
func (sr *systemResolvers) dialFunc(_ context.Context, _, address string) (_ net.Conn, err error) {
|
||||
// Just validate the passed address is a valid IP.
|
||||
var host string
|
||||
host, err = SplitHost(address)
|
||||
if err != nil {
|
||||
// TODO(e.burkov): Maybe use a structured badAddrPassedErr to
|
||||
// TODO(e.burkov): Maybe use a structured errBadAddrPassed to
|
||||
// allow unwrapping of the real error.
|
||||
return nil, fmt.Errorf("%s: %w", err, badAddrPassedErr)
|
||||
return nil, fmt.Errorf("%s: %w", err, errBadAddrPassed)
|
||||
}
|
||||
|
||||
if net.ParseIP(host) == nil {
|
||||
return nil, fmt.Errorf("parsing %q: %w", host, badAddrPassedErr)
|
||||
err = validateDialedHost(host)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("validating dialed host: %w", err)
|
||||
}
|
||||
|
||||
sr.addrsLock.Lock()
|
||||
@@ -78,7 +103,7 @@ func (sr *systemResolvers) dialFunc(_ context.Context, _, address string) (_ net
|
||||
|
||||
sr.addrs.Add(host)
|
||||
|
||||
return nil, fakeDialErr
|
||||
return nil, errFakeDial
|
||||
}
|
||||
|
||||
func (sr *systemResolvers) Get() (rs []string) {
|
||||
|
||||
Reference in New Issue
Block a user