Implement an offline mode

Fixes #528
This commit is contained in:
Frank Denis 2018-07-05 18:05:24 +02:00
parent 4a3be6086e
commit c73e95256d
3 changed files with 42 additions and 20 deletions

View File

@ -70,6 +70,7 @@ type Config struct {
TLSCipherSuite []uint16 `toml:"tls_cipher_suite"`
NetprobeAddress string `toml:"netprobe_address"`
NetprobeTimeout int `toml:"netprobe_timeout"`
OfflineMode bool `toml:"offline_mode"`
}
func newConfig() Config {
@ -104,6 +105,7 @@ func newConfig() Config {
TLSCipherSuite: nil,
NetprobeAddress: "9.9.9.9:53",
NetprobeTimeout: 30,
OfflineMode: false,
}
}
@ -397,12 +399,13 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error {
}
netProbe(config.NetprobeAddress, config.NetprobeTimeout)
if err := config.loadSources(proxy); err != nil {
return err
}
if len(proxy.registeredServers) == 0 {
return errors.New("No servers configured")
if !config.OfflineMode {
if err := config.loadSources(proxy); err != nil {
return err
}
if len(proxy.registeredServers) == 0 {
return errors.New("No servers configured")
}
}
if *list || *listAll {
config.printRegisteredServers(proxy, *jsonOutput)

View File

@ -186,6 +186,13 @@ ignore_system_dns = false
netprobe_timeout = 30
## Offline mode - Do not use any remote encrypted servers.
## The proxy will remain fully functional to respond to queries that
## plugins can handle directly (forwarding, cloaking, ...)
# offline_mode = false
## Automatic log files rotation
# Maximum log files size in MB

View File

@ -3,9 +3,9 @@ package main
import (
"io"
"io/ioutil"
"os"
"math/rand"
"net"
"os"
"sync/atomic"
"time"
@ -119,7 +119,7 @@ func (proxy *Proxy) StartProxy() {
FileDescriptors = append(FileDescriptors, fdUDP)
FileDescriptors = append(FileDescriptors, fdTCP)
// if 'username' is set and we are the child process
// if 'username' is set and we are the child process
} else {
// child
listenerUDP, err := net.FilePacketConn(os.NewFile(uintptr(3+FileDescriptorNum), "listenerUDP"))
@ -159,16 +159,18 @@ func (proxy *Proxy) StartProxy() {
dlog.Notice("dnscrypt-proxy is waiting for at least one server to be reachable")
}
proxy.prefetcher(&proxy.urlsToPrefetch)
go func() {
for {
delay := proxy.certRefreshDelay
if proxy.serversInfo.liveServers() == 0 {
delay = proxy.certRefreshDelayAfterFailure
if len(proxy.serversInfo.registeredServers) > 0 {
go func() {
for {
delay := proxy.certRefreshDelay
if proxy.serversInfo.liveServers() == 0 {
delay = proxy.certRefreshDelayAfterFailure
}
clocksmith.Sleep(delay)
proxy.serversInfo.refresh(proxy)
}
clocksmith.Sleep(delay)
proxy.serversInfo.refresh(proxy)
}
}()
}()
}
}
func (proxy *Proxy) prefetcher(urlsToPrefetch *[]URLToPrefetch) {
@ -318,7 +320,7 @@ func (proxy *Proxy) clientsCountDec() {
}
func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto string, serverProto string, query []byte, clientAddr *net.Addr, clientPc net.Conn) {
if len(query) < MinDNSPacketSize || serverInfo == nil {
if len(query) < MinDNSPacketSize {
return
}
pluginsState := NewPluginsState(proxy, clientProto, clientAddr)
@ -342,7 +344,7 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
} else {
pluginsState.returnCode = PluginsReturnCodeForward
}
if len(response) == 0 {
if len(response) == 0 && serverInfo != nil {
var ttl *uint32
if serverInfo.Proto == stamps.StampProtoTypeDNSCrypt {
sharedKey, encryptedQuery, clientNonce, err := proxy.Encrypt(serverInfo, query, serverProto)
@ -408,6 +410,14 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
serverInfo.noticeSuccess(proxy)
}
}
if len(response) < MinDNSPacketSize || len(response) > MaxDNSPacketSize {
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
if serverInfo != nil {
serverInfo.noticeFailure(proxy)
}
return
}
if clientProto == "udp" {
if len(response) > MaxDNSUDPPacketSize {
response, err = TruncatedResponse(response)
@ -428,7 +438,9 @@ func (proxy *Proxy) processIncomingQuery(serverInfo *ServerInfo, clientProto str
if err != nil {
pluginsState.returnCode = PluginsReturnCodeParseError
pluginsState.ApplyLoggingPlugins(&proxy.pluginsGlobals)
serverInfo.noticeFailure(proxy)
if serverInfo != nil {
serverInfo.noticeFailure(proxy)
}
return
}
clientPc.Write(response)