Skip to content

Commit

Permalink
Merge branch 'master' into 3020-client-sources
Browse files Browse the repository at this point in the history
  • Loading branch information
ainar-g committed Apr 25, 2022
2 parents 41fb071 + 0a1ff65 commit f8e6b6d
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 69 deletions.
1 change: 1 addition & 0 deletions .github/stale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
- 'documentation'
- 'enhancement'
- 'feature request'
- 'help wanted'
- 'localization'
- 'needs investigation'
- 'recurrent'
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ In this release, the schema version has changed from 12 to 14.

### Fixed

- Slow version update queries making other HTTP APIs unresponsible ([#4499]).
- ARP tables refreshing process causing excessive PTR requests ([#3157]).

[#1730]: https://github.com/AdguardTeam/AdGuardHome/issues/1730
Expand All @@ -140,6 +141,7 @@ In this release, the schema version has changed from 12 to 14.
[#4221]: https://github.com/AdguardTeam/AdGuardHome/issues/4221
[#4238]: https://github.com/AdguardTeam/AdGuardHome/issues/4238
[#4276]: https://github.com/AdguardTeam/AdGuardHome/issues/4276
[#4499]: https://github.com/AdguardTeam/AdGuardHome/issues/4499

[repr]: https://reproducible-builds.org/docs/source-date-epoch/
[doq-draft-10]: https://datatracker.ietf.org/doc/html/draft-ietf-dprive-dnsoquic-10#section-10.2
Expand Down
2 changes: 1 addition & 1 deletion client/src/__locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"bootstrap_dns": "Bootstrap DNS servers",
"bootstrap_dns_desc": "Bootstrap DNS servers are used to resolve IP addresses of the DoH/DoT resolvers you specify as upstreams.",
"local_ptr_title": "Private reverse DNS servers",
"local_ptr_desc": "The DNS servers that AdGuard Home uses for local PTR queries. These servers are used to resolve the hostnames of clients with private IP addresses, for example \"192.168.12.34\", using reverse DNS. If not set, AdGuard Home uses the addresses of the default DNS resolvers of your OS except for the addresses of AdGuard Home itself.",
"local_ptr_desc": "The DNS servers that AdGuard Home uses for local PTR queries. These servers are used to resolve PTR requests for addresses in private IP ranges, for example \"192.168.12.34\", using reverse DNS. If not set, AdGuard Home uses the addresses of the default DNS resolvers of your OS except for the addresses of AdGuard Home itself.",
"local_ptr_default_resolver": "By default, AdGuard Home uses the following reverse DNS resolvers: {{ip}}.",
"local_ptr_no_default_resolver": "AdGuard Home could not determine suitable private reverse DNS resolvers for this system.",
"local_ptr_placeholder": "Enter one server address per line",
Expand Down
29 changes: 19 additions & 10 deletions client/src/components/Logs/InfiniteTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ const InfiniteTable = ({

useEffect(() => {
listener();
}, [items.length < QUERY_LOGS_PAGE_LIMIT]);
}, [items.length < QUERY_LOGS_PAGE_LIMIT, isEntireLog]);

useEffect(() => {
const THROTTLE_TIME = 100;
Expand All @@ -66,15 +66,24 @@ const InfiniteTable = ({

const isNothingFound = items.length === 0 && !processingGetLogs;

return <div className='logs__table' role='grid'>
{loading && <Loading />}
<Header />
{isNothingFound
? <label className="logs__no-data">{t('nothing_found')}</label>
: <>{items.map(renderRow)}
{!isEntireLog && <div ref={loader} className="logs__loading text-center">{t('loading_table_status')}</div>}
</>}
</div>;
return (
<div className="logs__table" role="grid">
{loading && <Loading />}
<Header />
{isNothingFound ? (
<label className="logs__no-data">{t('nothing_found')}</label>
) : (
<>
{items.map(renderRow)}
{!isEntireLog && (
<div ref={loader} className="logs__loading text-center">
{t('loading_table_status')}
</div>
)}
</>
)}
</div>
);
};

InfiniteTable.propTypes = {
Expand Down
4 changes: 2 additions & 2 deletions client/src/helpers/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -693,8 +693,8 @@ export const replaceZeroWithEmptyString = (value) => (parseInt(value, 10) === 0
* @returns {string}
*/
export const getLogsUrlParams = (search, response_status) => `?${queryString.stringify({
search,
response_status,
search: search || undefined,
response_status: response_status || undefined,
})}`;

export const processContent = (
Expand Down
4 changes: 2 additions & 2 deletions internal/aghnet/net_nolinux.go → internal/aghnet/net_bsd.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build !linux
// +build !linux
//go:build darwin || freebsd || openbsd
// +build darwin freebsd openbsd

package aghnet

Expand Down
8 changes: 6 additions & 2 deletions internal/aghnet/net_windows.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//go:build !(linux || darwin || freebsd || openbsd)
// +build !linux,!darwin,!freebsd,!openbsd
//go:build windows
// +build windows

package aghnet

Expand All @@ -13,6 +13,10 @@ import (
"golang.org/x/sys/windows"
)

func canBindPrivilegedPorts() (can bool, err error) {
return true, nil
}

func ifaceHasStaticIP(string) (ok bool, err error) {
return false, aghos.Unsupported("checking static ip")
}
Expand Down
114 changes: 64 additions & 50 deletions internal/home/controlupdate.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package home
import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"os/exec"
Expand All @@ -27,12 +28,16 @@ type temporaryError interface {

// Get the latest available version from the Internet
func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")

resp := &versionResponse{}
if Context.disableUpdate {
// w.Header().Set("Content-Type", "application/json")
resp.Disabled = true
_ = json.NewEncoder(w).Encode(resp)
// TODO(e.burkov): Add error handling and deal with headers.
err := json.NewEncoder(w).Encode(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "writing body: %s", err)
}

return
}

Expand All @@ -44,30 +49,48 @@ func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) {
if r.ContentLength != 0 {
err = json.NewDecoder(r.Body).Decode(req)
if err != nil {
aghhttp.Error(r, w, http.StatusBadRequest, "JSON parse: %s", err)
aghhttp.Error(r, w, http.StatusBadRequest, "parsing request: %s", err)

return
}
}

for i := 0; i != 3; i++ {
func() {
Context.controlLock.Lock()
defer Context.controlLock.Unlock()
err = requestVersionInfo(resp, req.Recheck)
if err != nil {
// Don't wrap the error, because it's informative enough as is.
aghhttp.Error(r, w, http.StatusBadGateway, "%s", err)

return
}

resp.VersionInfo, err = Context.updater.VersionInfo(req.Recheck)
}()
err = resp.setAllowedToAutoUpdate()
if err != nil {
// Don't wrap the error, because it's informative enough as is.
aghhttp.Error(r, w, http.StatusInternalServerError, "%s", err)

return
}

err = json.NewEncoder(w).Encode(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "writing body: %s", err)
}
}

// requestVersionInfo sets the VersionInfo field of resp if it can reach the
// update server.
func requestVersionInfo(resp *versionResponse, recheck bool) (err error) {
for i := 0; i != 3; i++ {
resp.VersionInfo, err = Context.updater.VersionInfo(recheck)
if err != nil {
var terr temporaryError
if errors.As(err, &terr) && terr.Temporary() {
// Temporary network error. This case may happen while
// we're restarting our DNS server. Log and sleep for
// some time.
// Temporary network error. This case may happen while we're
// restarting our DNS server. Log and sleep for some time.
//
// See https://github.com/AdguardTeam/AdGuardHome/issues/934.
d := time.Duration(i) * time.Second
log.Info("temp net error: %q; sleeping for %s and retrying", err, d)
log.Info("update: temp net error: %q; sleeping for %s and retrying", err, d)
time.Sleep(d)

continue
Expand All @@ -76,29 +99,14 @@ func handleGetVersionJSON(w http.ResponseWriter, r *http.Request) {

break
}

if err != nil {
vcu := Context.updater.VersionCheckURL()
// TODO(a.garipov): Figure out the purpose of %T verb.
aghhttp.Error(
r,
w,
http.StatusBadGateway,
"Couldn't get version check json from %s: %T %s\n",
vcu,
err,
err,
)

return
return fmt.Errorf("getting version info from %s: %s", vcu, err)
}

resp.confirmAutoUpdate()

w.Header().Set("Content-Type", "application/json")
err = json.NewEncoder(w).Encode(resp)
if err != nil {
aghhttp.Error(r, w, http.StatusInternalServerError, "Couldn't write body: %s", err)
}
return nil
}

// handleUpdate performs an update to the latest available version procedure.
Expand Down Expand Up @@ -132,31 +140,37 @@ func handleUpdate(w http.ResponseWriter, r *http.Request) {

// versionResponse is the response for /control/version.json endpoint.
type versionResponse struct {
Disabled bool `json:"disabled"`
updater.VersionInfo
Disabled bool `json:"disabled"`
}

// confirmAutoUpdate checks the real possibility of auto update.
func (vr *versionResponse) confirmAutoUpdate() {
if vr.CanAutoUpdate != nil && *vr.CanAutoUpdate {
canUpdate := true
// setAllowedToAutoUpdate sets CanAutoUpdate to true if AdGuard Home is actually
// allowed to perform an automatic update by the OS.
func (vr *versionResponse) setAllowedToAutoUpdate() (err error) {
if vr.CanAutoUpdate == nil || !*vr.CanAutoUpdate {
return
}

var tlsConf *tlsConfigSettings
if runtime.GOOS != "windows" {
tlsConf = &tlsConfigSettings{}
Context.tls.WriteDiskConfig(tlsConf)
}
tlsConf := &tlsConfigSettings{}
Context.tls.WriteDiskConfig(tlsConf)

if tlsConf != nil &&
((tlsConf.Enabled && (tlsConf.PortHTTPS < 1024 ||
tlsConf.PortDNSOverTLS < 1024 ||
tlsConf.PortDNSOverQUIC < 1024)) ||
config.BindPort < 1024 ||
config.DNS.Port < 1024) {
canUpdate, _ = aghnet.CanBindPrivilegedPorts()
canUpdate := true
if tlsConfUsesPrivilegedPorts(tlsConf) || config.BindPort < 1024 || config.DNS.Port < 1024 {
canUpdate, err = aghnet.CanBindPrivilegedPorts()
if err != nil {
return fmt.Errorf("checking ability to bind privileged ports: %w", err)
}
vr.CanAutoUpdate = &canUpdate
}

vr.CanAutoUpdate = &canUpdate

return nil
}

// tlsConfUsesPrivilegedPorts returns true if the provided TLS configuration
// indicates that privileged ports are used.
func tlsConfUsesPrivilegedPorts(c *tlsConfigSettings) (ok bool) {
return c.Enabled && (c.PortHTTPS < 1024 || c.PortDNSOverTLS < 1024 || c.PortDNSOverQUIC < 1024)
}

// finishUpdate completes an update procedure.
Expand Down
2 changes: 1 addition & 1 deletion internal/updater/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ const versionCheckPeriod = 8 * time.Hour

// VersionInfo contains information about a new version.
type VersionInfo struct {
CanAutoUpdate *bool `json:"can_autoupdate,omitempty"`
NewVersion string `json:"new_version,omitempty"`
Announcement string `json:"announcement,omitempty"`
AnnouncementURL string `json:"announcement_url,omitempty"`
SelfUpdateMinVersion string `json:"-"`
CanAutoUpdate *bool `json:"can_autoupdate,omitempty"`
}

// MaxResponseSize is responses on server's requests maximum length in bytes.
Expand Down
1 change: 0 additions & 1 deletion scripts/make/go-lint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ underscores() {
-e '_freebsd.go'\
-e '_linux.go'\
-e '_little.go'\
-e '_nolinux.go'\
-e '_openbsd.go'\
-e '_others.go'\
-e '_test.go'\
Expand Down

0 comments on commit f8e6b6d

Please sign in to comment.