Skip to content

Commit

Permalink
Pull request: all: imp cyclo in new code
Browse files Browse the repository at this point in the history
Updates AdguardTeam#2646,

Squashed commit of the following:

commit af6a6fa
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon May 31 20:00:36 2021 +0300

    all: imp code, docs

commit 1cd4781
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date:   Mon May 31 18:51:23 2021 +0300

    all: imp cyclo in new code
  • Loading branch information
ainar-g committed May 31, 2021
1 parent c95acf7 commit e17e1f2
Show file tree
Hide file tree
Showing 10 changed files with 209 additions and 188 deletions.
79 changes: 40 additions & 39 deletions internal/aghnet/etchostscontainer.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package aghnet

import (
"bufio"
"io"
"net"
"os"
"path/filepath"
Expand Down Expand Up @@ -231,40 +230,53 @@ func (ehc *EtcHostsContainer) updateTableRev(tableRev map[string][]string, newHo
log.Debug("etchostscontainer: added reverse-address %s -> %s", ipStr, newHost)
}

// Read IP-hostname pairs from file
// Multiple hostnames per line (per one IP) is supported.
func (ehc *EtcHostsContainer) load(table map[string][]net.IP, tableRev map[string][]string, fn string) {
// parseHostsLine parses hosts from the fields.
func parseHostsLine(fields []string) (hosts []string) {
for _, f := range fields {
hashIdx := strings.IndexByte(f, '#')
if hashIdx == 0 {
// The rest of the fields are a part of the comment.
// Skip immediately.
return
} else if hashIdx > 0 {
// Only a part of the field is a comment.
hosts = append(hosts, f[:hashIdx])

return hosts
}

hosts = append(hosts, f)
}

return hosts
}

// load reads IP-hostname pairs from the hosts file. Multiple hostnames per
// line for one IP are supported.
func (ehc *EtcHostsContainer) load(
table map[string][]net.IP,
tableRev map[string][]string,
fn string,
) {
f, err := os.Open(fn)
if err != nil {
log.Error("etchostscontainer: %s", err)

return
}

defer func() {
derr := f.Close()
if derr != nil {
log.Error("etchostscontainer: closing file: %s", err)
}
}()

r := bufio.NewReader(f)
log.Debug("etchostscontainer: loading hosts from file %s", fn)

for done := false; !done; {
var line string
line, err = r.ReadString('\n')
if err == io.EOF {
done = true
} else if err != nil {
log.Error("etchostscontainer: %s", err)

return
}

line = strings.TrimSpace(line)
if len(line) == 0 || line[0] == '#' {
continue
}

s := bufio.NewScanner(f)
for s.Scan() {
line := strings.TrimSpace(s.Text())
fields := strings.Fields(line)
if len(fields) < 2 {
continue
Expand All @@ -275,28 +287,17 @@ func (ehc *EtcHostsContainer) load(table map[string][]net.IP, tableRev map[strin
continue
}

for i := 1; i != len(fields); i++ {
host := fields[i]
if len(host) == 0 {
break
}

sharp := strings.IndexByte(host, '#')
if sharp == 0 {
// Skip the comments.
break
} else if sharp > 0 {
host = host[:sharp]
}

hosts := parseHostsLine(fields[1:])
for _, host := range hosts {
ehc.updateTable(table, host, ip)
ehc.updateTableRev(tableRev, host, ip)
if sharp >= 0 {
// Skip the comments again.
break
}
}
}

err = s.Err()
if err != nil {
log.Error("etchostscontainer: %s", err)
}
}

// onlyWrites is a filter for (*fsnotify.Watcher).Events.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ func prepareTestFile(t *testing.T) (f *os.File) {
dir := t.TempDir()

f, err := os.CreateTemp(dir, "")
require.Nil(t, err)
require.NoError(t, err)
require.NotNil(t, f)

t.Cleanup(func() {
assert.Nil(t, f.Close())
assert.NoError(t, f.Close())
})

return f
Expand All @@ -37,7 +38,7 @@ func assertWriting(t *testing.T, f *os.File, strs ...string) {

for _, str := range strs {
n, err := f.WriteString(str)
require.Nil(t, err)
require.NoError(t, err)
assert.Equal(t, n, len(str))
}
}
Expand Down Expand Up @@ -77,16 +78,16 @@ func TestEtcHostsContainerResolution(t *testing.T) {
t.Run("ptr", func(t *testing.T) {
testCases := []struct {
wantIP string
wantLen int
wantHost string
wantLen int
}{
{wantIP: "127.0.0.1", wantLen: 2, wantHost: "host"},
{wantIP: "::1", wantLen: 1, wantHost: "localhost"},
{wantIP: "127.0.0.1", wantHost: "host", wantLen: 2},
{wantIP: "::1", wantHost: "localhost", wantLen: 1},
}

for _, tc := range testCases {
a, err := dns.ReverseAddr(tc.wantIP)
require.Nil(t, err)
require.NoError(t, err)

a = strings.TrimSuffix(a, ".")
hosts := ehc.ProcessReverse(a, dns.TypePTR)
Expand Down Expand Up @@ -114,7 +115,7 @@ func TestEtcHostsContainerFSNotify(t *testing.T) {
t.Cleanup(ehc.Close)

assertWriting(t, f, "127.0.0.2 newhost\n")
require.Nil(t, f.Sync())
require.NoError(t, f.Sync())

// Wait until fsnotify has triggerred and processed the
// file-modification event.
Expand Down
49 changes: 25 additions & 24 deletions internal/aghnet/net_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,40 +68,41 @@ func ifaceHasStaticIP(ifaceName string) (has bool, err error) {
return false, ErrNoStaticIPInfo
}

// findIfaceLine scans s until it finds the line that declares an interface with
// the given name. If findIfaceLine can't find the line, it returns false.
func findIfaceLine(s *bufio.Scanner, name string) (ok bool) {
for s.Scan() {
line := strings.TrimSpace(s.Text())
fields := strings.Fields(line)
if len(fields) == 2 && fields[0] == "interface" && fields[1] == name {
return true
}
}

return false
}

// dhcpcdStaticConfig checks if interface is configured by /etc/dhcpcd.conf to
// have a static IP.
func dhcpcdStaticConfig(r io.Reader, ifaceName string) (has bool, err error) {
s := bufio.NewScanner(r)
var withinInterfaceCtx bool
ifaceFound := findIfaceLine(s, ifaceName)
if !ifaceFound {
return false, s.Err()
}

for s.Scan() {
line := strings.TrimSpace(s.Text())

if withinInterfaceCtx && len(line) == 0 {
// An empty line resets our state.
withinInterfaceCtx = false
}

if len(line) == 0 || line[0] == '#' {
continue
}

fields := strings.Fields(line)

if withinInterfaceCtx {
if len(fields) >= 2 && fields[0] == "static" && strings.HasPrefix(fields[1], "ip_address=") {
return true, nil
}
if len(fields) > 0 && fields[0] == "interface" {
// Another interface found.
withinInterfaceCtx = false
}
continue
if len(fields) >= 2 &&
fields[0] == "static" &&
strings.HasPrefix(fields[1], "ip_address=") {
return true, s.Err()
}

if len(fields) == 2 && fields[0] == "interface" && fields[1] == ifaceName {
// The interface found.
withinInterfaceCtx = true
if len(fields) > 0 && fields[0] == "interface" {
// Another interface found.
break
}
}

Expand Down
13 changes: 0 additions & 13 deletions internal/aghnet/systemresolvers.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package aghnet
import (
"time"

"github.com/AdguardTeam/golibs/errors"
"github.com/AdguardTeam/golibs/log"
)

Expand All @@ -25,18 +24,6 @@ type SystemResolvers interface {
refresh() (err error)
}

const (
// errBadAddrPassed is returned when dialFunc can't parse an IP address.
errBadAddrPassed errors.Error = "the passed string is not a valid IP address"

// errFakeDial is an error which dialFunc is expected to return.
errFakeDial errors.Error = "this error signals the successful dialFunc work"

// errUnexpectedHostFormat is returned by validateDialedHost when the host has
// more than one percent sign.
errUnexpectedHostFormat errors.Error = "unexpected host format"
)

// refreshWithTicker refreshes the cache of sr after each tick form tickCh.
func refreshWithTicker(sr SystemResolvers, tickCh <-chan time.Time) {
defer log.OnPanic("systemResolvers")
Expand Down
12 changes: 12 additions & 0 deletions internal/aghnet/systemresolvers_others.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ type systemResolvers struct {
addrsLock sync.RWMutex
}

const (
// errBadAddrPassed is returned when dialFunc can't parse an IP address.
errBadAddrPassed errors.Error = "the passed string is not a valid IP address"

// errFakeDial is an error which dialFunc is expected to return.
errFakeDial errors.Error = "this error signals the successful dialFunc work"

// errUnexpectedHostFormat is returned by validateDialedHost when the host has
// more than one percent sign.
errUnexpectedHostFormat errors.Error = "unexpected host format"
)

func (sr *systemResolvers) refresh() (err error) {
defer func() { err = errors.Annotate(err, "systemResolvers: %w") }()

Expand Down
Loading

0 comments on commit e17e1f2

Please sign in to comment.