2018-01-10 12:01:49 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
2018-01-31 09:42:56 +01:00
|
|
|
"encoding/json"
|
2018-01-10 12:01:49 +01:00
|
|
|
"errors"
|
2018-01-10 13:40:50 +01:00
|
|
|
"flag"
|
2018-01-10 12:01:49 +01:00
|
|
|
"fmt"
|
2019-06-03 16:44:09 +02:00
|
|
|
"math/rand"
|
2020-09-18 00:11:26 +02:00
|
|
|
"net"
|
2018-11-15 18:47:33 +01:00
|
|
|
"net/http"
|
2018-06-06 15:54:51 +02:00
|
|
|
"net/url"
|
2018-01-18 12:22:25 +01:00
|
|
|
"os"
|
2018-04-03 19:42:27 +02:00
|
|
|
"path"
|
2018-02-03 10:46:47 +01:00
|
|
|
"path/filepath"
|
2019-10-20 20:35:25 +02:00
|
|
|
"strconv"
|
2018-01-14 00:08:46 +01:00
|
|
|
"strings"
|
2018-01-10 12:01:49 +01:00
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/BurntSushi/toml"
|
2018-01-11 11:50:54 +01:00
|
|
|
"github.com/jedisct1/dlog"
|
2018-04-18 18:58:39 +02:00
|
|
|
stamps "github.com/jedisct1/go-dnsstamps"
|
2018-06-06 15:54:51 +02:00
|
|
|
netproxy "golang.org/x/net/proxy"
|
2018-01-10 12:01:49 +01:00
|
|
|
)
|
|
|
|
|
2019-05-28 13:22:11 +02:00
|
|
|
const (
|
2019-06-04 01:37:59 +02:00
|
|
|
MaxTimeout = 3600
|
|
|
|
DefaultNetprobeAddress = "9.9.9.9:53"
|
2019-05-28 13:22:11 +02:00
|
|
|
)
|
|
|
|
|
2018-01-10 12:01:49 +01:00
|
|
|
type Config struct {
|
2020-11-14 15:34:03 +01:00
|
|
|
LogLevel int `toml:"log_level"`
|
|
|
|
LogFile *string `toml:"log_file"`
|
|
|
|
LogFileLatest bool `toml:"log_file_latest"`
|
|
|
|
UseSyslog bool `toml:"use_syslog"`
|
|
|
|
ServerNames []string `toml:"server_names"`
|
|
|
|
DisabledServerNames []string `toml:"disabled_server_names"`
|
|
|
|
ListenAddresses []string `toml:"listen_addresses"`
|
|
|
|
LocalDoH LocalDoHConfig `toml:"local_doh"`
|
2021-09-23 19:16:12 +02:00
|
|
|
UserName string `toml:"user_name"`
|
|
|
|
ForceTCP bool `toml:"force_tcp"`
|
2022-07-24 16:13:14 +02:00
|
|
|
HTTP3 bool `toml:"http3"`
|
2021-09-23 19:16:12 +02:00
|
|
|
Timeout int `toml:"timeout"`
|
|
|
|
KeepAlive int `toml:"keepalive"`
|
|
|
|
Proxy string `toml:"proxy"`
|
2023-12-18 12:25:54 +01:00
|
|
|
CertRefreshConcurrency int `toml:"cert_refresh_concurrency"`
|
2021-09-23 19:16:12 +02:00
|
|
|
CertRefreshDelay int `toml:"cert_refresh_delay"`
|
|
|
|
CertIgnoreTimestamp bool `toml:"cert_ignore_timestamp"`
|
|
|
|
EphemeralKeys bool `toml:"dnscrypt_ephemeral_keys"`
|
|
|
|
LBStrategy string `toml:"lb_strategy"`
|
|
|
|
LBEstimator bool `toml:"lb_estimator"`
|
|
|
|
BlockIPv6 bool `toml:"block_ipv6"`
|
|
|
|
BlockUnqualified bool `toml:"block_unqualified"`
|
|
|
|
BlockUndelegated bool `toml:"block_undelegated"`
|
2020-11-14 15:34:03 +01:00
|
|
|
Cache bool
|
|
|
|
CacheSize int `toml:"cache_size"`
|
|
|
|
CacheNegTTL uint32 `toml:"cache_neg_ttl"`
|
|
|
|
CacheNegMinTTL uint32 `toml:"cache_neg_min_ttl"`
|
|
|
|
CacheNegMaxTTL uint32 `toml:"cache_neg_max_ttl"`
|
|
|
|
CacheMinTTL uint32 `toml:"cache_min_ttl"`
|
|
|
|
CacheMaxTTL uint32 `toml:"cache_max_ttl"`
|
|
|
|
RejectTTL uint32 `toml:"reject_ttl"`
|
|
|
|
CloakTTL uint32 `toml:"cloak_ttl"`
|
|
|
|
QueryLog QueryLogConfig `toml:"query_log"`
|
|
|
|
NxLog NxLogConfig `toml:"nx_log"`
|
|
|
|
BlockName BlockNameConfig `toml:"blocked_names"`
|
|
|
|
BlockNameLegacy BlockNameConfigLegacy `toml:"blacklist"`
|
|
|
|
WhitelistNameLegacy WhitelistNameConfigLegacy `toml:"whitelist"`
|
|
|
|
AllowedName AllowedNameConfig `toml:"allowed_names"`
|
|
|
|
BlockIP BlockIPConfig `toml:"blocked_ips"`
|
|
|
|
BlockIPLegacy BlockIPConfigLegacy `toml:"ip_blacklist"`
|
2020-11-15 20:59:58 +01:00
|
|
|
AllowIP AllowIPConfig `toml:"allowed_ips"`
|
2020-11-14 15:34:03 +01:00
|
|
|
ForwardFile string `toml:"forwarding_rules"`
|
|
|
|
CloakFile string `toml:"cloaking_rules"`
|
2021-01-02 15:10:04 +01:00
|
|
|
CaptivePortals CaptivePortalsConfig `toml:"captive_portals"`
|
2020-11-14 15:34:03 +01:00
|
|
|
StaticsConfig map[string]StaticConfig `toml:"static"`
|
|
|
|
SourcesConfig map[string]SourceConfig `toml:"sources"`
|
|
|
|
BrokenImplementations BrokenImplementationsConfig `toml:"broken_implementations"`
|
|
|
|
SourceRequireDNSSEC bool `toml:"require_dnssec"`
|
|
|
|
SourceRequireNoLog bool `toml:"require_nolog"`
|
|
|
|
SourceRequireNoFilter bool `toml:"require_nofilter"`
|
|
|
|
SourceDNSCrypt bool `toml:"dnscrypt_servers"`
|
|
|
|
SourceDoH bool `toml:"doh_servers"`
|
2021-06-07 13:21:58 +02:00
|
|
|
SourceODoH bool `toml:"odoh_servers"`
|
2020-11-14 15:34:03 +01:00
|
|
|
SourceIPv4 bool `toml:"ipv4_servers"`
|
|
|
|
SourceIPv6 bool `toml:"ipv6_servers"`
|
|
|
|
MaxClients uint32 `toml:"max_clients"`
|
2021-02-20 18:50:42 +01:00
|
|
|
BootstrapResolversLegacy []string `toml:"fallback_resolvers"`
|
|
|
|
BootstrapResolvers []string `toml:"bootstrap_resolvers"`
|
2020-11-14 15:34:03 +01:00
|
|
|
IgnoreSystemDNS bool `toml:"ignore_system_dns"`
|
|
|
|
AllWeeklyRanges map[string]WeeklyRangesStr `toml:"schedules"`
|
|
|
|
LogMaxSize int `toml:"log_files_max_size"`
|
|
|
|
LogMaxAge int `toml:"log_files_max_age"`
|
|
|
|
LogMaxBackups int `toml:"log_files_max_backups"`
|
|
|
|
TLSDisableSessionTickets bool `toml:"tls_disable_session_tickets"`
|
|
|
|
TLSCipherSuite []uint16 `toml:"tls_cipher_suite"`
|
2023-05-24 09:20:58 +02:00
|
|
|
TLSKeyLogFile string `toml:"tls_key_log_file"`
|
2020-11-14 15:34:03 +01:00
|
|
|
NetprobeAddress string `toml:"netprobe_address"`
|
|
|
|
NetprobeTimeout int `toml:"netprobe_timeout"`
|
|
|
|
OfflineMode bool `toml:"offline_mode"`
|
|
|
|
HTTPProxyURL string `toml:"http_proxy"`
|
|
|
|
RefusedCodeInResponses bool `toml:"refused_code_in_responses"`
|
|
|
|
BlockedQueryResponse string `toml:"blocked_query_response"`
|
|
|
|
QueryMeta []string `toml:"query_meta"`
|
2022-02-01 08:18:45 +01:00
|
|
|
CloakedPTR bool `toml:"cloak_ptr"`
|
2020-11-14 15:34:03 +01:00
|
|
|
AnonymizedDNS AnonymizedDNSConfig `toml:"anonymized_dns"`
|
|
|
|
DoHClientX509Auth DoHClientX509AuthConfig `toml:"doh_client_x509_auth"`
|
|
|
|
DoHClientX509AuthLegacy DoHClientX509AuthConfig `toml:"tls_client_auth"`
|
|
|
|
DNS64 DNS64Config `toml:"dns64"`
|
|
|
|
EDNSClientSubnet []string `toml:"edns_client_subnet"`
|
2018-01-10 12:01:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func newConfig() Config {
|
|
|
|
return Config{
|
2018-04-07 22:23:29 +02:00
|
|
|
LogLevel: int(dlog.LogLevel()),
|
2020-06-08 22:31:03 +02:00
|
|
|
LogFileLatest: true,
|
2018-04-07 22:23:29 +02:00
|
|
|
ListenAddresses: []string{"127.0.0.1:53"},
|
2019-11-29 08:53:13 +01:00
|
|
|
LocalDoH: LocalDoHConfig{Path: "/dns-query"},
|
2019-10-20 19:22:02 +02:00
|
|
|
Timeout: 5000,
|
2018-04-07 22:23:29 +02:00
|
|
|
KeepAlive: 5,
|
2023-12-18 12:25:54 +01:00
|
|
|
CertRefreshConcurrency: 10,
|
2018-04-07 22:23:29 +02:00
|
|
|
CertRefreshDelay: 240,
|
2022-07-24 16:13:14 +02:00
|
|
|
HTTP3: false,
|
2018-04-07 22:23:29 +02:00
|
|
|
CertIgnoreTimestamp: false,
|
2018-04-09 03:12:34 +02:00
|
|
|
EphemeralKeys: false,
|
2018-04-07 22:23:29 +02:00
|
|
|
Cache: true,
|
2018-04-10 13:24:13 +02:00
|
|
|
CacheSize: 512,
|
2018-04-17 00:24:49 +02:00
|
|
|
CacheNegTTL: 0,
|
|
|
|
CacheNegMinTTL: 60,
|
|
|
|
CacheNegMaxTTL: 600,
|
2018-04-07 22:23:29 +02:00
|
|
|
CacheMinTTL: 60,
|
2019-10-18 17:21:08 +02:00
|
|
|
CacheMaxTTL: 86400,
|
2019-10-21 18:26:49 +02:00
|
|
|
RejectTTL: 600,
|
2019-10-17 16:19:07 +02:00
|
|
|
CloakTTL: 600,
|
2018-04-07 22:23:29 +02:00
|
|
|
SourceRequireNoLog: true,
|
|
|
|
SourceRequireNoFilter: true,
|
|
|
|
SourceIPv4: true,
|
|
|
|
SourceIPv6: false,
|
|
|
|
SourceDNSCrypt: true,
|
|
|
|
SourceDoH: true,
|
2021-06-07 13:21:58 +02:00
|
|
|
SourceODoH: false,
|
2018-04-07 22:23:29 +02:00
|
|
|
MaxClients: 250,
|
2021-02-20 18:50:42 +01:00
|
|
|
BootstrapResolvers: []string{DefaultBootstrapResolver},
|
2018-04-07 22:23:29 +02:00
|
|
|
IgnoreSystemDNS: false,
|
|
|
|
LogMaxSize: 10,
|
|
|
|
LogMaxAge: 7,
|
|
|
|
LogMaxBackups: 1,
|
|
|
|
TLSDisableSessionTickets: false,
|
|
|
|
TLSCipherSuite: nil,
|
2023-05-24 09:20:58 +02:00
|
|
|
TLSKeyLogFile: "",
|
2018-11-22 17:24:41 +01:00
|
|
|
NetprobeTimeout: 60,
|
2018-07-05 18:05:24 +02:00
|
|
|
OfflineMode: false,
|
2019-02-23 00:58:25 +01:00
|
|
|
RefusedCodeInResponses: false,
|
2019-06-03 16:44:09 +02:00
|
|
|
LBEstimator: true,
|
2019-06-19 18:11:06 +02:00
|
|
|
BlockedQueryResponse: "hinfo",
|
2019-11-17 21:44:46 +01:00
|
|
|
BrokenImplementations: BrokenImplementationsConfig{
|
2020-03-26 10:57:09 +01:00
|
|
|
FragmentsBlocked: []string{
|
2020-03-26 12:31:12 +01:00
|
|
|
"cisco", "cisco-ipv6", "cisco-familyshield", "cisco-familyshield-ipv6",
|
2021-01-02 12:53:10 +01:00
|
|
|
"cleanbrowsing-adult", "cleanbrowsing-adult-ipv6", "cleanbrowsing-family", "cleanbrowsing-family-ipv6", "cleanbrowsing-security", "cleanbrowsing-security-ipv6",
|
2020-03-26 10:57:09 +01:00
|
|
|
},
|
2019-11-17 21:44:46 +01:00
|
|
|
},
|
2021-01-03 13:01:44 +01:00
|
|
|
AnonymizedDNS: AnonymizedDNSConfig{
|
|
|
|
DirectCertFallback: true,
|
|
|
|
},
|
2022-02-01 08:18:45 +01:00
|
|
|
CloakedPTR: false,
|
2018-01-10 12:01:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-31 08:43:49 +01:00
|
|
|
type StaticConfig struct {
|
2018-01-22 09:59:32 +01:00
|
|
|
Stamp string
|
2018-01-10 12:01:49 +01:00
|
|
|
}
|
|
|
|
|
2018-01-13 23:52:44 +01:00
|
|
|
type SourceConfig struct {
|
|
|
|
URL string
|
2018-03-28 13:36:19 +02:00
|
|
|
URLs []string
|
2018-01-13 23:52:44 +01:00
|
|
|
MinisignKeyStr string `toml:"minisign_key"`
|
|
|
|
CacheFile string `toml:"cache_file"`
|
|
|
|
FormatStr string `toml:"format"`
|
|
|
|
RefreshDelay int `toml:"refresh_delay"`
|
2018-01-20 16:59:40 +01:00
|
|
|
Prefix string
|
2018-01-13 23:52:44 +01:00
|
|
|
}
|
|
|
|
|
2018-01-16 00:23:16 +01:00
|
|
|
type QueryLogConfig struct {
|
2018-01-20 13:27:37 +01:00
|
|
|
File string
|
|
|
|
Format string
|
|
|
|
IgnoredQtypes []string `toml:"ignored_qtypes"`
|
2018-01-16 00:23:16 +01:00
|
|
|
}
|
|
|
|
|
2018-01-20 16:59:40 +01:00
|
|
|
type NxLogConfig struct {
|
|
|
|
File string
|
|
|
|
Format string
|
|
|
|
}
|
|
|
|
|
2018-01-17 02:40:47 +01:00
|
|
|
type BlockNameConfig struct {
|
2020-06-26 23:18:30 +02:00
|
|
|
File string `toml:"blocked_names_file"`
|
|
|
|
LogFile string `toml:"log_file"`
|
|
|
|
Format string `toml:"log_format"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type BlockNameConfigLegacy struct {
|
2018-01-17 17:03:42 +01:00
|
|
|
File string `toml:"blacklist_file"`
|
|
|
|
LogFile string `toml:"log_file"`
|
|
|
|
Format string `toml:"log_format"`
|
2018-01-17 02:40:47 +01:00
|
|
|
}
|
|
|
|
|
2020-06-26 23:18:30 +02:00
|
|
|
type WhitelistNameConfigLegacy struct {
|
2018-04-07 23:02:40 +02:00
|
|
|
File string `toml:"whitelist_file"`
|
|
|
|
LogFile string `toml:"log_file"`
|
|
|
|
Format string `toml:"log_format"`
|
|
|
|
}
|
|
|
|
|
2020-06-26 23:18:30 +02:00
|
|
|
type AllowedNameConfig struct {
|
|
|
|
File string `toml:"allowed_names_file"`
|
|
|
|
LogFile string `toml:"log_file"`
|
|
|
|
Format string `toml:"log_format"`
|
|
|
|
}
|
|
|
|
|
2018-01-21 16:07:44 +01:00
|
|
|
type BlockIPConfig struct {
|
2020-06-26 23:18:30 +02:00
|
|
|
File string `toml:"blocked_ips_file"`
|
|
|
|
LogFile string `toml:"log_file"`
|
|
|
|
Format string `toml:"log_format"`
|
|
|
|
}
|
|
|
|
|
|
|
|
type BlockIPConfigLegacy struct {
|
2018-01-21 16:07:44 +01:00
|
|
|
File string `toml:"blacklist_file"`
|
|
|
|
LogFile string `toml:"log_file"`
|
|
|
|
Format string `toml:"log_format"`
|
|
|
|
}
|
|
|
|
|
2020-11-15 20:59:58 +01:00
|
|
|
type AllowIPConfig struct {
|
2020-12-11 12:25:57 +01:00
|
|
|
File string `toml:"allowed_ips_file"`
|
|
|
|
LogFile string `toml:"log_file"`
|
|
|
|
Format string `toml:"log_format"`
|
2020-11-15 20:59:58 +01:00
|
|
|
}
|
|
|
|
|
2019-10-14 01:45:38 +02:00
|
|
|
type AnonymizedDNSRouteConfig struct {
|
2019-10-14 12:08:47 +02:00
|
|
|
ServerName string `toml:"server_name"`
|
|
|
|
RelayNames []string `toml:"via"`
|
2019-10-14 01:45:38 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type AnonymizedDNSConfig struct {
|
2020-07-03 12:58:36 +02:00
|
|
|
Routes []AnonymizedDNSRouteConfig `toml:"routes"`
|
|
|
|
SkipIncompatible bool `toml:"skip_incompatible"`
|
|
|
|
DirectCertFallback bool `toml:"direct_cert_fallback"`
|
2019-10-14 01:45:38 +02:00
|
|
|
}
|
|
|
|
|
2019-11-16 18:51:16 +01:00
|
|
|
type BrokenImplementationsConfig struct {
|
2020-03-26 17:20:34 +01:00
|
|
|
BrokenQueryPadding []string `toml:"broken_query_padding"`
|
|
|
|
FragmentsBlocked []string `toml:"fragments_blocked"`
|
2019-11-16 18:51:16 +01:00
|
|
|
}
|
|
|
|
|
2019-11-28 17:04:29 +01:00
|
|
|
type LocalDoHConfig struct {
|
|
|
|
ListenAddresses []string `toml:"listen_addresses"`
|
2019-11-28 23:49:28 +01:00
|
|
|
Path string `toml:"path"`
|
2019-11-28 17:04:29 +01:00
|
|
|
CertFile string `toml:"cert_file"`
|
|
|
|
CertKeyFile string `toml:"cert_key_file"`
|
|
|
|
}
|
|
|
|
|
2018-01-31 09:42:56 +01:00
|
|
|
type ServerSummary struct {
|
2018-03-28 12:22:37 +02:00
|
|
|
Name string `json:"name"`
|
|
|
|
Proto string `json:"proto"`
|
|
|
|
IPv6 bool `json:"ipv6"`
|
|
|
|
Addrs []string `json:"addrs,omitempty"`
|
|
|
|
Ports []int `json:"ports"`
|
2023-09-23 18:46:11 +02:00
|
|
|
DNSSEC *bool `json:"dnssec,omitempty"`
|
2018-03-28 12:22:37 +02:00
|
|
|
NoLog bool `json:"nolog"`
|
|
|
|
NoFilter bool `json:"nofilter"`
|
|
|
|
Description string `json:"description,omitempty"`
|
2019-10-23 23:28:46 +02:00
|
|
|
Stamp string `json:"stamp"`
|
2018-01-31 09:42:56 +01:00
|
|
|
}
|
|
|
|
|
2020-03-09 22:11:53 +01:00
|
|
|
type TLSClientAuthCredsConfig struct {
|
|
|
|
ServerName string `toml:"server_name"`
|
|
|
|
ClientCert string `toml:"client_cert"`
|
|
|
|
ClientKey string `toml:"client_key"`
|
2020-06-08 18:01:40 +02:00
|
|
|
RootCA string `toml:"root_ca"`
|
2020-03-09 22:11:53 +01:00
|
|
|
}
|
|
|
|
|
2020-04-26 21:21:00 +02:00
|
|
|
type DoHClientX509AuthConfig struct {
|
2020-03-09 22:11:53 +01:00
|
|
|
Creds []TLSClientAuthCredsConfig `toml:"creds"`
|
|
|
|
}
|
|
|
|
|
2020-06-08 18:23:03 +02:00
|
|
|
type DNS64Config struct {
|
|
|
|
Prefixes []string `toml:"prefix"`
|
|
|
|
Resolvers []string `toml:"resolver"`
|
|
|
|
}
|
|
|
|
|
2021-01-02 15:10:04 +01:00
|
|
|
type CaptivePortalsConfig struct {
|
|
|
|
MapFile string `toml:"map_file"`
|
|
|
|
}
|
|
|
|
|
2019-10-30 14:30:31 +01:00
|
|
|
type ConfigFlags struct {
|
2021-01-02 22:20:52 +01:00
|
|
|
Resolve *string
|
2019-10-30 14:30:31 +01:00
|
|
|
List *bool
|
|
|
|
ListAll *bool
|
2023-09-23 18:37:52 +02:00
|
|
|
IncludeRelays *bool
|
2019-12-11 14:08:48 +01:00
|
|
|
JSONOutput *bool
|
2019-10-30 14:30:31 +01:00
|
|
|
Check *bool
|
|
|
|
ConfigFile *string
|
|
|
|
Child *bool
|
|
|
|
NetprobeTimeoutOverride *int
|
|
|
|
ShowCerts *bool
|
|
|
|
}
|
|
|
|
|
2018-04-03 20:15:33 +02:00
|
|
|
func findConfigFile(configFile *string) (string, error) {
|
2018-02-03 10:46:47 +01:00
|
|
|
if _, err := os.Stat(*configFile); os.IsNotExist(err) {
|
|
|
|
cdLocal()
|
2018-04-03 19:42:27 +02:00
|
|
|
if _, err := os.Stat(*configFile); err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2018-02-03 10:46:47 +01:00
|
|
|
}
|
2018-04-03 19:42:27 +02:00
|
|
|
pwd, err := os.Getwd()
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
2018-04-03 20:15:33 +02:00
|
|
|
if filepath.IsAbs(*configFile) {
|
|
|
|
return *configFile, nil
|
|
|
|
}
|
2018-04-03 19:42:27 +02:00
|
|
|
return path.Join(pwd, *configFile), nil
|
|
|
|
}
|
|
|
|
|
2019-10-30 14:30:31 +01:00
|
|
|
func ConfigLoad(proxy *Proxy, flags *ConfigFlags) error {
|
|
|
|
foundConfigFile, err := findConfigFile(flags.ConfigFile)
|
2018-04-03 20:15:33 +02:00
|
|
|
if err != nil {
|
2022-03-23 17:48:48 +01:00
|
|
|
return fmt.Errorf(
|
|
|
|
"Unable to load the configuration file [%s] -- Maybe use the -config command-line switch?",
|
|
|
|
*flags.ConfigFile,
|
|
|
|
)
|
2018-04-03 20:15:33 +02:00
|
|
|
}
|
2024-02-20 02:11:03 +01:00
|
|
|
WarnIfMaybeWritableByOtherUsers(foundConfigFile)
|
2018-01-10 12:01:49 +01:00
|
|
|
config := newConfig()
|
2018-04-03 20:15:33 +02:00
|
|
|
md, err := toml.DecodeFile(foundConfigFile, &config)
|
2018-02-10 21:19:40 +01:00
|
|
|
if err != nil {
|
2018-01-10 12:01:49 +01:00
|
|
|
return err
|
|
|
|
}
|
2021-01-02 22:20:52 +01:00
|
|
|
|
|
|
|
if flags.Resolve != nil && len(*flags.Resolve) > 0 {
|
|
|
|
addr := "127.0.0.1:53"
|
|
|
|
if len(config.ListenAddresses) > 0 {
|
|
|
|
addr = config.ListenAddresses[0]
|
|
|
|
}
|
|
|
|
Resolve(addr, *flags.Resolve, len(config.ServerNames) == 1)
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
|
2019-12-09 12:11:24 +01:00
|
|
|
if err := cdFileDir(foundConfigFile); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2018-01-19 20:06:04 +01:00
|
|
|
if config.LogLevel >= 0 && config.LogLevel < int(dlog.SeverityLast) {
|
|
|
|
dlog.SetLogLevel(dlog.Severity(config.LogLevel))
|
|
|
|
}
|
2018-01-20 13:56:26 +01:00
|
|
|
if dlog.LogLevel() <= dlog.SeverityDebug && os.Getenv("DEBUG") == "" {
|
|
|
|
dlog.SetLogLevel(dlog.SeverityInfo)
|
|
|
|
}
|
2020-06-08 22:31:03 +02:00
|
|
|
dlog.TruncateLogFile(config.LogFileLatest)
|
2022-08-03 14:52:08 +02:00
|
|
|
proxy.showCerts = *flags.ShowCerts || len(os.Getenv("SHOW_CERTS")) > 0
|
|
|
|
isCommandMode := *flags.Check || proxy.showCerts || *flags.List || *flags.ListAll
|
|
|
|
if isCommandMode {
|
|
|
|
} else if config.UseSyslog {
|
2018-01-19 20:06:04 +01:00
|
|
|
dlog.UseSyslog(true)
|
|
|
|
} else if config.LogFile != nil {
|
|
|
|
dlog.UseLogFile(*config.LogFile)
|
2019-10-30 14:30:31 +01:00
|
|
|
if !*flags.Child {
|
2018-06-13 16:52:41 +02:00
|
|
|
FileDescriptors = append(FileDescriptors, dlog.GetFileDescriptor())
|
|
|
|
} else {
|
2021-01-22 09:15:40 +01:00
|
|
|
dlog.SetFileDescriptor(os.NewFile(uintptr(InheritedDescriptorsBase+FileDescriptorNum), "logFile"))
|
2018-06-13 16:52:41 +02:00
|
|
|
FileDescriptorNum++
|
|
|
|
}
|
2018-01-19 20:06:04 +01:00
|
|
|
}
|
2020-07-27 16:01:44 +02:00
|
|
|
if !*flags.Child {
|
|
|
|
dlog.Noticef("dnscrypt-proxy %s", AppVersion)
|
|
|
|
}
|
|
|
|
undecoded := md.Undecoded()
|
|
|
|
if len(undecoded) > 0 {
|
|
|
|
return fmt.Errorf("Unsupported key in configuration file: [%s]", undecoded[0])
|
|
|
|
}
|
|
|
|
|
2018-03-02 10:34:00 +01:00
|
|
|
proxy.logMaxSize = config.LogMaxSize
|
|
|
|
proxy.logMaxAge = config.LogMaxAge
|
|
|
|
proxy.logMaxBackups = config.LogMaxBackups
|
2018-04-07 22:33:11 +02:00
|
|
|
|
2018-07-07 19:58:37 +02:00
|
|
|
proxy.userName = config.UserName
|
|
|
|
|
2019-10-30 14:30:31 +01:00
|
|
|
proxy.child = *flags.Child
|
2018-04-07 22:33:11 +02:00
|
|
|
proxy.xTransport = NewXTransport()
|
2018-04-07 22:23:29 +02:00
|
|
|
proxy.xTransport.tlsDisableSessionTickets = config.TLSDisableSessionTickets
|
|
|
|
proxy.xTransport.tlsCipherSuite = config.TLSCipherSuite
|
2019-07-10 13:13:28 +02:00
|
|
|
proxy.xTransport.mainProto = proxy.mainProto
|
2022-07-24 16:13:14 +02:00
|
|
|
proxy.xTransport.http3 = config.HTTP3
|
2021-02-20 18:50:42 +01:00
|
|
|
if len(config.BootstrapResolvers) == 0 && len(config.BootstrapResolversLegacy) > 0 {
|
2021-06-08 09:53:53 +02:00
|
|
|
dlog.Warnf("fallback_resolvers was renamed to bootstrap_resolvers - Please update your configuration")
|
2021-02-20 18:50:42 +01:00
|
|
|
config.BootstrapResolvers = config.BootstrapResolversLegacy
|
2020-01-15 19:58:14 +01:00
|
|
|
}
|
2021-02-20 18:50:42 +01:00
|
|
|
if len(config.BootstrapResolvers) > 0 {
|
|
|
|
for _, resolver := range config.BootstrapResolvers {
|
2020-01-15 19:58:14 +01:00
|
|
|
if err := isIPAndPort(resolver); err != nil {
|
2021-02-20 18:50:42 +01:00
|
|
|
return fmt.Errorf("Bootstrap resolver [%v]: %v", resolver, err)
|
2020-01-15 19:58:14 +01:00
|
|
|
}
|
2019-10-20 20:35:25 +02:00
|
|
|
}
|
2018-01-30 17:37:35 +01:00
|
|
|
proxy.xTransport.ignoreSystemDNS = config.IgnoreSystemDNS
|
|
|
|
}
|
2021-02-20 18:50:42 +01:00
|
|
|
proxy.xTransport.bootstrapResolvers = config.BootstrapResolvers
|
2018-03-21 09:05:30 +01:00
|
|
|
proxy.xTransport.useIPv4 = config.SourceIPv4
|
|
|
|
proxy.xTransport.useIPv6 = config.SourceIPv6
|
2018-04-02 01:49:09 +02:00
|
|
|
proxy.xTransport.keepAlive = time.Duration(config.KeepAlive) * time.Second
|
2018-11-15 18:47:33 +01:00
|
|
|
if len(config.HTTPProxyURL) > 0 {
|
|
|
|
httpProxyURL, err := url.Parse(config.HTTPProxyURL)
|
|
|
|
if err != nil {
|
2020-07-27 16:01:44 +02:00
|
|
|
return fmt.Errorf("Unable to parse the HTTP proxy URL [%v]", config.HTTPProxyURL)
|
2018-11-15 18:47:33 +01:00
|
|
|
}
|
|
|
|
proxy.xTransport.httpProxyFunction = http.ProxyURL(httpProxyURL)
|
|
|
|
}
|
2018-06-06 15:54:51 +02:00
|
|
|
|
|
|
|
if len(config.Proxy) > 0 {
|
|
|
|
proxyDialerURL, err := url.Parse(config.Proxy)
|
|
|
|
if err != nil {
|
2020-07-27 16:01:44 +02:00
|
|
|
return fmt.Errorf("Unable to parse the proxy URL [%v]", config.Proxy)
|
2018-06-06 15:54:51 +02:00
|
|
|
}
|
|
|
|
proxyDialer, err := netproxy.FromURL(proxyDialerURL, netproxy.Direct)
|
|
|
|
if err != nil {
|
2020-07-27 16:01:44 +02:00
|
|
|
return fmt.Errorf("Unable to use the proxy: [%v]", err)
|
2018-06-06 15:54:51 +02:00
|
|
|
}
|
|
|
|
proxy.xTransport.proxyDialer = &proxyDialer
|
2019-04-14 13:41:43 +02:00
|
|
|
proxy.mainProto = "tcp"
|
2018-06-06 15:54:51 +02:00
|
|
|
}
|
|
|
|
|
2018-04-07 22:23:29 +02:00
|
|
|
proxy.xTransport.rebuildTransport()
|
2018-04-07 22:33:40 +02:00
|
|
|
|
2019-06-19 18:11:06 +02:00
|
|
|
if md.IsDefined("refused_code_in_responses") {
|
|
|
|
dlog.Notice("config option `refused_code_in_responses` is deprecated, use `blocked_query_response`")
|
|
|
|
if config.RefusedCodeInResponses {
|
|
|
|
config.BlockedQueryResponse = "refused"
|
|
|
|
} else {
|
|
|
|
config.BlockedQueryResponse = "hinfo"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
proxy.blockedQueryResponse = config.BlockedQueryResponse
|
2018-01-10 12:01:49 +01:00
|
|
|
proxy.timeout = time.Duration(config.Timeout) * time.Millisecond
|
2018-01-24 16:51:26 +01:00
|
|
|
proxy.maxClients = config.MaxClients
|
2018-01-10 12:01:49 +01:00
|
|
|
proxy.mainProto = "udp"
|
|
|
|
if config.ForceTCP {
|
|
|
|
proxy.mainProto = "tcp"
|
|
|
|
}
|
2023-12-18 12:25:54 +01:00
|
|
|
proxy.certRefreshConcurrency = Max(1, config.CertRefreshConcurrency)
|
2019-11-08 22:51:04 +01:00
|
|
|
proxy.certRefreshDelay = time.Duration(Max(60, config.CertRefreshDelay)) * time.Minute
|
2018-01-17 17:22:29 +01:00
|
|
|
proxy.certRefreshDelayAfterFailure = time.Duration(10 * time.Second)
|
2018-01-21 18:10:38 +01:00
|
|
|
proxy.certIgnoreTimestamp = config.CertIgnoreTimestamp
|
2018-04-09 03:12:34 +02:00
|
|
|
proxy.ephemeralKeys = config.EphemeralKeys
|
2019-11-28 17:04:29 +01:00
|
|
|
if len(config.ListenAddresses) == 0 && len(config.LocalDoH.ListenAddresses) == 0 {
|
2018-02-01 16:59:09 +01:00
|
|
|
dlog.Debug("No local IP/port configured")
|
2018-01-10 12:01:49 +01:00
|
|
|
}
|
2020-03-20 17:37:34 +01:00
|
|
|
lbStrategy := LBStrategy(DefaultLBStrategy)
|
2020-03-20 17:48:54 +01:00
|
|
|
switch lbStrategyStr := strings.ToLower(config.LBStrategy); lbStrategyStr {
|
2018-02-05 01:53:23 +01:00
|
|
|
case "":
|
|
|
|
// default
|
2018-02-04 21:23:39 +01:00
|
|
|
case "p2":
|
2020-03-20 17:37:34 +01:00
|
|
|
lbStrategy = LBStrategyP2{}
|
2018-02-04 21:23:39 +01:00
|
|
|
case "ph":
|
2020-03-20 17:37:34 +01:00
|
|
|
lbStrategy = LBStrategyPH{}
|
2018-02-04 21:23:39 +01:00
|
|
|
case "fastest":
|
2019-06-02 13:24:24 +02:00
|
|
|
case "first":
|
2020-03-20 17:37:34 +01:00
|
|
|
lbStrategy = LBStrategyFirst{}
|
2018-02-04 21:23:39 +01:00
|
|
|
case "random":
|
2020-03-20 17:37:34 +01:00
|
|
|
lbStrategy = LBStrategyRandom{}
|
2018-02-04 21:23:39 +01:00
|
|
|
default:
|
2020-03-20 17:48:54 +01:00
|
|
|
if strings.HasPrefix(lbStrategyStr, "p") {
|
|
|
|
n, err := strconv.ParseInt(strings.TrimPrefix(lbStrategyStr, "p"), 10, 32)
|
|
|
|
if err != nil || n <= 0 {
|
2020-03-20 20:53:03 +01:00
|
|
|
dlog.Warnf("Invalid load balancing strategy: [%s]", config.LBStrategy)
|
|
|
|
} else {
|
|
|
|
lbStrategy = LBStrategyPN{n: int(n)}
|
2020-03-20 17:48:54 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
dlog.Warnf("Unknown load balancing strategy: [%s]", config.LBStrategy)
|
|
|
|
}
|
2018-02-04 21:23:39 +01:00
|
|
|
}
|
|
|
|
proxy.serversInfo.lbStrategy = lbStrategy
|
2019-06-03 13:04:34 +02:00
|
|
|
proxy.serversInfo.lbEstimator = config.LBEstimator
|
2018-02-04 21:23:39 +01:00
|
|
|
|
2018-01-10 12:01:49 +01:00
|
|
|
proxy.listenAddresses = config.ListenAddresses
|
2019-11-28 17:04:29 +01:00
|
|
|
proxy.localDoHListenAddresses = config.LocalDoH.ListenAddresses
|
2019-12-10 16:04:37 +01:00
|
|
|
if len(config.LocalDoH.Path) > 0 && config.LocalDoH.Path[0] != '/' {
|
2020-07-27 16:01:44 +02:00
|
|
|
return fmt.Errorf("local DoH: [%s] cannot be a valid URL path. Read the documentation", config.LocalDoH.Path)
|
2019-12-10 16:04:37 +01:00
|
|
|
}
|
2019-11-28 23:49:28 +01:00
|
|
|
proxy.localDoHPath = config.LocalDoH.Path
|
2019-11-28 17:04:29 +01:00
|
|
|
proxy.localDoHCertFile = config.LocalDoH.CertFile
|
|
|
|
proxy.localDoHCertKeyFile = config.LocalDoH.CertKeyFile
|
2018-01-10 17:23:20 +01:00
|
|
|
proxy.pluginBlockIPv6 = config.BlockIPv6
|
2019-12-09 20:25:38 +01:00
|
|
|
proxy.pluginBlockUnqualified = config.BlockUnqualified
|
2019-12-16 16:13:18 +01:00
|
|
|
proxy.pluginBlockUndelegated = config.BlockUndelegated
|
2018-01-10 18:32:05 +01:00
|
|
|
proxy.cache = config.Cache
|
2018-01-10 19:32:56 +01:00
|
|
|
proxy.cacheSize = config.CacheSize
|
2018-04-17 00:24:49 +02:00
|
|
|
|
|
|
|
if config.CacheNegTTL > 0 {
|
|
|
|
proxy.cacheNegMinTTL = config.CacheNegTTL
|
|
|
|
proxy.cacheNegMaxTTL = config.CacheNegTTL
|
|
|
|
} else {
|
|
|
|
proxy.cacheNegMinTTL = config.CacheNegMinTTL
|
|
|
|
proxy.cacheNegMaxTTL = config.CacheNegMaxTTL
|
|
|
|
}
|
|
|
|
|
2018-01-10 19:32:56 +01:00
|
|
|
proxy.cacheMinTTL = config.CacheMinTTL
|
|
|
|
proxy.cacheMaxTTL = config.CacheMaxTTL
|
2019-10-21 18:26:49 +02:00
|
|
|
proxy.rejectTTL = config.RejectTTL
|
2019-10-17 16:19:07 +02:00
|
|
|
proxy.cloakTTL = config.CloakTTL
|
2021-12-13 14:00:13 +01:00
|
|
|
proxy.cloakedPTR = config.CloakedPTR
|
2018-01-17 17:03:42 +01:00
|
|
|
|
2019-09-07 16:19:47 +02:00
|
|
|
proxy.queryMeta = config.QueryMeta
|
|
|
|
|
2020-09-18 00:11:26 +02:00
|
|
|
if len(config.EDNSClientSubnet) != 0 {
|
|
|
|
proxy.ednsClientSubnets = make([]*net.IPNet, 0)
|
|
|
|
for _, cidr := range config.EDNSClientSubnet {
|
|
|
|
_, net, err := net.ParseCIDR(cidr)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("Invalid EDNS-client-subnet CIDR: [%v]", cidr)
|
|
|
|
}
|
|
|
|
proxy.ednsClientSubnets = append(proxy.ednsClientSubnets, net)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-16 00:23:16 +01:00
|
|
|
if len(config.QueryLog.Format) == 0 {
|
|
|
|
config.QueryLog.Format = "tsv"
|
|
|
|
} else {
|
|
|
|
config.QueryLog.Format = strings.ToLower(config.QueryLog.Format)
|
|
|
|
}
|
2018-01-16 18:10:04 +01:00
|
|
|
if config.QueryLog.Format != "tsv" && config.QueryLog.Format != "ltsv" {
|
2018-01-16 00:23:16 +01:00
|
|
|
return errors.New("Unsupported query log format")
|
|
|
|
}
|
|
|
|
proxy.queryLogFile = config.QueryLog.File
|
|
|
|
proxy.queryLogFormat = config.QueryLog.Format
|
2018-01-20 13:27:37 +01:00
|
|
|
proxy.queryLogIgnoredQtypes = config.QueryLog.IgnoredQtypes
|
2018-01-17 17:03:42 +01:00
|
|
|
|
2018-01-20 16:59:40 +01:00
|
|
|
if len(config.NxLog.Format) == 0 {
|
|
|
|
config.NxLog.Format = "tsv"
|
|
|
|
} else {
|
|
|
|
config.NxLog.Format = strings.ToLower(config.NxLog.Format)
|
|
|
|
}
|
|
|
|
if config.NxLog.Format != "tsv" && config.NxLog.Format != "ltsv" {
|
|
|
|
return errors.New("Unsupported NX log format")
|
|
|
|
}
|
|
|
|
proxy.nxLogFile = config.NxLog.File
|
|
|
|
proxy.nxLogFormat = config.NxLog.Format
|
|
|
|
|
2020-06-26 23:18:30 +02:00
|
|
|
if len(config.BlockName.File) > 0 && len(config.BlockNameLegacy.File) > 0 {
|
2021-01-02 11:16:12 +01:00
|
|
|
return errors.New("Don't specify both [blocked_names] and [blacklist] sections - Update your config file")
|
2020-06-26 23:18:30 +02:00
|
|
|
}
|
|
|
|
if len(config.BlockNameLegacy.File) > 0 {
|
2021-01-02 11:16:12 +01:00
|
|
|
dlog.Notice("Use of [blacklist] is deprecated - Update your config file")
|
2020-06-26 23:18:30 +02:00
|
|
|
config.BlockName.File = config.BlockNameLegacy.File
|
|
|
|
config.BlockName.Format = config.BlockNameLegacy.Format
|
|
|
|
config.BlockName.LogFile = config.BlockNameLegacy.LogFile
|
|
|
|
}
|
2018-01-17 17:03:42 +01:00
|
|
|
if len(config.BlockName.Format) == 0 {
|
|
|
|
config.BlockName.Format = "tsv"
|
|
|
|
} else {
|
|
|
|
config.BlockName.Format = strings.ToLower(config.BlockName.Format)
|
|
|
|
}
|
|
|
|
if config.BlockName.Format != "tsv" && config.BlockName.Format != "ltsv" {
|
|
|
|
return errors.New("Unsupported block log format")
|
|
|
|
}
|
2018-01-17 02:40:47 +01:00
|
|
|
proxy.blockNameFile = config.BlockName.File
|
2018-01-17 17:03:42 +01:00
|
|
|
proxy.blockNameFormat = config.BlockName.Format
|
|
|
|
proxy.blockNameLogFile = config.BlockName.LogFile
|
|
|
|
|
2020-06-26 23:18:30 +02:00
|
|
|
if len(config.AllowedName.File) > 0 && len(config.WhitelistNameLegacy.File) > 0 {
|
2021-01-02 11:16:12 +01:00
|
|
|
return errors.New("Don't specify both [whitelist] and [allowed_names] sections - Update your config file")
|
2020-06-26 23:18:30 +02:00
|
|
|
}
|
|
|
|
if len(config.WhitelistNameLegacy.File) > 0 {
|
2021-01-02 11:16:12 +01:00
|
|
|
dlog.Notice("Use of [whitelist] is deprecated - Update your config file")
|
2020-06-26 23:18:30 +02:00
|
|
|
config.AllowedName.File = config.WhitelistNameLegacy.File
|
|
|
|
config.AllowedName.Format = config.WhitelistNameLegacy.Format
|
|
|
|
config.AllowedName.LogFile = config.WhitelistNameLegacy.LogFile
|
|
|
|
}
|
|
|
|
if len(config.AllowedName.Format) == 0 {
|
|
|
|
config.AllowedName.Format = "tsv"
|
2018-04-07 23:02:40 +02:00
|
|
|
} else {
|
2020-06-26 23:18:30 +02:00
|
|
|
config.AllowedName.Format = strings.ToLower(config.AllowedName.Format)
|
2018-04-07 23:02:40 +02:00
|
|
|
}
|
2020-06-26 23:18:30 +02:00
|
|
|
if config.AllowedName.Format != "tsv" && config.AllowedName.Format != "ltsv" {
|
|
|
|
return errors.New("Unsupported allowed_names log format")
|
2018-04-07 23:02:40 +02:00
|
|
|
}
|
2021-03-30 11:02:47 +02:00
|
|
|
proxy.allowNameFile = config.AllowedName.File
|
|
|
|
proxy.allowNameFormat = config.AllowedName.Format
|
|
|
|
proxy.allowNameLogFile = config.AllowedName.LogFile
|
2018-04-07 23:02:40 +02:00
|
|
|
|
2020-06-26 23:18:30 +02:00
|
|
|
if len(config.BlockIP.File) > 0 && len(config.BlockIPLegacy.File) > 0 {
|
2021-01-02 11:16:12 +01:00
|
|
|
return errors.New("Don't specify both [blocked_ips] and [ip_blacklist] sections - Update your config file")
|
2020-06-26 23:18:30 +02:00
|
|
|
}
|
|
|
|
if len(config.BlockIPLegacy.File) > 0 {
|
2021-01-02 11:16:12 +01:00
|
|
|
dlog.Notice("Use of [ip_blacklist] is deprecated - Update your config file")
|
2020-06-26 23:18:30 +02:00
|
|
|
config.BlockIP.File = config.BlockIPLegacy.File
|
|
|
|
config.BlockIP.Format = config.BlockIPLegacy.Format
|
|
|
|
config.BlockIP.LogFile = config.BlockIPLegacy.LogFile
|
|
|
|
}
|
2018-01-21 16:07:44 +01:00
|
|
|
if len(config.BlockIP.Format) == 0 {
|
|
|
|
config.BlockIP.Format = "tsv"
|
|
|
|
} else {
|
|
|
|
config.BlockIP.Format = strings.ToLower(config.BlockIP.Format)
|
|
|
|
}
|
|
|
|
if config.BlockIP.Format != "tsv" && config.BlockIP.Format != "ltsv" {
|
|
|
|
return errors.New("Unsupported IP block log format")
|
|
|
|
}
|
|
|
|
proxy.blockIPFile = config.BlockIP.File
|
|
|
|
proxy.blockIPFormat = config.BlockIP.Format
|
|
|
|
proxy.blockIPLogFile = config.BlockIP.LogFile
|
|
|
|
|
2020-11-15 20:59:58 +01:00
|
|
|
if len(config.AllowIP.Format) == 0 {
|
|
|
|
config.AllowIP.Format = "tsv"
|
|
|
|
} else {
|
|
|
|
config.AllowIP.Format = strings.ToLower(config.AllowIP.Format)
|
|
|
|
}
|
|
|
|
if config.AllowIP.Format != "tsv" && config.AllowIP.Format != "ltsv" {
|
|
|
|
return errors.New("Unsupported allowed_ips log format")
|
|
|
|
}
|
|
|
|
proxy.allowedIPFile = config.AllowIP.File
|
|
|
|
proxy.allowedIPFormat = config.AllowIP.Format
|
|
|
|
proxy.allowedIPLogFile = config.AllowIP.LogFile
|
|
|
|
|
2018-01-17 09:44:03 +01:00
|
|
|
proxy.forwardFile = config.ForwardFile
|
2018-02-04 01:43:37 +01:00
|
|
|
proxy.cloakFile = config.CloakFile
|
2021-01-02 15:10:04 +01:00
|
|
|
proxy.captivePortalMapFile = config.CaptivePortals.MapFile
|
2018-01-18 13:01:16 +01:00
|
|
|
|
2018-01-31 23:08:38 +01:00
|
|
|
allWeeklyRanges, err := ParseAllWeeklyRanges(config.AllWeeklyRanges)
|
|
|
|
if err != nil {
|
2018-01-31 22:49:40 +01:00
|
|
|
return err
|
|
|
|
}
|
2018-01-31 23:08:38 +01:00
|
|
|
proxy.allWeeklyRanges = allWeeklyRanges
|
2018-01-31 22:18:11 +01:00
|
|
|
|
2019-10-14 01:45:38 +02:00
|
|
|
if configRoutes := config.AnonymizedDNS.Routes; configRoutes != nil {
|
2019-10-14 12:08:47 +02:00
|
|
|
routes := make(map[string][]string)
|
2019-10-14 01:45:38 +02:00
|
|
|
for _, configRoute := range configRoutes {
|
2019-10-14 12:08:47 +02:00
|
|
|
routes[configRoute.ServerName] = configRoute.RelayNames
|
2019-10-14 01:45:38 +02:00
|
|
|
}
|
|
|
|
proxy.routes = &routes
|
|
|
|
}
|
2021-01-03 16:00:02 +01:00
|
|
|
proxy.skipAnonIncompatibleResolvers = config.AnonymizedDNS.SkipIncompatible
|
2020-07-03 12:58:36 +02:00
|
|
|
proxy.anonDirectCertFallback = config.AnonymizedDNS.DirectCertFallback
|
2020-03-26 13:41:57 +01:00
|
|
|
|
2023-05-24 09:20:58 +02:00
|
|
|
if len(config.TLSKeyLogFile) > 0 {
|
2023-08-11 00:17:46 +02:00
|
|
|
f, err := os.OpenFile(config.TLSKeyLogFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o600)
|
2023-05-24 09:20:58 +02:00
|
|
|
if err != nil {
|
|
|
|
dlog.Fatalf("Unable to create key log file [%s]: [%s]", config.TLSKeyLogFile, err)
|
|
|
|
}
|
|
|
|
dlog.Warnf("TLS key log file [%s] enabled", config.TLSKeyLogFile)
|
|
|
|
proxy.xTransport.keyLogWriter = f
|
|
|
|
proxy.xTransport.rebuildTransport()
|
|
|
|
}
|
|
|
|
|
2020-06-10 11:34:59 +02:00
|
|
|
if config.DoHClientX509AuthLegacy.Creds != nil {
|
2021-01-02 11:16:12 +01:00
|
|
|
return errors.New("[tls_client_auth] has been renamed to [doh_client_x509_auth] - Update your config file")
|
2020-06-10 11:34:59 +02:00
|
|
|
}
|
2021-06-07 11:23:48 +02:00
|
|
|
dohClientCreds := config.DoHClientX509Auth.Creds
|
|
|
|
if len(dohClientCreds) > 0 {
|
|
|
|
dlog.Noticef("Enabling TLS authentication")
|
|
|
|
configClientCred := dohClientCreds[0]
|
2021-06-07 11:26:37 +02:00
|
|
|
if len(dohClientCreds) > 1 {
|
|
|
|
dlog.Fatal("Only one tls_client_auth entry is currently supported")
|
|
|
|
}
|
2021-06-07 11:23:48 +02:00
|
|
|
proxy.xTransport.tlsClientCreds = DOHClientCreds{
|
2020-03-09 22:11:53 +01:00
|
|
|
clientCert: configClientCred.ClientCert,
|
|
|
|
clientKey: configClientCred.ClientKey,
|
2020-06-08 18:01:40 +02:00
|
|
|
rootCA: configClientCred.RootCA,
|
2020-03-09 22:11:53 +01:00
|
|
|
}
|
2021-06-07 11:23:48 +02:00
|
|
|
proxy.xTransport.rebuildTransport()
|
2020-03-09 22:11:53 +01:00
|
|
|
}
|
|
|
|
|
2020-03-25 20:09:46 +01:00
|
|
|
// Backwards compatibility
|
2022-03-23 17:48:48 +01:00
|
|
|
config.BrokenImplementations.FragmentsBlocked = append(
|
|
|
|
config.BrokenImplementations.FragmentsBlocked,
|
|
|
|
config.BrokenImplementations.BrokenQueryPadding...)
|
2020-03-25 20:09:46 +01:00
|
|
|
|
2020-05-19 15:57:56 +02:00
|
|
|
proxy.serversBlockingFragments = config.BrokenImplementations.FragmentsBlocked
|
2019-10-14 01:45:38 +02:00
|
|
|
|
2020-06-08 18:23:03 +02:00
|
|
|
proxy.dns64Prefixes = config.DNS64.Prefixes
|
|
|
|
proxy.dns64Resolvers = config.DNS64.Resolvers
|
|
|
|
|
2019-10-30 14:30:31 +01:00
|
|
|
if *flags.ListAll {
|
2018-02-02 14:51:14 +01:00
|
|
|
config.ServerNames = nil
|
2019-02-23 14:54:22 +01:00
|
|
|
config.DisabledServerNames = nil
|
2018-02-01 21:48:46 +01:00
|
|
|
config.SourceRequireDNSSEC = false
|
|
|
|
config.SourceRequireNoFilter = false
|
|
|
|
config.SourceRequireNoLog = false
|
|
|
|
config.SourceIPv4 = true
|
|
|
|
config.SourceIPv6 = true
|
2018-04-01 16:35:32 +02:00
|
|
|
config.SourceDNSCrypt = true
|
2018-02-06 14:11:58 +01:00
|
|
|
config.SourceDoH = true
|
2021-06-07 13:21:58 +02:00
|
|
|
config.SourceODoH = true
|
2018-02-01 21:48:46 +01:00
|
|
|
}
|
|
|
|
|
2021-01-01 14:04:12 +01:00
|
|
|
var requiredProps stamps.ServerInformalProperties
|
|
|
|
if config.SourceRequireDNSSEC {
|
|
|
|
requiredProps |= stamps.ServerInformalPropertyDNSSEC
|
|
|
|
}
|
|
|
|
if config.SourceRequireNoLog {
|
|
|
|
requiredProps |= stamps.ServerInformalPropertyNoLog
|
|
|
|
}
|
|
|
|
if config.SourceRequireNoFilter {
|
|
|
|
requiredProps |= stamps.ServerInformalPropertyNoFilter
|
|
|
|
}
|
|
|
|
proxy.requiredProps = requiredProps
|
|
|
|
proxy.ServerNames = config.ServerNames
|
|
|
|
proxy.DisabledServerNames = config.DisabledServerNames
|
|
|
|
proxy.SourceIPv4 = config.SourceIPv4
|
|
|
|
proxy.SourceIPv6 = config.SourceIPv6
|
|
|
|
proxy.SourceDNSCrypt = config.SourceDNSCrypt
|
|
|
|
proxy.SourceDoH = config.SourceDoH
|
2021-06-07 13:21:58 +02:00
|
|
|
proxy.SourceODoH = config.SourceODoH
|
2021-01-01 14:04:12 +01:00
|
|
|
|
2018-11-15 14:24:26 +01:00
|
|
|
netprobeTimeout := config.NetprobeTimeout
|
2018-11-16 18:13:39 +01:00
|
|
|
flag.Visit(func(flag *flag.Flag) {
|
2019-10-30 14:30:31 +01:00
|
|
|
if flag.Name == "netprobe-timeout" && flags.NetprobeTimeoutOverride != nil {
|
|
|
|
netprobeTimeout = *flags.NetprobeTimeoutOverride
|
2018-11-16 18:13:39 +01:00
|
|
|
}
|
|
|
|
})
|
2019-06-04 01:37:59 +02:00
|
|
|
netprobeAddress := DefaultNetprobeAddress
|
|
|
|
if len(config.NetprobeAddress) > 0 {
|
|
|
|
netprobeAddress = config.NetprobeAddress
|
2021-02-20 18:50:42 +01:00
|
|
|
} else if len(config.BootstrapResolvers) > 0 {
|
|
|
|
netprobeAddress = config.BootstrapResolvers[0]
|
2019-06-04 01:37:59 +02:00
|
|
|
}
|
2022-08-03 14:52:08 +02:00
|
|
|
if !isCommandMode {
|
2020-08-03 18:05:42 +02:00
|
|
|
if err := NetProbe(proxy, netprobeAddress, netprobeTimeout); err != nil {
|
2020-06-10 11:01:59 +02:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
for _, listenAddrStr := range proxy.listenAddresses {
|
|
|
|
proxy.addDNSListener(listenAddrStr)
|
|
|
|
}
|
|
|
|
for _, listenAddrStr := range proxy.localDoHListenAddresses {
|
|
|
|
proxy.addLocalDoHListener(listenAddrStr)
|
|
|
|
}
|
|
|
|
if err := proxy.addSystemDListeners(); err != nil {
|
2020-07-27 16:01:44 +02:00
|
|
|
return err
|
2020-06-10 11:01:59 +02:00
|
|
|
}
|
2020-04-26 14:57:18 +02:00
|
|
|
}
|
2020-04-20 12:27:53 +02:00
|
|
|
// if 'userName' is set and we are the parent process drop privilege and exit
|
|
|
|
if len(proxy.userName) > 0 && !proxy.child {
|
|
|
|
proxy.dropPrivilege(proxy.userName, FileDescriptors)
|
2022-03-23 17:48:48 +01:00
|
|
|
return errors.New(
|
|
|
|
"Dropping privileges is not supporting on this operating system. Unset `user_name` in the configuration file",
|
|
|
|
)
|
2020-04-20 12:27:53 +02:00
|
|
|
}
|
2018-07-05 18:05:24 +02:00
|
|
|
if !config.OfflineMode {
|
|
|
|
if err := config.loadSources(proxy); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if len(proxy.registeredServers) == 0 {
|
|
|
|
return errors.New("No servers configured")
|
|
|
|
}
|
2018-01-31 08:27:59 +01:00
|
|
|
}
|
2019-10-30 14:30:31 +01:00
|
|
|
if *flags.List || *flags.ListAll {
|
2023-09-23 18:37:52 +02:00
|
|
|
if err := config.printRegisteredServers(proxy, *flags.JSONOutput, *flags.IncludeRelays); err != nil {
|
2020-07-27 16:01:44 +02:00
|
|
|
return err
|
|
|
|
}
|
2018-01-31 08:27:59 +01:00
|
|
|
os.Exit(0)
|
|
|
|
}
|
2019-10-14 11:02:13 +02:00
|
|
|
if proxy.routes != nil && len(*proxy.routes) > 0 {
|
2019-10-20 14:19:21 +02:00
|
|
|
hasSpecificRoutes := false
|
2019-10-14 11:02:13 +02:00
|
|
|
for _, server := range proxy.registeredServers {
|
|
|
|
if via, ok := (*proxy.routes)[server.name]; ok {
|
2022-03-23 17:48:48 +01:00
|
|
|
if server.stamp.Proto != stamps.StampProtoTypeDNSCrypt &&
|
|
|
|
server.stamp.Proto != stamps.StampProtoTypeODoHTarget {
|
|
|
|
dlog.Errorf(
|
|
|
|
"DNS anonymization is only supported with the DNSCrypt and ODoH protocols - Connections to [%v] cannot be anonymized",
|
|
|
|
server.name,
|
|
|
|
)
|
2019-10-20 14:19:21 +02:00
|
|
|
} else {
|
|
|
|
dlog.Noticef("Anonymized DNS: routing [%v] via %v", server.name, via)
|
|
|
|
}
|
|
|
|
hasSpecificRoutes = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if via, ok := (*proxy.routes)["*"]; ok {
|
|
|
|
if hasSpecificRoutes {
|
|
|
|
dlog.Noticef("Anonymized DNS: routing everything else via %v", via)
|
|
|
|
} else {
|
|
|
|
dlog.Noticef("Anonymized DNS: routing everything via %v", via)
|
2019-10-14 11:02:13 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-10-30 14:30:31 +01:00
|
|
|
if *flags.Check {
|
2018-02-19 18:35:06 +01:00
|
|
|
dlog.Notice("Configuration successfully checked")
|
|
|
|
os.Exit(0)
|
|
|
|
}
|
2018-01-31 08:27:59 +01:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-09-23 18:37:52 +02:00
|
|
|
func (config *Config) printRegisteredServers(proxy *Proxy, jsonOutput bool, includeRelays bool) error {
|
2018-01-31 09:42:56 +01:00
|
|
|
var summary []ServerSummary
|
2023-09-23 18:37:52 +02:00
|
|
|
if includeRelays {
|
|
|
|
for _, registeredRelay := range proxy.registeredRelays {
|
|
|
|
addrStr, port := registeredRelay.stamp.ServerAddrStr, stamps.DefaultPort
|
|
|
|
var hostAddr string
|
|
|
|
hostAddr, port = ExtractHostAndPort(addrStr, port)
|
|
|
|
addrs := make([]string, 0)
|
|
|
|
if (registeredRelay.stamp.Proto == stamps.StampProtoTypeDoH || registeredRelay.stamp.Proto == stamps.StampProtoTypeODoHTarget) &&
|
|
|
|
len(registeredRelay.stamp.ProviderName) > 0 {
|
|
|
|
providerName := registeredRelay.stamp.ProviderName
|
|
|
|
var host string
|
|
|
|
host, port = ExtractHostAndPort(providerName, port)
|
|
|
|
addrs = append(addrs, host)
|
|
|
|
}
|
|
|
|
if len(addrStr) > 0 {
|
|
|
|
addrs = append(addrs, hostAddr)
|
|
|
|
}
|
2023-09-23 22:52:43 +02:00
|
|
|
nolog := true
|
|
|
|
nofilter := true
|
|
|
|
if registeredRelay.stamp.Proto == stamps.StampProtoTypeODoHRelay {
|
|
|
|
nolog = registeredRelay.stamp.Props&stamps.ServerInformalPropertyNoLog != 0
|
|
|
|
}
|
2023-09-23 18:37:52 +02:00
|
|
|
serverSummary := ServerSummary{
|
|
|
|
Name: registeredRelay.name,
|
|
|
|
Proto: registeredRelay.stamp.Proto.String(),
|
|
|
|
IPv6: strings.HasPrefix(addrStr, "["),
|
|
|
|
Ports: []int{port},
|
|
|
|
Addrs: addrs,
|
2023-09-23 22:52:43 +02:00
|
|
|
NoLog: nolog,
|
|
|
|
NoFilter: nofilter,
|
2023-09-23 18:37:52 +02:00
|
|
|
Description: registeredRelay.description,
|
|
|
|
Stamp: registeredRelay.stamp.String(),
|
|
|
|
}
|
|
|
|
if jsonOutput {
|
|
|
|
summary = append(summary, serverSummary)
|
|
|
|
} else {
|
|
|
|
fmt.Println(serverSummary.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-31 09:42:56 +01:00
|
|
|
for _, registeredServer := range proxy.registeredServers {
|
2018-04-14 15:03:21 +02:00
|
|
|
addrStr, port := registeredServer.stamp.ServerAddrStr, stamps.DefaultPort
|
2019-10-11 12:16:04 +02:00
|
|
|
var hostAddr string
|
|
|
|
hostAddr, port = ExtractHostAndPort(addrStr, port)
|
2018-03-28 12:22:37 +02:00
|
|
|
addrs := make([]string, 0)
|
2022-03-23 17:48:48 +01:00
|
|
|
if (registeredServer.stamp.Proto == stamps.StampProtoTypeDoH || registeredServer.stamp.Proto == stamps.StampProtoTypeODoHTarget) &&
|
|
|
|
len(registeredServer.stamp.ProviderName) > 0 {
|
2018-04-14 15:03:21 +02:00
|
|
|
providerName := registeredServer.stamp.ProviderName
|
2018-03-28 12:22:37 +02:00
|
|
|
var host string
|
|
|
|
host, port = ExtractHostAndPort(providerName, port)
|
|
|
|
addrs = append(addrs, host)
|
|
|
|
}
|
|
|
|
if len(addrStr) > 0 {
|
2019-10-11 12:16:04 +02:00
|
|
|
addrs = append(addrs, hostAddr)
|
2018-02-01 21:48:46 +01:00
|
|
|
}
|
2023-09-23 18:46:11 +02:00
|
|
|
dnssec := registeredServer.stamp.Props&stamps.ServerInformalPropertyDNSSEC != 0
|
2018-01-31 09:42:56 +01:00
|
|
|
serverSummary := ServerSummary{
|
|
|
|
Name: registeredServer.name,
|
2018-04-14 15:03:21 +02:00
|
|
|
Proto: registeredServer.stamp.Proto.String(),
|
2018-02-01 21:48:46 +01:00
|
|
|
IPv6: strings.HasPrefix(addrStr, "["),
|
|
|
|
Ports: []int{port},
|
2018-03-28 12:22:37 +02:00
|
|
|
Addrs: addrs,
|
2023-09-23 18:46:11 +02:00
|
|
|
DNSSEC: &dnssec,
|
2018-04-14 15:03:21 +02:00
|
|
|
NoLog: registeredServer.stamp.Props&stamps.ServerInformalPropertyNoLog != 0,
|
|
|
|
NoFilter: registeredServer.stamp.Props&stamps.ServerInformalPropertyNoFilter != 0,
|
2018-01-31 09:42:56 +01:00
|
|
|
Description: registeredServer.description,
|
2019-10-23 23:30:29 +02:00
|
|
|
Stamp: registeredServer.stamp.String(),
|
2018-01-31 09:42:56 +01:00
|
|
|
}
|
|
|
|
if jsonOutput {
|
|
|
|
summary = append(summary, serverSummary)
|
|
|
|
} else {
|
|
|
|
fmt.Println(serverSummary.Name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if jsonOutput {
|
|
|
|
jsonStr, err := json.MarshalIndent(summary, "", " ")
|
|
|
|
if err != nil {
|
2020-07-27 16:01:44 +02:00
|
|
|
return err
|
2018-01-31 09:42:56 +01:00
|
|
|
}
|
|
|
|
fmt.Print(string(jsonStr))
|
|
|
|
}
|
2020-07-27 16:01:44 +02:00
|
|
|
return nil
|
2018-01-31 09:42:56 +01:00
|
|
|
}
|
|
|
|
|
2018-01-31 08:27:59 +01:00
|
|
|
func (config *Config) loadSources(proxy *Proxy) error {
|
2020-06-11 11:10:33 +02:00
|
|
|
for cfgSourceName, cfgSource_ := range config.SourcesConfig {
|
|
|
|
cfgSource := cfgSource_
|
2021-01-22 15:06:49 +01:00
|
|
|
rand.Shuffle(len(cfgSource.URLs), func(i, j int) {
|
|
|
|
cfgSource.URLs[i], cfgSource.URLs[j] = cfgSource.URLs[j], cfgSource.URLs[i]
|
|
|
|
})
|
2021-01-01 14:04:12 +01:00
|
|
|
if err := config.loadSource(proxy, cfgSourceName, &cfgSource); err != nil {
|
2018-01-31 08:32:44 +01:00
|
|
|
return err
|
2018-01-14 00:08:46 +01:00
|
|
|
}
|
2018-01-10 12:01:49 +01:00
|
|
|
}
|
2020-12-12 21:57:04 +01:00
|
|
|
for name, config := range config.StaticsConfig {
|
|
|
|
if stamp, err := stamps.NewServerStampFromString(config.Stamp); err == nil {
|
|
|
|
if stamp.Proto == stamps.StampProtoTypeDNSCryptRelay || stamp.Proto == stamps.StampProtoTypeODoHRelay {
|
|
|
|
dlog.Debugf("Adding [%s] to the set of available static relays", name)
|
|
|
|
registeredServer := RegisteredServer{name: name, stamp: stamp, description: "static relay"}
|
|
|
|
proxy.registeredRelays = append(proxy.registeredRelays, registeredServer)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2018-01-17 21:41:36 +01:00
|
|
|
if len(config.ServerNames) == 0 {
|
2019-10-20 11:53:50 +02:00
|
|
|
for serverName := range config.StaticsConfig {
|
2018-01-17 21:41:36 +01:00
|
|
|
config.ServerNames = append(config.ServerNames, serverName)
|
|
|
|
}
|
|
|
|
}
|
2018-01-10 12:01:49 +01:00
|
|
|
for _, serverName := range config.ServerNames {
|
2019-10-20 11:53:50 +02:00
|
|
|
staticConfig, ok := config.StaticsConfig[serverName]
|
2018-01-10 12:01:49 +01:00
|
|
|
if !ok {
|
2018-01-14 00:08:46 +01:00
|
|
|
continue
|
2018-01-10 12:01:49 +01:00
|
|
|
}
|
2018-01-31 08:43:49 +01:00
|
|
|
if len(staticConfig.Stamp) == 0 {
|
2020-07-27 16:01:44 +02:00
|
|
|
return fmt.Errorf("Missing stamp for the static [%s] definition", serverName)
|
2018-01-20 14:13:11 +01:00
|
|
|
}
|
2018-04-14 15:03:21 +02:00
|
|
|
stamp, err := stamps.NewServerStampFromString(staticConfig.Stamp)
|
2018-01-20 14:13:11 +01:00
|
|
|
if err != nil {
|
2020-07-27 16:01:44 +02:00
|
|
|
return fmt.Errorf("Stamp error for the static [%s] definition: [%v]", serverName, err)
|
2018-01-10 12:01:49 +01:00
|
|
|
}
|
2018-01-31 08:27:59 +01:00
|
|
|
proxy.registeredServers = append(proxy.registeredServers, RegisteredServer{name: serverName, stamp: stamp})
|
2018-01-30 17:51:47 +01:00
|
|
|
}
|
2023-06-24 22:23:12 +02:00
|
|
|
if err := proxy.updateRegisteredServers(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2021-01-02 19:04:53 +01:00
|
|
|
rs1 := proxy.registeredServers
|
|
|
|
rs2 := proxy.serversInfo.registeredServers
|
|
|
|
rand.Shuffle(len(rs1), func(i, j int) {
|
|
|
|
rs1[i], rs1[j] = rs1[j], rs1[i]
|
|
|
|
})
|
|
|
|
rand.Shuffle(len(rs2), func(i, j int) {
|
|
|
|
rs2[i], rs2[j] = rs2[j], rs2[i]
|
|
|
|
})
|
2018-01-10 12:01:49 +01:00
|
|
|
return nil
|
|
|
|
}
|
2018-01-14 00:08:46 +01:00
|
|
|
|
2021-01-01 14:04:12 +01:00
|
|
|
func (config *Config) loadSource(proxy *Proxy, cfgSourceName string, cfgSource *SourceConfig) error {
|
2018-03-28 13:36:19 +02:00
|
|
|
if len(cfgSource.URLs) == 0 {
|
|
|
|
if len(cfgSource.URL) == 0 {
|
|
|
|
dlog.Debugf("Missing URLs for source [%s]", cfgSourceName)
|
|
|
|
} else {
|
|
|
|
cfgSource.URLs = []string{cfgSource.URL}
|
|
|
|
}
|
2018-01-31 08:32:44 +01:00
|
|
|
}
|
|
|
|
if cfgSource.MinisignKeyStr == "" {
|
|
|
|
return fmt.Errorf("Missing Minisign key for source [%s]", cfgSourceName)
|
|
|
|
}
|
|
|
|
if cfgSource.CacheFile == "" {
|
|
|
|
return fmt.Errorf("Missing cache file for source [%s]", cfgSourceName)
|
|
|
|
}
|
|
|
|
if cfgSource.FormatStr == "" {
|
2018-01-31 14:23:44 +01:00
|
|
|
cfgSource.FormatStr = "v2"
|
2018-01-31 08:32:44 +01:00
|
|
|
}
|
2023-08-11 00:51:34 +02:00
|
|
|
if cfgSource.RefreshDelay <= 0 {
|
|
|
|
cfgSource.RefreshDelay = 72
|
2018-01-31 08:32:44 +01:00
|
|
|
}
|
2023-08-11 11:42:12 +02:00
|
|
|
cfgSource.RefreshDelay = Min(168, Max(24, cfgSource.RefreshDelay))
|
2022-03-23 17:48:48 +01:00
|
|
|
source, err := NewSource(
|
|
|
|
cfgSourceName,
|
|
|
|
proxy.xTransport,
|
|
|
|
cfgSource.URLs,
|
|
|
|
cfgSource.MinisignKeyStr,
|
|
|
|
cfgSource.CacheFile,
|
|
|
|
cfgSource.FormatStr,
|
|
|
|
time.Duration(cfgSource.RefreshDelay)*time.Hour,
|
|
|
|
cfgSource.Prefix,
|
|
|
|
)
|
2018-01-31 08:32:44 +01:00
|
|
|
if err != nil {
|
2023-06-24 22:08:01 +02:00
|
|
|
if len(source.bin) <= 0 {
|
2020-05-30 08:38:04 +02:00
|
|
|
dlog.Criticalf("Unable to retrieve source [%s]: [%s]", cfgSourceName, err)
|
|
|
|
return err
|
|
|
|
}
|
2020-05-31 13:46:44 +02:00
|
|
|
dlog.Infof("Downloading [%s] failed: %v, using cache file to startup", source.name, err)
|
2018-01-31 08:32:44 +01:00
|
|
|
}
|
2019-10-31 02:22:48 +01:00
|
|
|
proxy.sources = append(proxy.sources, source)
|
2018-01-31 08:32:44 +01:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2018-01-14 00:08:46 +01:00
|
|
|
func includesName(names []string, name string) bool {
|
|
|
|
for _, found := range names {
|
|
|
|
if strings.EqualFold(found, name) {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|
2018-02-03 10:46:47 +01:00
|
|
|
|
2019-12-09 12:11:24 +01:00
|
|
|
func cdFileDir(fileName string) error {
|
|
|
|
return os.Chdir(filepath.Dir(fileName))
|
2018-02-03 10:46:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func cdLocal() {
|
|
|
|
exeFileName, err := os.Executable()
|
|
|
|
if err != nil {
|
2022-03-23 17:48:48 +01:00
|
|
|
dlog.Warnf(
|
|
|
|
"Unable to determine the executable directory: [%s] -- You will need to specify absolute paths in the configuration file",
|
|
|
|
err,
|
|
|
|
)
|
2020-03-13 18:44:30 +01:00
|
|
|
} else if err := os.Chdir(filepath.Dir(exeFileName)); err != nil {
|
2019-12-09 10:07:05 +01:00
|
|
|
dlog.Warnf("Unable to change working directory to [%s]: %s", exeFileName, err)
|
2019-12-09 09:49:33 +01:00
|
|
|
}
|
2018-02-03 10:46:47 +01:00
|
|
|
}
|
2019-10-20 20:35:25 +02:00
|
|
|
|
2019-11-01 23:06:42 +01:00
|
|
|
func isIPAndPort(addrStr string) error {
|
2019-11-01 23:05:17 +01:00
|
|
|
host, port := ExtractHostAndPort(addrStr, -1)
|
2022-08-10 22:24:36 +02:00
|
|
|
if ip := ParseIP(host); ip == nil {
|
2019-11-01 23:05:17 +01:00
|
|
|
return fmt.Errorf("Host does not parse as IP '%s'", addrStr)
|
2019-10-20 20:35:25 +02:00
|
|
|
} else if port == -1 {
|
2019-11-01 23:05:17 +01:00
|
|
|
return fmt.Errorf("Port missing '%s'", addrStr)
|
2019-10-20 20:35:25 +02:00
|
|
|
} else if _, err := strconv.ParseUint(strconv.Itoa(port), 10, 16); err != nil {
|
2019-11-01 23:05:17 +01:00
|
|
|
return fmt.Errorf("Port does not parse '%s' [%v]", addrStr, err)
|
2019-10-20 20:35:25 +02:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|