mirror of
https://github.com/AdguardTeam/AdGuardHome.git
synced 2024-11-15 18:08:30 -07:00
Merge branch 'master' into AG-28327-upstream-config-parser
This commit is contained in:
commit
ccbbae6d61
65
CHANGELOG.md
65
CHANGELOG.md
@ -25,15 +25,80 @@ NOTE: Add new changes BELOW THIS COMMENT.
|
||||
|
||||
### Added
|
||||
|
||||
- Etc timezones to the timezone list ([#6568]).
|
||||
- The schema version of the configuration file to the output of running
|
||||
`AdGuardHome` (or `AdGuardHome.exe`) with `-v --version` command-line options
|
||||
([#6545]).
|
||||
- Ability to disable plain-DNS serving via UI if an encrypted protocol is
|
||||
already used ([#1660]).
|
||||
|
||||
### Changed
|
||||
|
||||
- The bootstrapped upstream addresses now updated according to the TTL of the
|
||||
bootstrap DNS response ([#6321]).
|
||||
- Logging level of timeout errors is now `error` instead of `debug` ([#6574]).
|
||||
- The field `"upstream_mode"` in `POST /control/dns_config` and
|
||||
`GET /control/dns_info` HTTP APIs now accepts `load_balance` value. Check
|
||||
`openapi/CHANGELOG.md` for more details.
|
||||
|
||||
#### Configuration changes
|
||||
|
||||
In this release, the schema version has changed from 27 to 28.
|
||||
|
||||
- The new property `clients.persistent.*.uid`, which is unique identifier of the
|
||||
persistent client.
|
||||
- The properties `dns.all_servers` and `dns.fastest_addr` were removed, their
|
||||
values migrated to newly added field `dns.upstream_mode` that describes the
|
||||
logic through which upstreams will be used. See also a [Wiki
|
||||
page][wiki-config].
|
||||
|
||||
```yaml
|
||||
# BEFORE:
|
||||
'dns':
|
||||
# …
|
||||
'all_servers': true
|
||||
'fastest_addr': true
|
||||
|
||||
# AFTER:
|
||||
'dns':
|
||||
# …
|
||||
'upstream_mode': 'parallel'
|
||||
```
|
||||
|
||||
To rollback this change, remove the new field `upstream_mode`, set back
|
||||
`dns.all_servers` and `dns.fastest_addr` properties in `dns` section, and
|
||||
change the `schema_version` back to `27`.
|
||||
|
||||
### Fixed
|
||||
|
||||
- Panic on using `--no-etc-hosts` flag ([#6644]).
|
||||
- Schedule display in the client settings after creating or updating.
|
||||
- Zero value in `querylog.size_memory` disables logging ([#6570]).
|
||||
- Non-anonymized IP addresses on the dashboard ([#6584]).
|
||||
- Maximum cache TTL requirement when editing minimum cache TTL in the Web UI
|
||||
([#6409]).
|
||||
- Load balancing algorithm stuck on a single server ([#6480]).
|
||||
- Statistics for 7 days displayed as 168 hours on the dashboard.
|
||||
- Pre-filling the Edit static lease window with data ([#6534]).
|
||||
- Names defined in the `/etc/hosts` for a single address family wrongly
|
||||
considered undefined for another family ([#6541]).
|
||||
- Omitted CNAME records in safe search results, which can cause YouTube to not
|
||||
work on iOS ([#6352]).
|
||||
|
||||
[#6321]: https://github.com/AdguardTeam/AdGuardHome/issues/6321
|
||||
[#6352]: https://github.com/AdguardTeam/AdGuardHome/issues/6352
|
||||
[#6409]: https://github.com/AdguardTeam/AdGuardHome/issues/6409
|
||||
[#6480]: https://github.com/AdguardTeam/AdGuardHome/issues/6480
|
||||
[#6534]: https://github.com/AdguardTeam/AdGuardHome/issues/6534
|
||||
[#6541]: https://github.com/AdguardTeam/AdGuardHome/issues/6541
|
||||
[#6545]: https://github.com/AdguardTeam/AdGuardHome/issues/6545
|
||||
[#6568]: https://github.com/AdguardTeam/AdGuardHome/issues/6568
|
||||
[#6570]: https://github.com/AdguardTeam/AdGuardHome/issues/6570
|
||||
[#6574]: https://github.com/AdguardTeam/AdGuardHome/issues/6574
|
||||
[#6584]: https://github.com/AdguardTeam/AdGuardHome/issues/6584
|
||||
[#6644]: https://github.com/AdguardTeam/AdGuardHome/issues/6644
|
||||
|
||||
[wiki-config]: https://github.com/AdguardTeam/AdGuardHome/wiki/Configuration
|
||||
|
||||
<!--
|
||||
NOTE: Add new changes ABOVE THIS COMMENT.
|
||||
|
17
README.md
17
README.md
@ -276,6 +276,15 @@ Open your terminal and execute these commands:
|
||||
git clone https://github.com/AdguardTeam/AdGuardHome
|
||||
cd AdGuardHome
|
||||
make
|
||||
```
|
||||
|
||||
#### <a href="#building-node" id="building-node" name="building-node">Building with Node.js 17 and later</a>
|
||||
|
||||
In order to build AdGuard Home with Node.js 17 and later, specify
|
||||
`--openssl-legacy-provider` option.
|
||||
|
||||
```sh
|
||||
export NODE_OPTIONS=--openssl-legacy-provider
|
||||
```
|
||||
|
||||
**NOTE:** The non-standard `-j` flag is currently not supported, so building
|
||||
@ -409,6 +418,7 @@ There are three options how you can install an unstable version:
|
||||
```sh
|
||||
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -c edge
|
||||
```
|
||||
|
||||
[wiki-platf]: https://github.com/AdguardTeam/AdGuardHome/wiki/Platforms
|
||||
|
||||
|
||||
@ -463,10 +473,6 @@ bug or implementing the feature.
|
||||
[@kongfl888](https://github.com/kongfl888) (originally by
|
||||
[@rufengsuixing](https://github.com/rufengsuixing)).
|
||||
|
||||
* [Prometheus exporter for AdGuard
|
||||
Home](https://github.com/ebrianne/adguard-exporter) by
|
||||
[@ebrianne](https://github.com/ebrianne).
|
||||
|
||||
* [Terminal-based, real-time traffic monitoring and statistics for your AdGuard Home
|
||||
instance](https://github.com/Lissy93/AdGuardian-Term) by
|
||||
[@Lissy93](https://github.com/Lissy93)
|
||||
@ -485,7 +491,8 @@ bug or implementing the feature.
|
||||
* [Node.js library](https://github.com/Andrea055/AdguardHomeAPI) by
|
||||
[@Andrea055](https://github.com/Andrea055/).
|
||||
|
||||
|
||||
* [Browser Extension](https://github.com/satheshshiva/Adguard-Home-Browser-Ext) by
|
||||
[@satheshshiva](https://github.com/satheshshiva/).
|
||||
|
||||
## <a href="#acknowledgments" id="acknowledgments" name="acknowledgments">Acknowledgments</a>
|
||||
|
||||
|
26
client/package-lock.json
generated
vendored
26
client/package-lock.json
generated
vendored
@ -11,6 +11,7 @@
|
||||
"@nivo/line": "^0.64.0",
|
||||
"axios": "^0.19.2",
|
||||
"classnames": "^2.2.6",
|
||||
"countries-and-timezones": "^3.6.0",
|
||||
"date-fns": "^1.29.0",
|
||||
"i18next": "^19.6.2",
|
||||
"i18next-browser-languagedetector": "^4.2.0",
|
||||
@ -37,7 +38,6 @@
|
||||
"redux-actions": "^2.6.5",
|
||||
"redux-form": "^8.3.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"timezones-list": "^3.0.2",
|
||||
"url-polyfill": "^1.1.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -5596,6 +5596,15 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/countries-and-timezones": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/countries-and-timezones/-/countries-and-timezones-3.6.0.tgz",
|
||||
"integrity": "sha512-8/nHBCs1eKeQ1jnsZVGdqrLYxS8nPcfJn8PnmxdJXWRLZdXsGFR8gnVhRjatGDBjqmPm7H+FtYpBYTPWd0Eiqg==",
|
||||
"engines": {
|
||||
"node": ">=8.x",
|
||||
"npm": ">=5.x"
|
||||
}
|
||||
},
|
||||
"node_modules/create-ecdh": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
|
||||
@ -18881,11 +18890,6 @@
|
||||
"node": ">=0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/timezones-list": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/timezones-list/-/timezones-list-3.0.2.tgz",
|
||||
"integrity": "sha512-I698hm6Jp/xxkwyTSOr39pZkYKETL8LDJeSIhjxXBfPUAHM5oZNuQ4o9UK3PSkDBOkjATecSOBb3pR1IkIBUsg=="
|
||||
},
|
||||
"node_modules/tiny-invariant": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
|
||||
@ -25268,6 +25272,11 @@
|
||||
"yaml": "^1.7.2"
|
||||
}
|
||||
},
|
||||
"countries-and-timezones": {
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/countries-and-timezones/-/countries-and-timezones-3.6.0.tgz",
|
||||
"integrity": "sha512-8/nHBCs1eKeQ1jnsZVGdqrLYxS8nPcfJn8PnmxdJXWRLZdXsGFR8gnVhRjatGDBjqmPm7H+FtYpBYTPWd0Eiqg=="
|
||||
},
|
||||
"create-ecdh": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
|
||||
@ -35674,11 +35683,6 @@
|
||||
"setimmediate": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"timezones-list": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/timezones-list/-/timezones-list-3.0.2.tgz",
|
||||
"integrity": "sha512-I698hm6Jp/xxkwyTSOr39pZkYKETL8LDJeSIhjxXBfPUAHM5oZNuQ4o9UK3PSkDBOkjATecSOBb3pR1IkIBUsg=="
|
||||
},
|
||||
"tiny-invariant": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz",
|
||||
|
2
client/package.json
vendored
2
client/package.json
vendored
@ -16,6 +16,7 @@
|
||||
"@nivo/line": "^0.64.0",
|
||||
"axios": "^0.19.2",
|
||||
"classnames": "^2.2.6",
|
||||
"countries-and-timezones": "^3.6.0",
|
||||
"date-fns": "^1.29.0",
|
||||
"i18next": "^19.6.2",
|
||||
"i18next-browser-languagedetector": "^4.2.0",
|
||||
@ -42,7 +43,6 @@
|
||||
"redux-actions": "^2.6.5",
|
||||
"redux-form": "^8.3.5",
|
||||
"redux-thunk": "^2.3.0",
|
||||
"timezones-list": "^3.0.2",
|
||||
"url-polyfill": "^1.1.9"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -36,7 +36,7 @@ const Examples = () => (
|
||||
<Trans
|
||||
components={[
|
||||
<a
|
||||
href="https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists"
|
||||
href="https://link.adtidy.org/forward.html?action=dns_kb_filtering_syntax&from=ui&app=home"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
key="0"
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React from 'react';
|
||||
import timezones from 'timezones-list';
|
||||
import ct from 'countries-and-timezones';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
@ -15,6 +15,8 @@ export const Timezone = ({
|
||||
setTimezone(event.target.value);
|
||||
};
|
||||
|
||||
const timezones = ct.getAllTimezones();
|
||||
|
||||
return (
|
||||
<div className="schedule__timezone">
|
||||
<label className="form__label form__label--with-desc mb-2">
|
||||
@ -30,9 +32,9 @@ export const Timezone = ({
|
||||
{t('schedule_timezone')}
|
||||
</option>
|
||||
{/* TODO: get timezones from backend method when the method is ready */}
|
||||
{timezones.map((zone) => (
|
||||
<option key={zone.name} value={zone.tzCode}>
|
||||
{zone.label}
|
||||
{Object.keys(timezones).map((zone) => (
|
||||
<option key={zone} value={zone}>
|
||||
{zone} (GMT{timezones[zone].utcOffsetStr})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
@ -21,10 +21,7 @@ export const ScheduleForm = ({
|
||||
const onModalOpen = () => setModalOpen(true);
|
||||
const onModalClose = () => setModalOpen(false);
|
||||
|
||||
const filteredScheduleKeys = useMemo(() => (
|
||||
schedule ? Object.keys(schedule).filter((v) => v !== 'time_zone') : []
|
||||
), [schedule]);
|
||||
|
||||
const filteredScheduleKeys = schedule ? Object.keys(schedule).filter((v) => v !== 'time_zone') : [];
|
||||
const scheduleMap = new Map();
|
||||
filteredScheduleKeys.forEach((day) => scheduleMap.set(day, schedule[day]));
|
||||
|
||||
|
@ -162,7 +162,7 @@ let Form = (props) => {
|
||||
const [activeTabLabel, setActiveTabLabel] = useState('settings');
|
||||
|
||||
const handleScheduleSubmit = (values) => {
|
||||
change('blocked_services_schedule', values);
|
||||
change('blocked_services_schedule', { ...values });
|
||||
};
|
||||
|
||||
const tabs = {
|
||||
@ -371,7 +371,7 @@ let Form = (props) => {
|
||||
</div>
|
||||
<div className="form__desc mt-0 mb-2">
|
||||
<Trans components={[
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists#ctag"
|
||||
<a target="_blank" rel="noopener noreferrer" href="https://link.adtidy.org/forward.html?action=dns_kb_filtering_syntax_ctag&from=ui&app=home"
|
||||
key="0">link</a>,
|
||||
]}>
|
||||
tags_desc
|
||||
|
@ -3,7 +3,7 @@ import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import ReactTable from 'react-table';
|
||||
import { Trans, withTranslation } from 'react-i18next';
|
||||
import { LEASES_TABLE_DEFAULT_PAGE_SIZE } from '../../../helpers/constants';
|
||||
import { LEASES_TABLE_DEFAULT_PAGE_SIZE, MODAL_TYPE } from '../../../helpers/constants';
|
||||
import { sortIp } from '../../../helpers/helpers';
|
||||
import { toggleLeaseModal } from '../../../actions';
|
||||
|
||||
@ -18,7 +18,10 @@ class Leases extends Component {
|
||||
|
||||
convertToStatic = (data) => () => {
|
||||
const { dispatch } = this.props;
|
||||
dispatch(toggleLeaseModal(data));
|
||||
dispatch(toggleLeaseModal({
|
||||
type: MODAL_TYPE.ADD_LEASE,
|
||||
config: data,
|
||||
}));
|
||||
}
|
||||
|
||||
makeStatic = ({ row }) => {
|
||||
|
@ -41,7 +41,7 @@ const Form = ({
|
||||
cache_ttl_max, cache_ttl_min,
|
||||
} = useSelector((state) => state.form[FORM_NAME.CACHE].values, shallowEqual);
|
||||
|
||||
const minExceedsMax = cache_ttl_min > cache_ttl_max;
|
||||
const minExceedsMax = cache_ttl_min > 0 && cache_ttl_max > 0 && cache_ttl_min > cache_ttl_max;
|
||||
|
||||
const handleClearCache = () => {
|
||||
if (window.confirm(t('confirm_dns_cache_clear'))) {
|
||||
|
@ -181,6 +181,7 @@ export const MODAL_TYPE = {
|
||||
ADD_REWRITE: 'ADD_REWRITE',
|
||||
EDIT_REWRITE: 'EDIT_REWRITE',
|
||||
EDIT_LEASE: 'EDIT_LEASE',
|
||||
ADD_LEASE: 'ADD_LEASE',
|
||||
};
|
||||
|
||||
export const CLIENT_ID = {
|
||||
@ -435,7 +436,7 @@ export const SCHEME_TO_PROTOCOL_MAP = {
|
||||
export const DNS_REQUEST_OPTIONS = {
|
||||
PARALLEL: 'parallel',
|
||||
FASTEST_ADDR: 'fastest_addr',
|
||||
LOAD_BALANCING: '',
|
||||
LOAD_BALANCING: 'load_balance',
|
||||
};
|
||||
|
||||
export const DHCP_FORM_NAMES = {
|
||||
|
@ -142,11 +142,11 @@ export default {
|
||||
"homepage": "https://github.com/AdguardTeam/AdGuardSDNSFilter",
|
||||
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt"
|
||||
},
|
||||
"adway_default_blocklist": {
|
||||
"name": "AdAway Default Blocklist",
|
||||
"awavenue_ads_rule": {
|
||||
"name": "AWAvenue Ads Rule",
|
||||
"categoryId": "general",
|
||||
"homepage": "https://github.com/AdAway/adaway.github.io/",
|
||||
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt"
|
||||
"homepage": "https://awavenue.top/",
|
||||
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_53.txt"
|
||||
},
|
||||
"curben_phishing_filter": {
|
||||
"name": "Phishing URL Blocklist (PhishTank and OpenPhish)",
|
||||
@ -190,6 +190,12 @@ export default {
|
||||
"homepage": "https://github.com/hagezi/dns-blocklists#piracy",
|
||||
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_46.txt"
|
||||
},
|
||||
"hagezi_dyndns_blocklist": {
|
||||
"name": "HaGeZi's DynDNS Blocklist",
|
||||
"categoryId": "security",
|
||||
"homepage": "https://github.com/hagezi/dns-blocklists",
|
||||
"source": "https://adguardteam.github.io/HostlistsRegistry/assets/filter_54.txt"
|
||||
},
|
||||
"hagezi_encrypted_dns_vpn_tor_proxy_bypass": {
|
||||
"name": "HaGeZi's Encrypted DNS/VPN/TOR/Proxy Bypass",
|
||||
"categoryId": "security",
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"timeUpdated": "2023-12-01T15:24:07.522Z",
|
||||
"timeUpdated": "2024-01-22T00:10:10.554Z",
|
||||
"categories": {
|
||||
"0": "audio_video_player",
|
||||
"1": "comments",
|
||||
@ -10758,9 +10758,10 @@
|
||||
},
|
||||
"localytics": {
|
||||
"name": "Localytics",
|
||||
"categoryId": 6,
|
||||
"url": "http://www.localytics.com/",
|
||||
"companyId": "localytics"
|
||||
"categoryId": 101,
|
||||
"url": "https://uplandsoftware.com/localytics/",
|
||||
"companyId": "upland",
|
||||
"source": "AdGuard"
|
||||
},
|
||||
"lockerdome": {
|
||||
"name": "LockerDome",
|
||||
@ -15613,10 +15614,11 @@
|
||||
"companyId": "sharecompany"
|
||||
},
|
||||
"sharepoint": {
|
||||
"name": "Microsoft SharePoint",
|
||||
"categoryId": 2,
|
||||
"url": "https://products.office.com/en-us/sharepoint/sharepoint-online-collaboration-software",
|
||||
"companyId": "microsoft"
|
||||
"name": "SharePoint",
|
||||
"categoryId": 8,
|
||||
"url": "https://www.microsoft.com/microsoft-365/sharepoint/collaboration",
|
||||
"companyId": "microsoft",
|
||||
"source": "AdGuard"
|
||||
},
|
||||
"sharethis": {
|
||||
"name": "ShareThis",
|
||||
@ -22958,6 +22960,7 @@
|
||||
"loadercdn.com": "loadercdn.com",
|
||||
"loadsource.org": "loadsource.org",
|
||||
"web.localytics.com": "localytics",
|
||||
"localytics.com": "localytics",
|
||||
"cdn2.lockerdome.com": "lockerdome",
|
||||
"addtoany.com": "lockerz_share",
|
||||
"pixel.loganmedia.mobi": "logan_media",
|
||||
@ -23254,6 +23257,7 @@
|
||||
"k-msedge.net": "msedge",
|
||||
"l-msedge.net": "msedge",
|
||||
"s-msedge.net": "msedge",
|
||||
"spo-msedge.net": "msedge",
|
||||
"t-msedge.net": "msedge",
|
||||
"wac-msedge.net": "msedge",
|
||||
"msn.com": "msn",
|
||||
@ -23521,8 +23525,10 @@
|
||||
"outbrain.com": "outbrain",
|
||||
"outbrainimg.com": "outbrain",
|
||||
"live.com": "outlook",
|
||||
"cloud.microsoft": "outlook",
|
||||
"hotmail.com": "outlook",
|
||||
"outlook.com": "outlook",
|
||||
"svc.ms": "outlook",
|
||||
"overheat.it": "overheat.it",
|
||||
"oewabox.at": "owa",
|
||||
"owneriq.net": "owneriq",
|
||||
@ -23790,6 +23796,7 @@
|
||||
"rcsmediagroup.it": "rcs.it",
|
||||
"d335luupugsy2.cloudfront.net": "rd_station",
|
||||
"rea-group.com": "rea_group",
|
||||
"reagroupdata.com.au": "rea_group",
|
||||
"reastatic.net": "rea_group",
|
||||
"d12ulf131zb0yj.cloudfront.net": "reachforce",
|
||||
"reachforce.com": "reachforce",
|
||||
@ -24109,6 +24116,8 @@
|
||||
"quintrics.nl": "sharecompany",
|
||||
"sharecompany.nl": "sharecompany",
|
||||
"sharepointonline.com": "sharepoint",
|
||||
"onmicrosoft.com": "sharepoint",
|
||||
"sharepoint.com": "sharepoint",
|
||||
"sharethis.com": "sharethis",
|
||||
"shareth.ru": "sharethrough",
|
||||
"sharethrough.com": "sharethrough",
|
||||
|
@ -128,7 +128,8 @@ const dhcp = handleActions(
|
||||
const newState = {
|
||||
...state,
|
||||
isModalOpen: !state.isModalOpen,
|
||||
leaseModalConfig: payload,
|
||||
modalType: payload?.type || '',
|
||||
leaseModalConfig: payload?.config,
|
||||
};
|
||||
return newState;
|
||||
},
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { handleActions } from 'redux-actions';
|
||||
|
||||
import * as actions from '../actions/dnsConfig';
|
||||
import { ALL_INTERFACES_IP, BLOCKING_MODES } from '../helpers/constants';
|
||||
import { ALL_INTERFACES_IP, BLOCKING_MODES, DNS_REQUEST_OPTIONS } from '../helpers/constants';
|
||||
|
||||
const DEFAULT_BLOCKING_IPV4 = ALL_INTERFACES_IP;
|
||||
const DEFAULT_BLOCKING_IPV6 = '::';
|
||||
@ -15,6 +15,7 @@ const dnsConfig = handleActions(
|
||||
blocking_ipv4,
|
||||
blocking_ipv6,
|
||||
upstream_dns,
|
||||
upstream_mode,
|
||||
fallback_dns,
|
||||
bootstrap_dns,
|
||||
local_ptr_upstreams,
|
||||
@ -33,6 +34,7 @@ const dnsConfig = handleActions(
|
||||
local_ptr_upstreams: (local_ptr_upstreams && local_ptr_upstreams.join('\n')) || '',
|
||||
ratelimit_whitelist: (ratelimit_whitelist && ratelimit_whitelist.join('\n')) || '',
|
||||
processingGetConfig: false,
|
||||
upstream_mode: upstream_mode === '' ? DNS_REQUEST_OPTIONS.LOAD_BALANCING : upstream_mode,
|
||||
};
|
||||
},
|
||||
|
||||
|
34
go.mod
34
go.mod
@ -3,12 +3,13 @@ module github.com/AdguardTeam/AdGuardHome
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
github.com/AdguardTeam/dnsproxy v0.60.2-0.20240111154045-f9e73722f6d8
|
||||
github.com/AdguardTeam/golibs v0.18.0
|
||||
github.com/AdguardTeam/dnsproxy v0.64.0
|
||||
github.com/AdguardTeam/golibs v0.19.0
|
||||
github.com/AdguardTeam/urlfilter v0.17.3
|
||||
github.com/NYTimes/gziphandler v1.1.1
|
||||
github.com/ameshkov/dnscrypt/v2 v2.2.7
|
||||
github.com/bluele/gcache v0.0.2
|
||||
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500
|
||||
github.com/digineo/go-ipset/v2 v2.2.1
|
||||
github.com/dimfeld/httptreemux/v5 v5.5.0
|
||||
github.com/fsnotify/fsnotify v1.7.0
|
||||
@ -16,7 +17,7 @@ require (
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/google/gopacket v1.1.19
|
||||
github.com/google/renameio/v2 v2.0.0
|
||||
github.com/google/uuid v1.4.0
|
||||
github.com/google/uuid v1.5.0
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2
|
||||
github.com/josharian/native v1.1.1-0.20230202152459-5c7d0dd6ab86
|
||||
github.com/kardianos/service v1.2.2
|
||||
@ -26,15 +27,15 @@ require (
|
||||
// TODO(a.garipov): This package is deprecated; find a new one or use our
|
||||
// own code for that. Perhaps, use gopacket.
|
||||
github.com/mdlayher/raw v0.1.0
|
||||
github.com/miekg/dns v1.1.57
|
||||
github.com/miekg/dns v1.1.58
|
||||
github.com/quic-go/quic-go v0.40.0
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/ti-mo/netfilter v0.5.1
|
||||
go.etcd.io/bbolt v1.3.8
|
||||
golang.org/x/crypto v0.16.0
|
||||
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb
|
||||
golang.org/x/net v0.19.0
|
||||
golang.org/x/sys v0.15.0
|
||||
golang.org/x/crypto v0.18.0
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a
|
||||
golang.org/x/net v0.20.0
|
||||
golang.org/x/sys v0.16.0
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
howett.net/plist v1.0.1
|
||||
@ -47,20 +48,21 @@ require (
|
||||
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
|
||||
github.com/google/pprof v0.0.0-20231205033806-a5a03c77bf08 // indirect
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 // indirect
|
||||
// TODO(a.garipov): Upgrade to v0.5.0 once we switch to Go 1.21+.
|
||||
github.com/mdlayher/socket v0.4.1 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.13.2 // indirect
|
||||
github.com/mdlayher/socket v0.5.0 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.19 // indirect
|
||||
github.com/pierrec/lz4/v4 v4.1.21 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/quic-go/qpack v0.4.0 // indirect
|
||||
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
|
||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 // indirect
|
||||
go.uber.org/mock v0.3.0 // indirect
|
||||
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e // indirect
|
||||
go.uber.org/mock v0.4.0 // indirect
|
||||
golang.org/x/mod v0.14.0 // indirect
|
||||
golang.org/x/sync v0.5.0 // indirect
|
||||
golang.org/x/sync v0.6.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/tools v0.16.0 // indirect
|
||||
golang.org/x/tools v0.17.0 // indirect
|
||||
gonum.org/v1/gonum v0.14.0 // indirect
|
||||
)
|
||||
|
70
go.sum
70
go.sum
@ -1,7 +1,7 @@
|
||||
github.com/AdguardTeam/dnsproxy v0.60.2-0.20240111154045-f9e73722f6d8 h1:KuObu+oJf2UNxrdEB5NLUgaA8psetrXZMpxCA/znHsE=
|
||||
github.com/AdguardTeam/dnsproxy v0.60.2-0.20240111154045-f9e73722f6d8/go.mod h1:B7FvvTFQZBfey1cJXQo732EyCLX6xj4JqrciCawATzg=
|
||||
github.com/AdguardTeam/golibs v0.18.0 h1:ckS2YK7t2Ub6UkXl0fnreVaM15Zb07Hh1gmFqttjpWg=
|
||||
github.com/AdguardTeam/golibs v0.18.0/go.mod h1:DKhCIXHcUYtBhU8ibTLKh1paUL96n5zhQBlx763sj+U=
|
||||
github.com/AdguardTeam/dnsproxy v0.64.0 h1:AwUrUwUZHr+d2xTlkW+FK+7HdsYFCoLM6ytt1R1O3xs=
|
||||
github.com/AdguardTeam/dnsproxy v0.64.0/go.mod h1:dRRAFOjrq4QYM92jGs4lt4BoY0Dm3EY3HkaleoM2Feo=
|
||||
github.com/AdguardTeam/golibs v0.19.0 h1:y/x+Xn3pDg1ZfQ+QEZapPJqaeVYUIMp/EODMtVhn7PM=
|
||||
github.com/AdguardTeam/golibs v0.19.0/go.mod h1:3WunclLLfrVAq7fYQRhd6f168FHOEMssnipVXCxDL/w=
|
||||
github.com/AdguardTeam/urlfilter v0.17.3 h1:fg/ObbnO0Cv6aw0tW6N/ETDMhhNvmcUUOZ7HlmKC3rw=
|
||||
github.com/AdguardTeam/urlfilter v0.17.3/go.mod h1:Jru7jFfeH2CoDf150uDs+rRYcZBzHHBz05r9REyDKyE=
|
||||
github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I=
|
||||
@ -18,6 +18,8 @@ github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0 h1:0b2vaepXIfMsG+
|
||||
github.com/beefsack/go-rate v0.0.0-20220214233405-116f4ca011a0/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA=
|
||||
github.com/bluele/gcache v0.0.2 h1:WcbfdXICg7G/DGBh1PFfcirkWOQV+v077yF1pSy3DGw=
|
||||
github.com/bluele/gcache v0.0.2/go.mod h1:m15KV+ECjptwSPxKhOhQoAFQVtUFjTVkc3H8o0t/fp0=
|
||||
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500 h1:6lhrsTEnloDPXyeZBvSYvQf8u86jbKehZPVDDlkgDl4=
|
||||
github.com/c2h5oh/datasize v0.0.0-20231215233829-aa82cc1e6500/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@ -41,13 +43,13 @@ github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/google/pprof v0.0.0-20231205033806-a5a03c77bf08 h1:PxlBVtIFHR/mtWk2i0gTEdCz+jBnqiuHNSki0epDbVs=
|
||||
github.com/google/pprof v0.0.0-20231205033806-a5a03c77bf08/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815 h1:WzfWbQz/Ze8v6l++GGbGNFZnUShVpP/0xffCPLL+ax8=
|
||||
github.com/google/pprof v0.0.0-20240117000934-35fc243c5815/go.mod h1:czg5+yv1E0ZGTi6S6vVK1mke0fV+FaUhNGcd6VRS9Ik=
|
||||
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
|
||||
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
|
||||
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2 h1:9K06NfxkBh25x56yVhWWlKFE8YpicaSfHwoV8SFbueA=
|
||||
github.com/insomniacslk/dhcp v0.0.0-20231206064809-8c70d406f6d2/go.mod h1:3A9PQ1cunSDF/1rbTq99Ts4pVnycWg+vlPkfeD2NLFI=
|
||||
@ -71,19 +73,19 @@ github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU
|
||||
github.com/mdlayher/raw v0.1.0 h1:K4PFMVy+AFsp0Zdlrts7yNhxc/uXoPVHi9RzRvtZF2Y=
|
||||
github.com/mdlayher/raw v0.1.0/go.mod h1:yXnxvs6c0XoF/aK52/H5PjsVHmWBCFfZUfoh/Y5s9Sg=
|
||||
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
|
||||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||
github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
|
||||
github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
|
||||
github.com/mdlayher/socket v0.5.0 h1:ilICZmJcQz70vrWVes1MFera4jGiWNocSkykwwoy3XI=
|
||||
github.com/mdlayher/socket v0.5.0/go.mod h1:WkcBFfvyG8QENs5+hfQPl1X6Jpd2yeLIYgrGFmJiJxI=
|
||||
github.com/miekg/dns v1.1.58 h1:ca2Hdkz+cDg/7eNF6V56jjzuZ4aCAE+DbVkILdQWG/4=
|
||||
github.com/miekg/dns v1.1.58/go.mod h1:Ypv+3b/KadlvW9vJfXOTf300O4UqaHFzFCuHz+rPkBY=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/onsi/ginkgo/v2 v2.13.2 h1:Bi2gGVkfn6gQcjNjZJVO8Gf0FHzMPf2phUei9tejVMs=
|
||||
github.com/onsi/ginkgo/v2 v2.13.2/go.mod h1:XStQ8QcGwLyF4HdfcZB8SFOS/MWCgDuXMSBe6zrvLgM=
|
||||
github.com/onsi/gomega v1.29.0 h1:KIA/t2t5UBzoirT4H9tsML45GEbo3ouUnBHsCfD2tVg=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0 h1:79HwNRBAZHOEwrczrgSOPy+eFTTlIGELKy5as+ClttY=
|
||||
github.com/onsi/ginkgo/v2 v2.15.0/go.mod h1:HlxMHtYF57y6Dpf+mc5529KKmSq9h2FpCF+/ZkwUxKM=
|
||||
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19 h1:tYLzDnjDXh9qIxSTKHwXwOYmm9d887Y7Y1ZkyXYHAN4=
|
||||
github.com/pierrec/lz4/v4 v4.1.19/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ=
|
||||
github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
@ -109,19 +111,19 @@ github.com/ti-mo/netfilter v0.5.1 h1:cqamEd1c1zmpfpqvInLOro0Znq/RAfw2QL5wL2rAR/8
|
||||
github.com/ti-mo/netfilter v0.5.1/go.mod h1:h9UPQ3ZrTZGBitay+LETMxZvNgWGK/efTUcqES2YiLw=
|
||||
github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM=
|
||||
github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms=
|
||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63 h1:YcojQL98T/OO+rybuzn2+5KrD5dBwXIvYBvQ2cD3Avg=
|
||||
github.com/u-root/uio v0.0.0-20230305220412-3e8cd9d6bf63/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
||||
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e h1:BA9O3BmlTmpjbvajAwzWx4Wo2TRVdpPXZEeemGQcajw=
|
||||
github.com/u-root/uio v0.0.0-20240118234441-a3c409a6018e/go.mod h1:eLL9Nub3yfAho7qB0MzZizFhTU2QkLeoVsWdHtDW264=
|
||||
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
|
||||
go.etcd.io/bbolt v1.3.8 h1:xs88BrvEv273UsB79e0hcVrlUWmS0a8upikMFhSyAtA=
|
||||
go.etcd.io/bbolt v1.3.8/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw=
|
||||
go.uber.org/mock v0.3.0 h1:3mUxI1No2/60yUYax92Pt8eNOEecx2D3lcXZh2NEZJo=
|
||||
go.uber.org/mock v0.3.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
|
||||
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.16.0 h1:mMMrFzRSCF0GvB7Ne27XVtVAaXLrPmgPC7/v0tkwHaY=
|
||||
golang.org/x/crypto v0.16.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
|
||||
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb h1:c0vyKkb6yr3KR7jEfJaOSv4lG7xPkbN6r52aJz1d8a8=
|
||||
golang.org/x/exp v0.0.0-20231206192017-f3f8817b8deb/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
|
||||
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
|
||||
@ -132,12 +134,12 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
|
||||
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
|
||||
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190322080309-f49334f85ddc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@ -149,8 +151,8 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220622161953-175b2fd9d664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.4.1-0.20230131160137-e7d7f63158de/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
|
||||
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
@ -158,10 +160,12 @@ golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/tools v0.16.0 h1:GO788SKMRunPIBCXiQyo2AaexLstOrVhuAL5YwsckQM=
|
||||
golang.org/x/tools v0.16.0/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0=
|
||||
golang.org/x/tools v0.17.0 h1:FvmRgNOcs3kOa+T20R1uhfP9F6HgG2mfxDv1vrx1Htc=
|
||||
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gonum.org/v1/gonum v0.14.0 h1:2NiG67LD1tEH0D7kM+ps2V+fXmsAnpUeec7n8tcr4S0=
|
||||
gonum.org/v1/gonum v0.14.0/go.mod h1:AoWeoz0becf9QMWtE8iWXNXc27fK4fNeHNf/oMejGfU=
|
||||
google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
|
@ -1,23 +1,15 @@
|
||||
package aghalg
|
||||
|
||||
import (
|
||||
"github.com/AdguardTeam/golibs/errors"
|
||||
)
|
||||
|
||||
// RingBuffer is the implementation of ring buffer data structure.
|
||||
type RingBuffer[T any] struct {
|
||||
buf []T
|
||||
cur int
|
||||
cur uint
|
||||
full bool
|
||||
}
|
||||
|
||||
// NewRingBuffer initializes the new instance of ring buffer. size must be
|
||||
// greater or equal to zero.
|
||||
func NewRingBuffer[T any](size int) (rb *RingBuffer[T]) {
|
||||
if size < 0 {
|
||||
panic(errors.Error("ring buffer: size must be greater or equal to zero"))
|
||||
}
|
||||
|
||||
func NewRingBuffer[T any](size uint) (rb *RingBuffer[T]) {
|
||||
return &RingBuffer[T]{
|
||||
buf: make([]T, size),
|
||||
}
|
||||
@ -30,7 +22,7 @@ func (rb *RingBuffer[T]) Append(e T) {
|
||||
}
|
||||
|
||||
rb.buf[rb.cur] = e
|
||||
rb.cur = (rb.cur + 1) % cap(rb.buf)
|
||||
rb.cur = (rb.cur + 1) % uint(cap(rb.buf))
|
||||
if rb.cur == 0 {
|
||||
rb.full = true
|
||||
}
|
||||
@ -87,12 +79,12 @@ func (rb *RingBuffer[T]) splitCur() (before, after []T) {
|
||||
}
|
||||
|
||||
// Len returns a length of the buffer.
|
||||
func (rb *RingBuffer[T]) Len() (l int) {
|
||||
func (rb *RingBuffer[T]) Len() (l uint) {
|
||||
if !rb.full {
|
||||
return rb.cur
|
||||
}
|
||||
|
||||
return cap(rb.buf)
|
||||
return uint(cap(rb.buf))
|
||||
}
|
||||
|
||||
// Clear clears the buffer.
|
||||
|
@ -9,13 +9,13 @@ import (
|
||||
)
|
||||
|
||||
// elements is a helper function that returns n elements of the buffer.
|
||||
func elements(b *aghalg.RingBuffer[int], n int, reverse bool) (es []int) {
|
||||
func elements(b *aghalg.RingBuffer[int], n uint, reverse bool) (es []int) {
|
||||
fn := b.Range
|
||||
if reverse {
|
||||
fn = b.ReverseRange
|
||||
}
|
||||
|
||||
i := 0
|
||||
var i uint
|
||||
fn(func(e int) (cont bool) {
|
||||
if i >= n {
|
||||
return false
|
||||
@ -42,19 +42,14 @@ func TestNewRingBuffer(t *testing.T) {
|
||||
assert.Zero(t, b.Len())
|
||||
})
|
||||
|
||||
t.Run("negative_size", func(t *testing.T) {
|
||||
assert.PanicsWithError(t, "ring buffer: size must be greater or equal to zero", func() {
|
||||
aghalg.NewRingBuffer[int](-5)
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("zero", func(t *testing.T) {
|
||||
b := aghalg.NewRingBuffer[int](0)
|
||||
for i := 0; i < 10; i++ {
|
||||
b.Append(i)
|
||||
assert.Equal(t, 0, b.Len())
|
||||
assert.Empty(t, elements(b, b.Len(), false))
|
||||
assert.Empty(t, elements(b, b.Len(), true))
|
||||
bufLen := b.Len()
|
||||
assert.EqualValues(t, 0, bufLen)
|
||||
assert.Empty(t, elements(b, bufLen, false))
|
||||
assert.Empty(t, elements(b, bufLen, true))
|
||||
}
|
||||
})
|
||||
|
||||
@ -62,9 +57,10 @@ func TestNewRingBuffer(t *testing.T) {
|
||||
b := aghalg.NewRingBuffer[int](1)
|
||||
for i := 0; i < 10; i++ {
|
||||
b.Append(i)
|
||||
assert.Equal(t, 1, b.Len())
|
||||
assert.Equal(t, []int{i}, elements(b, b.Len(), false))
|
||||
assert.Equal(t, []int{i}, elements(b, b.Len(), true))
|
||||
bufLen := b.Len()
|
||||
assert.EqualValues(t, 1, bufLen)
|
||||
assert.Equal(t, []int{i}, elements(b, bufLen, false))
|
||||
assert.Equal(t, []int{i}, elements(b, bufLen, true))
|
||||
}
|
||||
})
|
||||
}
|
||||
@ -78,7 +74,7 @@ func TestRingBuffer_Range(t *testing.T) {
|
||||
name string
|
||||
want []int
|
||||
count int
|
||||
length int
|
||||
length uint
|
||||
}{{
|
||||
name: "three",
|
||||
count: 3,
|
||||
@ -163,11 +159,11 @@ func TestRingBuffer_Range_increment(t *testing.T) {
|
||||
for i, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
b.Append(i)
|
||||
|
||||
assert.Equal(t, tc.want, elements(b, b.Len(), false))
|
||||
bufLen := b.Len()
|
||||
assert.Equal(t, tc.want, elements(b, bufLen, false))
|
||||
|
||||
slices.Reverse(tc.want)
|
||||
assert.Equal(t, tc.want, elements(b, b.Len(), true))
|
||||
assert.Equal(t, tc.want, elements(b, bufLen, true))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -262,8 +262,7 @@ func (p *DefaultAddrProc) processRDNS(ip netip.Addr) (host string) {
|
||||
// shouldResolve returns false if ip is a loopback address, or ip is private and
|
||||
// resolving of private addresses is disabled.
|
||||
func (p *DefaultAddrProc) shouldResolve(ip netip.Addr) (ok bool) {
|
||||
return !ip.IsLoopback() &&
|
||||
(p.usePrivateRDNS || !p.privateSubnets.Contains(ip.AsSlice()))
|
||||
return !ip.IsLoopback() && (p.usePrivateRDNS || !p.privateSubnets.Contains(ip))
|
||||
}
|
||||
|
||||
// processWHOIS looks up the information about clients' IP addresses in the
|
||||
|
5
internal/configmigrate/configmigrate.go
Normal file
5
internal/configmigrate/configmigrate.go
Normal file
@ -0,0 +1,5 @@
|
||||
// Package configmigrate provides a way to upgrade the YAML configuration file.
|
||||
package configmigrate
|
||||
|
||||
// LastSchemaVersion is the most recent schema version.
|
||||
const LastSchemaVersion uint = 28
|
@ -1,9 +1,10 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/AdguardTeam/golibs/timeutil"
|
||||
@ -1646,3 +1647,84 @@ func TestUpgradeSchema26to27(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpgradeSchema27to28(t *testing.T) {
|
||||
const newSchemaVer = 28
|
||||
|
||||
testCases := []struct {
|
||||
in yobj
|
||||
want yobj
|
||||
name string
|
||||
}{{
|
||||
name: "empty",
|
||||
in: yobj{},
|
||||
want: yobj{
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
}, {
|
||||
name: "load_balance",
|
||||
in: yobj{
|
||||
"dns": yobj{
|
||||
"all_servers": false,
|
||||
"fastest_addr": false,
|
||||
},
|
||||
},
|
||||
want: yobj{
|
||||
"dns": yobj{
|
||||
"upstream_mode": dnsforward.UpstreamModeLoadBalance,
|
||||
},
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
}, {
|
||||
name: "parallel",
|
||||
in: yobj{
|
||||
"dns": yobj{
|
||||
"all_servers": true,
|
||||
"fastest_addr": false,
|
||||
},
|
||||
},
|
||||
want: yobj{
|
||||
"dns": yobj{
|
||||
"upstream_mode": dnsforward.UpstreamModeParallel,
|
||||
},
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
}, {
|
||||
name: "parallel_fastest",
|
||||
in: yobj{
|
||||
"dns": yobj{
|
||||
"all_servers": true,
|
||||
"fastest_addr": true,
|
||||
},
|
||||
},
|
||||
want: yobj{
|
||||
"dns": yobj{
|
||||
"upstream_mode": dnsforward.UpstreamModeParallel,
|
||||
},
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
}, {
|
||||
name: "load_balance",
|
||||
in: yobj{
|
||||
"dns": yobj{
|
||||
"all_servers": false,
|
||||
"fastest_addr": true,
|
||||
},
|
||||
},
|
||||
want: yobj{
|
||||
"dns": yobj{
|
||||
"upstream_mode": dnsforward.UpstreamModeFastestAddr,
|
||||
},
|
||||
"schema_version": newSchemaVer,
|
||||
},
|
||||
}}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := migrateTo28(tc.in)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, tc.want, tc.in)
|
||||
})
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
// Package confmigrate provides a way to upgrade the YAML configuration file.
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -9,9 +8,6 @@ import (
|
||||
yaml "gopkg.in/yaml.v3"
|
||||
)
|
||||
|
||||
// LastSchemaVersion is the most recent schema version.
|
||||
const LastSchemaVersion uint = 27
|
||||
|
||||
// Config is a the configuration for initializing a [Migrator].
|
||||
type Config struct {
|
||||
// WorkingDir is an absolute path to the working directory of AdGuardHome.
|
||||
@ -123,6 +119,7 @@ func (m *Migrator) upgradeConfigSchema(current, target uint, diskConf yobj) (err
|
||||
24: migrateTo25,
|
||||
25: migrateTo26,
|
||||
26: migrateTo27,
|
||||
27: migrateTo28,
|
||||
}
|
||||
|
||||
for i, migrate := range upgrades[current:target] {
|
@ -1,4 +1,4 @@
|
||||
package confmigrate_test
|
||||
package configmigrate_test
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
@ -6,7 +6,7 @@ import (
|
||||
"path"
|
||||
"testing"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/confmigrate"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/configmigrate"
|
||||
"github.com/AdguardTeam/golibs/testutil"
|
||||
"github.com/stretchr/testify/require"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
@ -200,7 +200,7 @@ func TestMigrateConfig_Migrate(t *testing.T) {
|
||||
wantBody, err := fs.ReadFile(testdata, path.Join(t.Name(), outputFileName))
|
||||
require.NoError(t, err)
|
||||
|
||||
migrator := confmigrate.New(&confmigrate.Config{
|
||||
migrator := configmigrate.New(&configmigrate.Config{
|
||||
WorkingDir: t.Name(),
|
||||
})
|
||||
newBody, upgraded, err := migrator.Migrate(body, tc.targetVersion)
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"os"
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo11 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"time"
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo13 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo14 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo15 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo16 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo17 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo18 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import "github.com/AdguardTeam/golibs/log"
|
||||
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"os"
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"time"
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo21 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"fmt"
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo24 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo25 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo26 performs the following changes:
|
||||
//
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo27 performs the following changes:
|
||||
//
|
47
internal/configmigrate/v28.go
Normal file
47
internal/configmigrate/v28.go
Normal file
@ -0,0 +1,47 @@
|
||||
package configmigrate
|
||||
|
||||
import (
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
|
||||
)
|
||||
|
||||
// migrateTo28 performs the following changes:
|
||||
//
|
||||
// # BEFORE:
|
||||
// 'dns':
|
||||
// 'all_servers': true
|
||||
// 'fastest_addr': true
|
||||
// # …
|
||||
// # …
|
||||
//
|
||||
// # AFTER:
|
||||
// 'dns':
|
||||
// 'upstream_mode': 'parallel'
|
||||
// # …
|
||||
// # …
|
||||
func migrateTo28(diskConf yobj) (err error) {
|
||||
diskConf["schema_version"] = 28
|
||||
|
||||
dns, ok, err := fieldVal[yobj](diskConf, "dns")
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
|
||||
allServers, _, _ := fieldVal[bool](dns, "all_servers")
|
||||
fastestAddr, _, _ := fieldVal[bool](dns, "fastest_addr")
|
||||
|
||||
var upstreamModeType dnsforward.UpstreamMode
|
||||
if allServers {
|
||||
upstreamModeType = dnsforward.UpstreamModeParallel
|
||||
} else if fastestAddr {
|
||||
upstreamModeType = dnsforward.UpstreamModeFastestAddr
|
||||
} else {
|
||||
upstreamModeType = dnsforward.UpstreamModeLoadBalance
|
||||
}
|
||||
|
||||
dns["upstream_mode"] = upstreamModeType
|
||||
|
||||
delete(dns, "all_servers")
|
||||
delete(dns, "fastest_addr")
|
||||
|
||||
return nil
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package confmigrate
|
||||
package configmigrate
|
||||
|
||||
// migrateTo3 performs the following changes:
|
||||
//
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user