Skip to content

Commit

Permalink
Merge branch 'master' into 2305-limit-message-size
Browse files Browse the repository at this point in the history
  • Loading branch information
EugeneOne1 committed Nov 19, 2020
2 parents 7b77c2c + 62a8fe0 commit bbd1d49
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 43 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ jobs:
steps:
- uses: actions/checkout@v2
- name: golangci-lint
uses: golangci/golangci-lint-action@v1
uses: golangci/golangci-lint-action@v2.3.0
with:
# Required: the version of golangci-lint is required and must be specified without patch version: we always use the latest patch version.
version: v1.27
version: v1.32

eslint:
runs-on: ubuntu-latest
Expand Down
37 changes: 33 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,46 @@ and this project adheres to

## [Unreleased]



## [v0.104.3] - 2020-11-19

### Fixed

- The accidentally exposed profiler HTTP API ([#2336]).

[#2336]: https://github.com/AdguardTeam/AdGuardHome/issues/2336



## [v0.104.2] - 2020-11-19

### Added

- This changelog :-) (#2294).
- This changelog :-) ([#2294]).
- `HACKING.md`, a guide for developers.

### Changed

- Improved tests output (#2273).
- Improved tests output ([#2273]).

### Fixed

- Query logs from file not loading after the ones buffered in memory ([#2325]).
- Unnecessary errors in query logs when switching between log files ([#2324]).
- `404 Not Found` errors on the DHCP settings page on *Windows*. The page now
correctly shows that DHCP is not currently available on that OS (#2295).
- Infinite loop in `/dhcp/find_active_dhcp` (#2301).
correctly shows that DHCP is not currently available on that OS ([#2295]).
- Infinite loop in `/dhcp/find_active_dhcp` ([#2301]).

[#2273]: https://github.com/AdguardTeam/AdGuardHome/issues/2273
[#2294]: https://github.com/AdguardTeam/AdGuardHome/issues/2294
[#2295]: https://github.com/AdguardTeam/AdGuardHome/issues/2295
[#2301]: https://github.com/AdguardTeam/AdGuardHome/issues/2301
[#2324]: https://github.com/AdguardTeam/AdGuardHome/issues/2324
[#2325]: https://github.com/AdguardTeam/AdGuardHome/issues/2325



[Unreleased]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.104.3...HEAD
[v0.104.3]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.104.2...v0.104.3
[v0.104.2]: https://github.com/AdguardTeam/AdGuardHome/compare/v0.104.1...v0.104.2
4 changes: 2 additions & 2 deletions client/src/components/Settings/Dhcp/Interfaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,12 @@ const Interfaces = () => {
(store) => store.form[FORM_NAME.DHCP_INTERFACES]?.values?.interface_name,
);

const interfaceValue = interface_name && interfaces[interface_name];

if (processingInterfaces || !interfaces) {
return null;
}

const interfaceValue = interface_name && interfaces[interface_name];

return <div className="row dhcp__interfaces">
<div className="col col__dhcp">
<Field
Expand Down
2 changes: 1 addition & 1 deletion internal/agherr/agherr_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func TestError_Unwrap(t *testing.T) {
)
errs := []error{
errSimple: errors.New("a"),
errWrapped: fmt.Errorf("%w", errors.New("nested")),
errWrapped: fmt.Errorf("err: %w", errors.New("nested")),
errNil: nil,
}
testCases := []struct {
Expand Down
18 changes: 18 additions & 0 deletions internal/home/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net"
"net/http"
"strconv"
"strings"
"sync"

"github.com/AdguardTeam/AdGuardHome/internal/util"
Expand Down Expand Up @@ -141,6 +142,7 @@ func (web *Web) Start() {
web.httpServer = &http.Server{
ErrorLog: web.errLogger,
Addr: address,
Handler: filterPPROF(http.DefaultServeMux),
}
err := web.httpServer.ListenAndServe()
if err != http.ErrServerClosed {
Expand All @@ -151,6 +153,22 @@ func (web *Web) Start() {
}
}

// TODO(a.garipov): We currently have to use this, because everything registers
// its HTTP handlers in http.DefaultServeMux. In the future, refactor our HTTP
// API initialization process and stop using the gosh darn http.DefaultServeMux
// for anything at all. Gosh darn global variables.
func filterPPROF(h http.Handler) (filtered http.Handler) {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if strings.HasPrefix(r.URL.Path, "/debug/pprof") {
http.NotFound(w, r)

return
}

h.ServeHTTP(w, r)
})
}

// Close - stop HTTP server, possibly waiting for all active connections to be closed
func (web *Web) Close() {
log.Info("Stopping HTTP server...")
Expand Down
37 changes: 20 additions & 17 deletions internal/querylog/qlog_file.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package querylog

import (
"fmt"
"io"
"os"
"sync"
Expand All @@ -10,12 +11,12 @@ import (
"github.com/AdguardTeam/golibs/log"
)

// ErrSeekNotFound is returned from Seek if when it fails to find the requested
// record.
const ErrSeekNotFound agherr.Error = "seek: record not found"

// ErrEndOfLog is returned from Seek when the end of the current log is reached.
const ErrEndOfLog agherr.Error = "seek: end of log"
// Timestamp not found errors.
const (
ErrTSNotFound agherr.Error = "ts not found"
ErrTSTooLate agherr.Error = "ts too late"
ErrTSTooEarly agherr.Error = "ts too early"
)

// TODO: Find a way to grow buffer instead of relying on this value when reading strings
const maxEntrySize = 16 * 1024
Expand Down Expand Up @@ -68,7 +69,7 @@ func NewQLogFile(path string) (*QLogFile, error) {
// * It returns the position of the the line with the timestamp we were looking for
// so that when we call "ReadNext" this line was returned.
// * Depth of the search (how many times we compared timestamps).
// * If we could not find it, it returns ErrSeekNotFound
// * If we could not find it, it returns one of the errors described above.
func (q *QLogFile) Seek(timestamp int64) (int64, int, error) {
q.lock.Lock()
defer q.lock.Unlock()
Expand Down Expand Up @@ -103,23 +104,26 @@ func (q *QLogFile) Seek(timestamp int64) (int64, int, error) {
return 0, depth, err
}

if lineIdx < start || lineEndIdx > end || lineIdx == lastProbeLineIdx {
if lineIdx == lastProbeLineIdx {
if lineIdx == 0 {
return 0, depth, ErrTSTooEarly
}

// If we're testing the same line twice then most likely
// the scope is too narrow and we won't find anything anymore
log.Error("querylog: didn't find timestamp:%v", timestamp)
return 0, depth, ErrSeekNotFound
} else if lineIdx == end && lineEndIdx == end {
return 0, depth, ErrEndOfLog
// the scope is too narrow and we won't find anything
// anymore in any other file.
return 0, depth, fmt.Errorf("looking up timestamp %d in %q: %w", timestamp, q.file.Name(), ErrTSNotFound)
} else if lineIdx == fileInfo.Size() {
return 0, depth, ErrTSTooLate
}

// Save the last found idx
lastProbeLineIdx = lineIdx

// Get the timestamp from the query log record
ts := readQLogTimestamp(line)

if ts == 0 {
return 0, depth, ErrSeekNotFound
return 0, depth, fmt.Errorf("looking up timestamp %d in %q: record %q has empty timestamp", timestamp, q.file.Name(), line)
}

if ts == timestamp {
Expand All @@ -141,8 +145,7 @@ func (q *QLogFile) Seek(timestamp int64) (int64, int, error) {

depth++
if depth >= 100 {
log.Error("Seek depth is too high, aborting. File %s, ts %v", q.file.Name(), timestamp)
return 0, depth, ErrSeekNotFound
return 0, depth, fmt.Errorf("looking up timestamp %d in %q: depth %d too high: %w", timestamp, q.file.Name(), depth, ErrTSNotFound)
}
}

Expand Down
37 changes: 33 additions & 4 deletions internal/querylog/qlog_file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -243,10 +243,10 @@ func prepareTestFiles(dir string, filesCount, linesCount int) []string {
lineTime, _ := time.Parse(time.RFC3339Nano, "2020-02-18T22:36:35.920973+03:00")
lineIP := uint32(0)

files := make([]string, 0)
files := make([]string, filesCount)
for j := 0; j < filesCount; j++ {
f, _ := ioutil.TempFile(dir, "*.txt")
files = append(files, f.Name())
files[filesCount-j-1] = f.Name()

for i := 0; i < linesCount; i++ {
lineIP += 1
Expand Down Expand Up @@ -289,7 +289,7 @@ func TestQLogSeek(t *testing.T) {
assert.Equal(t, 1, depth)
}

func TestQLogSeek_ErrEndOfLog(t *testing.T) {
func TestQLogSeek_ErrTSTooLate(t *testing.T) {
testDir := prepareTestDir()
t.Cleanup(func() {
_ = os.RemoveAll(testDir)
Expand All @@ -314,6 +314,35 @@ func TestQLogSeek_ErrEndOfLog(t *testing.T) {
assert.Nil(t, err)

_, depth, err := q.Seek(target.UnixNano() + int64(time.Second))
assert.Equal(t, ErrEndOfLog, err)
assert.Equal(t, ErrTSTooLate, err)
assert.Equal(t, 2, depth)
}

func TestQLogSeek_ErrTSTooEarly(t *testing.T) {
testDir := prepareTestDir()
t.Cleanup(func() {
_ = os.RemoveAll(testDir)
})

d := `{"T":"2020-08-31T18:44:23.911246629+03:00","QH":"wfqvjymurpwegyv","QT":"A","QC":"IN","CP":"","Answer":"","Result":{},"Elapsed":66286385,"Upstream":"tls://dns-unfiltered.adguard.com:853"}
{"T":"2020-08-31T18:44:25.376690873+03:00"}
{"T":"2020-08-31T18:44:25.382540454+03:00"}
`
f, err := ioutil.TempFile(testDir, "*.txt")
assert.Nil(t, err)
defer f.Close()

_, err = f.WriteString(d)
assert.Nil(t, err)

q, err := NewQLogFile(f.Name())
assert.Nil(t, err)
defer q.Close()

target, err := time.Parse(time.RFC3339, "2020-08-31T18:44:23.911246629+03:00")
assert.Nil(t, err)

_, depth, err := q.Seek(target.UnixNano() - int64(time.Second))
assert.Equal(t, ErrTSTooEarly, err)
assert.Equal(t, 1, depth)
}
29 changes: 20 additions & 9 deletions internal/querylog/qlog_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package querylog

import (
"errors"
"fmt"
"io"

"github.com/AdguardTeam/AdGuardHome/internal/agherr"
Expand Down Expand Up @@ -49,22 +50,32 @@ func NewQLogReader(files []string) (*QLogReader, error) {
//
// Returns nil if the record is successfully found.
// Returns an error if for some reason we could not find a record with the specified timestamp.
func (r *QLogReader) Seek(timestamp int64) error {
func (r *QLogReader) Seek(timestamp int64) (err error) {
for i := len(r.qFiles) - 1; i >= 0; i-- {
q := r.qFiles[i]
_, _, err := q.Seek(timestamp)
if err == nil || errors.Is(err, ErrEndOfLog) {
// Our search is finished, and we either found the
// element we were looking for or reached the end of the
// log. Update currentFile only, position is already
// set properly in QLogFile.
_, _, err = q.Seek(timestamp)
if err == nil {
// Search is finished, and the searched element have
// been found. Update currentFile only, position is
// already set properly in QLogFile.
r.currentFile = i

return err
return nil
} else if errors.Is(err, ErrTSTooEarly) {
// Look at the next file, since we've reached the end of
// this one.
continue
} else if errors.Is(err, ErrTSTooLate) {
// Just seek to the start then. timestamp is probably
// between the end of the previous one and the start of
// this one.
return r.SeekStart()
} else if errors.Is(err, ErrTSNotFound) {
break
}
}

return ErrSeekNotFound
return fmt.Errorf("querylog: %w", err)
}

// SeekStart changes the current position to the end of the newest file
Expand Down
Loading

0 comments on commit bbd1d49

Please sign in to comment.