Skip to content

Commit

Permalink
Merge branch 'master' into AG-20200-translation-script-update-auto
Browse files Browse the repository at this point in the history
  • Loading branch information
schzhn committed Mar 28, 2023
2 parents 207c8ba + 487675b commit 6e92a76
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 57 deletions.
55 changes: 31 additions & 24 deletions internal/aghnet/hostscontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (rm *requestMatcher) MatchRequest(
) (res *urlfilter.DNSResult, ok bool) {
switch req.DNSType {
case dns.TypeA, dns.TypeAAAA, dns.TypePTR:
log.Debug("%s: handling the request for %s", hostsContainerPref, req.Hostname)
log.Debug("%s: handling the request for %s", hostsContainerPrefix, req.Hostname)
default:
return nil, false
}
Expand Down Expand Up @@ -90,9 +90,9 @@ func (rm *requestMatcher) resetEng(rulesStrg *filterlist.RuleStorage, tr map[str
rm.translator = tr
}

// hostsContainerPref is a prefix for logging and wrapping errors in
// hostsContainerPrefix is a prefix for logging and wrapping errors in
// HostsContainer's methods.
const hostsContainerPref = "hosts container"
const hostsContainerPrefix = "hosts container"

// HostsContainer stores the relevant hosts database provided by the OS and
// processes both A/AAAA and PTR DNS requests for those.
Expand All @@ -115,8 +115,8 @@ type HostsContainer struct {
// fsys is the working file system to read hosts files from.
fsys fs.FS

// w tracks the changes in specified files and directories.
w aghos.FSWatcher
// watcher tracks the changes in specified files and directories.
watcher aghos.FSWatcher

// patterns stores specified paths in the fs.Glob-compatible form.
patterns []string
Expand Down Expand Up @@ -160,7 +160,7 @@ func NewHostsContainer(
w aghos.FSWatcher,
paths ...string,
) (hc *HostsContainer, err error) {
defer func() { err = errors.Annotate(err, "%s: %w", hostsContainerPref) }()
defer func() { err = errors.Annotate(err, "%s: %w", hostsContainerPrefix) }()

if len(paths) == 0 {
return nil, ErrNoHostsPaths
Expand All @@ -182,11 +182,11 @@ func NewHostsContainer(
done: make(chan struct{}, 1),
updates: make(chan HostsRecords, 1),
fsys: fsys,
w: w,
watcher: w,
patterns: patterns,
}

log.Debug("%s: starting", hostsContainerPref)
log.Debug("%s: starting", hostsContainerPrefix)

// Load initially.
if err = hc.refresh(); err != nil {
Expand All @@ -199,7 +199,7 @@ func NewHostsContainer(
return nil, fmt.Errorf("adding path: %w", err)
}

log.Debug("%s: %s is expected to exist but doesn't", hostsContainerPref, p)
log.Debug("%s: %s is expected to exist but doesn't", hostsContainerPrefix, p)
}
}

Expand All @@ -208,14 +208,21 @@ func NewHostsContainer(
return hc, nil
}

// Close implements the io.Closer interface for *HostsContainer. Close must
// only be called once. The returned err is always nil.
// Close implements the [io.Closer] interface for *HostsContainer. It closes
// both itself and its [aghos.FSWatcher]. Close must only be called once.
func (hc *HostsContainer) Close() (err error) {
log.Debug("%s: closing", hostsContainerPref)
log.Debug("%s: closing", hostsContainerPrefix)

err = hc.watcher.Close()
if err != nil {
err = fmt.Errorf("closing fs watcher: %w", err)

// Go on and close the container either way.
}

close(hc.done)

return nil
return err
}

// Upd returns the channel into which the updates are sent.
Expand Down Expand Up @@ -251,22 +258,22 @@ func pathsToPatterns(fsys fs.FS, paths []string) (patterns []string, err error)
// update channel of HostsContainer when finishes. It's used to be called
// within a separate goroutine.
func (hc *HostsContainer) handleEvents() {
defer log.OnPanic(fmt.Sprintf("%s: handling events", hostsContainerPref))
defer log.OnPanic(fmt.Sprintf("%s: handling events", hostsContainerPrefix))

defer close(hc.updates)

ok, eventsCh := true, hc.w.Events()
ok, eventsCh := true, hc.watcher.Events()
for ok {
select {
case _, ok = <-eventsCh:
if !ok {
log.Debug("%s: watcher closed the events channel", hostsContainerPref)
log.Debug("%s: watcher closed the events channel", hostsContainerPrefix)

continue
}

if err := hc.refresh(); err != nil {
log.Error("%s: %s", hostsContainerPref, err)
log.Error("%s: %s", hostsContainerPrefix, err)
}
case _, ok = <-hc.done:
// Go on.
Expand Down Expand Up @@ -345,7 +352,7 @@ func (hp *hostsParser) parseLine(line string) (ip netip.Addr, hosts []string) {
// TODO(e.burkov): Investigate if hosts may contain DNS-SD domains.
err = netutil.ValidateHostname(f)
if err != nil {
log.Error("%s: host %q is invalid, ignoring", hostsContainerPref, f)
log.Error("%s: host %q is invalid, ignoring", hostsContainerPrefix, f)

continue
}
Expand Down Expand Up @@ -389,7 +396,7 @@ func (hp *hostsParser) addRules(ip netip.Addr, host, line string) {
rule, rulePtr := hp.writeRules(host, ip)
hp.translations[rule], hp.translations[rulePtr] = line, line

log.Debug("%s: added ip-host pair %q-%q", hostsContainerPref, ip, host)
log.Debug("%s: added ip-host pair %q-%q", hostsContainerPrefix, ip, host)
}

// writeRules writes the actual rule for the qtype and the PTR for the host-ip
Expand Down Expand Up @@ -443,19 +450,19 @@ func (hp *hostsParser) writeRules(host string, ip netip.Addr) (rule, rulePtr str

// sendUpd tries to send the parsed data to the ch.
func (hp *hostsParser) sendUpd(ch chan HostsRecords) {
log.Debug("%s: sending upd", hostsContainerPref)
log.Debug("%s: sending upd", hostsContainerPrefix)

upd := hp.table
select {
case ch <- upd:
// Updates are delivered. Go on.
case <-ch:
ch <- upd
log.Debug("%s: replaced the last update", hostsContainerPref)
log.Debug("%s: replaced the last update", hostsContainerPrefix)
case ch <- upd:
// The previous update was just read and the next one pushed. Go on.
default:
log.Error("%s: the updates channel is broken", hostsContainerPref)
log.Error("%s: the updates channel is broken", hostsContainerPrefix)
}
}

Expand All @@ -473,7 +480,7 @@ func (hp *hostsParser) newStrg(id int) (s *filterlist.RuleStorage, err error) {
//
// TODO(e.burkov): Accept a parameter to specify the files to refresh.
func (hc *HostsContainer) refresh() (err error) {
log.Debug("%s: refreshing", hostsContainerPref)
log.Debug("%s: refreshing", hostsContainerPrefix)

hp := hc.newHostsParser()
if _, err = aghos.FileWalker(hp.parseFile).Walk(hc.fsys, hc.patterns...); err != nil {
Expand All @@ -482,7 +489,7 @@ func (hc *HostsContainer) refresh() (err error) {

// hc.last is nil on the first refresh, so let that one through.
if hc.last != nil && maps.EqualFunc(hp.table, hc.last, (*HostsRecord).equal) {
log.Debug("%s: no changes detected", hostsContainerPref)
log.Debug("%s: no changes detected", hostsContainerPrefix)

return nil
}
Expand Down
10 changes: 5 additions & 5 deletions internal/aghnet/hostscontainer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func TestNewHostsContainer(t *testing.T) {
hc, err := NewHostsContainer(0, testFS, &aghtest.FSWatcher{
OnEvents: onEvents,
OnAdd: onAdd,
OnClose: func() (err error) { panic("not implemented") },
OnClose: func() (err error) { return nil },
}, tc.paths...)
if tc.wantErr != nil {
require.ErrorIs(t, err, tc.wantErr)
Expand Down Expand Up @@ -124,7 +124,7 @@ func TestNewHostsContainer(t *testing.T) {
errWatcher := &aghtest.FSWatcher{
OnEvents: func() (e <-chan struct{}) { panic("not implemented") },
OnAdd: func(name string) (err error) { return errOnAdd },
OnClose: func() (err error) { panic("not implemented") },
OnClose: func() (err error) { return nil },
}

hc, err := NewHostsContainer(0, testFS, errWatcher, p)
Expand Down Expand Up @@ -155,7 +155,7 @@ func TestHostsContainer_refresh(t *testing.T) {

return nil
},
OnClose: func() (err error) { panic("not implemented") },
OnClose: func() (err error) { return nil },
}

hc, err := NewHostsContainer(0, testFS, w, "dir")
Expand Down Expand Up @@ -292,7 +292,7 @@ func TestHostsContainer_Translate(t *testing.T) {
stubWatcher := aghtest.FSWatcher{
OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil },
OnClose: func() (err error) { panic("not implemented") },
OnClose: func() (err error) { return nil },
}

require.NoError(t, fstest.TestFS(testdata, "etc_hosts"))
Expand Down Expand Up @@ -524,7 +524,7 @@ func TestHostsContainer(t *testing.T) {
stubWatcher := aghtest.FSWatcher{
OnEvents: func() (e <-chan struct{}) { return nil },
OnAdd: func(name string) (err error) { return nil },
OnClose: func() (err error) { panic("not implemented") },
OnClose: func() (err error) { return nil },
}

hc, err := NewHostsContainer(listID, testdata, &stubWatcher, "etc_hosts")
Expand Down
46 changes: 18 additions & 28 deletions internal/home/home.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,10 @@ type homeContext struct {
filters *filtering.DNSFilter // DNS filtering module
web *Web // Web (HTTP, HTTPS) module
tls *tlsManager // TLS module
// etcHosts is an IP-hostname pairs set taken from system configuration
// (e.g. /etc/hosts) files.

// etcHosts contains IP-hostname mappings taken from the OS-specific hosts
// configuration files, for example /etc/hosts.
etcHosts *aghnet.HostsContainer
// hostsWatcher is the watcher to detect changes in the hosts files.
hostsWatcher aghos.FSWatcher

updater *updater.Updater

Expand All @@ -80,7 +79,6 @@ type homeContext struct {
pidFileName string // PID file name. Empty if no PID file was created.
controlLock sync.Mutex
tlsRoots *x509.CertPool // list of root CAs for TLSv1.2
transport *http.Transport
client *http.Client
appSignalChannel chan os.Signal // Channel for receiving OS signals by the console app

Expand Down Expand Up @@ -150,18 +148,17 @@ func setupContext(opts options) {
setupContextFlags(opts)

Context.tlsRoots = aghtls.SystemRootCAs()
Context.transport = &http.Transport{
DialContext: customDialContext,
Proxy: getHTTPProxy,
TLSClientConfig: &tls.Config{
RootCAs: Context.tlsRoots,
CipherSuites: Context.tlsCipherIDs,
MinVersion: tls.VersionTLS12,
},
}
Context.client = &http.Client{
Timeout: time.Minute * 5,
Transport: Context.transport,
Timeout: time.Minute * 5,
Transport: &http.Transport{
DialContext: customDialContext,
Proxy: getHTTPProxy,
TLSClientConfig: &tls.Config{
RootCAs: Context.tlsRoots,
CipherSuites: Context.tlsCipherIDs,
MinVersion: tls.VersionTLS12,
},
},
}

if !Context.firstRun {
Expand Down Expand Up @@ -264,26 +261,26 @@ func configureOS(conf *configuration) (err error) {
// setupHostsContainer initializes the structures to keep up-to-date the hosts
// provided by the OS.
func setupHostsContainer() (err error) {
Context.hostsWatcher, err = aghos.NewOSWritesWatcher()
hostsWatcher, err := aghos.NewOSWritesWatcher()
if err != nil {
return fmt.Errorf("initing hosts watcher: %w", err)
}

Context.etcHosts, err = aghnet.NewHostsContainer(
filtering.SysHostsListID,
aghos.RootDirFS(),
Context.hostsWatcher,
hostsWatcher,
aghnet.DefaultHostsPaths()...,
)
if err != nil {
cerr := Context.hostsWatcher.Close()
if errors.Is(err, aghnet.ErrNoHostsPaths) && cerr == nil {
closeErr := hostsWatcher.Close()
if errors.Is(err, aghnet.ErrNoHostsPaths) && closeErr == nil {
log.Info("warning: initing hosts container: %s", err)

return nil
}

return errors.WithDeferred(fmt.Errorf("initing hosts container: %w", err), cerr)
return errors.WithDeferred(fmt.Errorf("initing hosts container: %w", err), closeErr)
}

return nil
Expand Down Expand Up @@ -755,13 +752,6 @@ func cleanup(ctx context.Context) {
}

if Context.etcHosts != nil {
// Currently Context.hostsWatcher is only used in Context.etcHosts and
// needs closing only in case of the successful initialization of
// Context.etcHosts.
if err = Context.hostsWatcher.Close(); err != nil {
log.Error("closing hosts watcher: %s", err)
}

if err = Context.etcHosts.Close(); err != nil {
log.Error("closing hosts container: %s", err)
}
Expand Down

0 comments on commit 6e92a76

Please sign in to comment.