Pull request 2064: AG-23599 Upd proxy

Merge in DNS/adguard-home from AG-23599-upd-proxy to master

Squashed commit of the following:

commit 31a4da2fe425d648a94f13060e8786ffae0be3ca
Merge: 2c2fb253d 94bceaa84
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Nov 16 13:37:55 2023 +0300

    Merge branch 'master' into AG-23599-upd-proxy

commit 2c2fb253d489baa6b97a524b7e3327676ee6aa6f
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Nov 15 19:03:20 2023 +0300

    dnsforward: imp code

commit 7384365758f80753cc4234184e7bd7311a85435d
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Nov 14 17:02:07 2023 +0300

    all: imp code

commit 9c0be82285eed0602f593f805cfb7d02ace17a64
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Fri Nov 10 20:21:00 2023 +0300

    all: imp code, docs

commit 5a47875882b5afd0264e4d473e884843745ff3f4
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Thu Nov 9 16:50:51 2023 +0300

    all: upd proxy
This commit is contained in:
Eugene Burkov
2023-11-16 14:05:10 +03:00
parent 94bceaa84d
commit 9b91a87406
19 changed files with 443 additions and 346 deletions

View File

@@ -126,7 +126,13 @@ func (clients *clientsContainer) Init(
return nil
}
if clients.etcHosts != nil {
// The clients.etcHosts may be nil even if config.Clients.Sources.HostsFile
// is true, because of the deprecated option --no-etc-hosts.
//
// TODO(e.burkov): The option should probably be returned, since hosts file
// currently used not only for clients' information enrichment, but also in
// the filtering module and upstream addresses resolution.
if config.Clients.Sources.HostsFile && clients.etcHosts != nil {
go clients.handleHostsUpdates()
}
@@ -419,11 +425,14 @@ func (clients *clientsContainer) shouldCountClient(ids []string) (y bool) {
return true
}
// findUpstreams returns upstreams configured for the client, identified either
// by its IP address or its ClientID. upsConf is nil if the client isn't found
// or if the client has no custom upstreams.
func (clients *clientsContainer) findUpstreams(
// type check
var _ dnsforward.ClientsContainer = (*clientsContainer)(nil)
// UpstreamConfigByID implements the [dnsforward.ClientsContainer] interface for
// *clientsContainer.
func (clients *clientsContainer) UpstreamConfigByID(
id string,
bootstrap upstream.Resolver,
) (upsConf *proxy.UpstreamConfig, err error) {
clients.lock.Lock()
defer clients.lock.Unlock()
@@ -431,6 +440,8 @@ func (clients *clientsContainer) findUpstreams(
c, ok := clients.findLocked(id)
if !ok {
return nil, nil
} else if c.upstreamConfig != nil {
return c.upstreamConfig, nil
}
upstreams := stringutil.FilterOut(c.Upstreams, dnsforward.IsCommentOrEmpty)
@@ -438,21 +449,18 @@ func (clients *clientsContainer) findUpstreams(
return nil, nil
}
if c.upstreamConfig != nil {
return c.upstreamConfig, nil
}
var conf *proxy.UpstreamConfig
conf, err = proxy.ParseUpstreamsConfig(
upstreams,
&upstream.Options{
Bootstrap: config.DNS.BootstrapDNS,
Bootstrap: bootstrap,
Timeout: config.DNS.UpstreamTimeout.Duration,
HTTPVersions: dnsforward.UpstreamHTTPVersions(config.DNS.UseHTTP3Upstreams),
PreferIPv6: config.DNS.BootstrapPreferIPv6,
},
)
if err != nil {
// Don't wrap the error since it's informative enough as is.
return nil, err
}
@@ -672,10 +680,6 @@ func (clients *clientsContainer) Del(name string) (ok bool) {
return false
}
if err := c.closeUpstreams(); err != nil {
log.Error("client container: removing client %s: %s", name, err)
}
clients.del(c)
return true
@@ -683,10 +687,14 @@ func (clients *clientsContainer) Del(name string) (ok bool) {
// del removes c from the indexes. clients.lock is expected to be locked.
func (clients *clientsContainer) del(c *Client) {
// update Name index
if err := c.closeUpstreams(); err != nil {
log.Error("client container: removing client %s: %s", c.Name, err)
}
// Update the name index.
delete(clients.list, c.Name)
// update ID index
// Update the ID index.
for _, id := range c.IDs {
delete(clients.idIndex, id)
}

View File

@@ -355,11 +355,11 @@ func TestClientsCustomUpstream(t *testing.T) {
require.NoError(t, err)
assert.True(t, ok)
config, err := clients.findUpstreams("1.2.3.4")
config, err := clients.UpstreamConfigByID("1.2.3.4", net.DefaultResolver)
assert.Nil(t, config)
assert.NoError(t, err)
config, err = clients.findUpstreams("1.1.1.1")
config, err = clients.UpstreamConfigByID("1.1.1.1", net.DefaultResolver)
require.NotNil(t, config)
assert.NoError(t, err)
assert.Len(t, config.Upstreams, 1)

View File

@@ -138,8 +138,9 @@ func initDNSServer(
QueryLog: qlog,
PrivateNets: privateNets,
Anonymizer: anonymizer,
LocalDomain: config.DHCP.LocalDomainName,
DHCPServer: dhcpSrv,
EtcHosts: Context.etcHosts,
LocalDomain: config.DHCP.LocalDomainName,
})
if err != nil {
closeDNSServer()
@@ -288,7 +289,7 @@ func newServerConfig(
newConf.TLSAllowUnencryptedDoH = tlsConf.AllowUnencryptedDoH
newConf.FilterHandler = applyAdditionalFiltering
newConf.GetCustomUpstreamByClient = Context.clients.findUpstreams
newConf.ClientsContainer = &Context.clients
newConf.LocalPTRResolvers = dnsConf.LocalPTRResolvers
newConf.UpstreamTimeout = dnsConf.UpstreamTimeout.Duration

View File

@@ -6,7 +6,6 @@ import (
"crypto/x509"
"fmt"
"io/fs"
"net"
"net/http"
"net/netip"
"net/url"
@@ -160,7 +159,7 @@ func setupContext(opts options) (err error) {
os.Exit(0)
}
if !opts.noEtcHosts && config.Clients.Sources.HostsFile {
if !opts.noEtcHosts {
err = setupHostsContainer()
if err != nil {
// Don't wrap the error, because it's informative enough as is.
@@ -239,13 +238,13 @@ func setupHostsContainer() (err error) {
)
if err != nil {
closeErr := hostsWatcher.Close()
if errors.Is(err, aghnet.ErrNoHostsPaths) && closeErr == nil {
if errors.Is(err, aghnet.ErrNoHostsPaths) {
log.Info("warning: initing hosts container: %s", err)
return nil
return closeErr
}
return errors.WithDeferred(fmt.Errorf("initing hosts container: %w", err), closeErr)
return errors.Join(fmt.Errorf("initializing hosts container: %w", err), closeErr)
}
return nil
@@ -294,19 +293,13 @@ func initContextClients() (err error) {
arpDB = arpdb.New()
}
err = Context.clients.Init(
return Context.clients.Init(
config.Clients.Persistent,
Context.dhcpServer,
Context.etcHosts,
arpDB,
config.Filtering,
)
if err != nil {
// Don't wrap the error, because it's informative enough as is.
return err
}
return nil
}
// setupBindOpts overrides bind host/port from the opts.
@@ -376,11 +369,15 @@ func setupDNSFilteringConf(conf *filtering.Config) (err error) {
upsOpts := &upstream.Options{
Timeout: dnsTimeout,
ServerIPAddrs: []net.IP{
{94, 140, 14, 15},
{94, 140, 15, 16},
net.ParseIP("2a10:50c0::bad1:ff"),
net.ParseIP("2a10:50c0::bad2:ff"),
Bootstrap: upstream.StaticResolver{
// 94.140.14.15.
netip.AddrFrom4([4]byte{94, 140, 14, 15}),
// 94.140.14.16.
netip.AddrFrom4([4]byte{94, 140, 14, 16}),
// 2a10:50c0::bad1:ff.
netip.AddrFrom16([16]byte{42, 16, 80, 192, 12: 186, 209, 0, 255}),
// 2a10:50c0::bad2:ff.
netip.AddrFrom16([16]byte{42, 16, 80, 192, 12: 186, 210, 0, 255}),
},
}