Skip to content

Commit 1c27d6c

Browse files
committed
Improved error handling
1 parent 7fbb4c5 commit 1c27d6c

2 files changed

Lines changed: 73 additions & 92 deletions

File tree

dnscrypt-proxy/main.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,14 @@ func (proxy *Proxy) prefetcher(urlsToPrefetch *[]URLToPrefetch) {
187187
urlToPrefetch := &(*urlsToPrefetch)[i]
188188
if now.After(urlToPrefetch.when) {
189189
dlog.Debugf("Prefetching [%s]", urlToPrefetch.url)
190-
PrefetchSourceURL(urlToPrefetch)
190+
if err := PrefetchSourceURL(urlToPrefetch); err != nil {
191+
dlog.Debugf("Prefetching [%s] failed: %s", err)
192+
} else {
193+
dlog.Debugf("Prefetching [%s] succeeded. Next refresh scheduled for %v", urlToPrefetch.url, urlToPrefetch.when)
194+
}
191195
}
192196
}
193-
time.Sleep(60 * time.Second)
197+
time.Sleep(5 * time.Second)
194198
}
195199
}()
196200
}

dnscrypt-proxy/sources.go

Lines changed: 67 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"encoding/csv"
5+
"errors"
56
"fmt"
67
"io/ioutil"
78
"net/http"
@@ -23,6 +24,7 @@ const (
2324

2425
const (
2526
SourcesUpdateDelayAfterFailure = time.Duration(1) * time.Minute
27+
SourcesUpdateDelay = time.Duration(24) * time.Hour
2628
)
2729

2830
type Source struct {
@@ -31,67 +33,59 @@ type Source struct {
3133
in string
3234
}
3335

34-
func fetchFromCache(cacheFile string) ([]byte, error) {
35-
dlog.Debugf("Loading source information from cache file [%s]", cacheFile)
36-
return ioutil.ReadFile(cacheFile)
36+
func fetchFromCache(cacheFile string) (in string, delayTillNextUpdate time.Duration, err error) {
37+
fi, err := os.Stat(cacheFile)
38+
if err != nil {
39+
delayTillNextUpdate = time.Duration(0)
40+
return
41+
}
42+
elapsed := time.Since(fi.ModTime())
43+
if elapsed < SourcesUpdateDelay {
44+
dlog.Debugf("Cache file [%s] is still fresh", cacheFile)
45+
delayTillNextUpdate = SourcesUpdateDelay - elapsed
46+
} else {
47+
dlog.Debugf("Cache file [%s] needs to be refreshed", cacheFile)
48+
delayTillNextUpdate = time.Duration(0)
49+
}
50+
var bin []byte
51+
bin, err = ioutil.ReadFile(cacheFile)
52+
if err != nil {
53+
delayTillNextUpdate = time.Duration(0)
54+
return
55+
}
56+
in = string(bin)
57+
return
3758
}
3859

39-
func fetchWithCache(url string, cacheFile string, refreshDelay time.Duration) (in string, cached bool, fromBackup bool, delayTillNextUpdate time.Duration, err error) {
40-
var bin []byte
41-
cached, fromBackup, usableCache, hotCache := false, false, false, false
42-
delayTillNextUpdate = refreshDelay
43-
fi, err := os.Stat(cacheFile)
44-
var elapsed time.Duration
60+
func fetchWithCache(url string, cacheFile string) (in string, cached bool, delayTillNextUpdate time.Duration, err error) {
61+
cached = false
62+
in, delayTillNextUpdate, err = fetchFromCache(cacheFile)
4563
if err == nil {
46-
usableCache = true
47-
dlog.Debugf("Cache file present for [%s]", url)
48-
elapsed = time.Since(fi.ModTime())
49-
if elapsed < refreshDelay && elapsed >= 0 {
50-
hotCache = true
51-
}
64+
dlog.Debugf("Delay till next update: %v", delayTillNextUpdate)
65+
cached = true
66+
return
67+
}
68+
var resp *http.Response
69+
dlog.Infof("Loading source information from URL [%s]", url)
70+
resp, err = http.Get(url)
71+
if err == nil && resp != nil && (resp.StatusCode < 200 || resp.StatusCode > 299) {
72+
err = fmt.Errorf("Webserver returned code %d", resp.StatusCode)
73+
return
74+
} else if err != nil {
75+
return
76+
} else if resp == nil {
77+
err = errors.New("Webserver returned an error")
78+
return
5279
}
53-
if hotCache {
54-
bin, err = fetchFromCache(cacheFile)
55-
if err == nil {
56-
dlog.Debugf("Cache is still fresh for [%s]", url)
57-
cached = true
58-
delayTillNextUpdate = refreshDelay - elapsed
59-
}
60-
}
61-
if !cached {
62-
var resp *http.Response
63-
dlog.Infof("Loading source information from URL [%s]", url)
64-
resp, err = http.Get(url)
65-
if err == nil && resp != nil && (resp.StatusCode < 200 || resp.StatusCode > 299) {
66-
err = fmt.Errorf("Webserver returned code %d", resp.StatusCode)
67-
}
68-
if err != nil {
69-
delayTillNextUpdate = time.Duration(0)
70-
if usableCache {
71-
dlog.Debugf("Falling back to cached version of [%s]", url)
72-
bin, err = fetchFromCache(cacheFile)
73-
}
74-
if err != nil {
75-
return
76-
}
77-
fromBackup = true
78-
} else {
79-
bin, err = ioutil.ReadAll(resp.Body)
80-
resp.Body.Close()
81-
if err != nil {
82-
delayTillNextUpdate = time.Duration(0)
83-
if usableCache {
84-
bin, err = fetchFromCache(cacheFile)
85-
}
86-
if err != nil {
87-
return
88-
}
89-
fromBackup = true
90-
}
91-
}
80+
var bin []byte
81+
bin, err = ioutil.ReadAll(resp.Body)
82+
resp.Body.Close()
83+
if err != nil {
84+
return
9285
}
9386
err = nil
9487
in = string(bin)
88+
delayTillNextUpdate = SourcesUpdateDelay
9589
return
9690
}
9791

@@ -106,6 +100,7 @@ type URLToPrefetch struct {
106100
}
107101

108102
func NewSource(url string, minisignKeyStr string, cacheFile string, formatStr string, refreshDelay time.Duration) (Source, []URLToPrefetch, error) {
103+
_ = refreshDelay
109104
source := Source{url: url}
110105
if formatStr != "v1" {
111106
return source, []URLToPrefetch{}, fmt.Errorf("Unsupported source format: [%s]", formatStr)
@@ -115,23 +110,17 @@ func NewSource(url string, minisignKeyStr string, cacheFile string, formatStr st
115110
if err != nil {
116111
return source, []URLToPrefetch{}, err
117112
}
113+
now := time.Now()
114+
urlsToPrefetch := []URLToPrefetch{}
115+
118116
sigURL := url + ".minisig"
119-
when := time.Now()
120-
urlsToPrefetch := []URLToPrefetch{
121-
URLToPrefetch{url: url, cacheFile: cacheFile, when: when},
122-
URLToPrefetch{url: sigURL, cacheFile: cacheFile, when: when},
123-
}
124-
in, cached, fromBackup, delayTillNextUpdate, err := fetchWithCache(url, cacheFile, refreshDelay)
125-
if err != nil {
126-
dlog.Debugf("Scheduling [%s] for prefetch", url)
127-
return source, urlsToPrefetch, err
128-
}
117+
in, cached, delayTillNextUpdate, err := fetchWithCache(url, cacheFile)
118+
urlsToPrefetch = append(urlsToPrefetch, URLToPrefetch{url: url, cacheFile: cacheFile, when: now.Add(delayTillNextUpdate)})
119+
129120
sigCacheFile := cacheFile + ".minisig"
130-
sigStr, sigCached, sigFromBackup, sigDelayTillNextUpdate, err := fetchWithCache(sigURL, sigCacheFile, refreshDelay)
131-
if err != nil {
132-
dlog.Debugf("Scheduling [%s] for prefetch", sigURL)
133-
return source, urlsToPrefetch, err
134-
}
121+
sigStr, sigCached, sigDelayTillNextUpdate, err := fetchWithCache(sigURL, sigCacheFile)
122+
urlsToPrefetch = append(urlsToPrefetch, URLToPrefetch{url: sigURL, cacheFile: sigCacheFile, when: now.Add(sigDelayTillNextUpdate)})
123+
135124
signature, err := minisign.DecodeSignature(sigStr)
136125
if err != nil {
137126
os.Remove(cacheFile)
@@ -144,27 +133,18 @@ func NewSource(url string, minisignKeyStr string, cacheFile string, formatStr st
144133
os.Remove(sigCacheFile)
145134
return source, urlsToPrefetch, err
146135
}
147-
if !cached && !fromBackup {
136+
if !cached {
148137
if err = AtomicFileWrite(cacheFile, []byte(in)); err != nil {
149-
return source, urlsToPrefetch, err
138+
dlog.Warnf("%s: %s", cacheFile, err)
150139
}
151140
}
152-
if !sigCached && !fromBackup {
141+
if !sigCached {
153142
if err = AtomicFileWrite(sigCacheFile, []byte(sigStr)); err != nil {
154-
return source, urlsToPrefetch, err
143+
dlog.Warnf("%s: %s", sigCacheFile, err)
155144
}
156145
}
157146
dlog.Noticef("Source [%s] loaded", url)
158147
source.in = in
159-
if sigDelayTillNextUpdate < delayTillNextUpdate {
160-
delayTillNextUpdate = sigDelayTillNextUpdate
161-
}
162-
when = time.Now().Add(delayTillNextUpdate)
163-
if !fromBackup && !sigFromBackup {
164-
for i := range urlsToPrefetch {
165-
urlsToPrefetch[i].when = when
166-
}
167-
}
168148
return source, urlsToPrefetch, nil
169149
}
170150

@@ -210,13 +190,10 @@ func (source *Source) Parse() ([]RegisteredServer, error) {
210190
}
211191

212192
func PrefetchSourceURL(urlToPrefetch *URLToPrefetch) error {
213-
_, _, fromBackup, _, err := fetchWithCache(urlToPrefetch.url, urlToPrefetch.cacheFile, time.Duration(0))
214-
if err != nil {
215-
dlog.Debugf("[%s]: %s", urlToPrefetch.url, err)
216-
return err
217-
}
218-
if !fromBackup {
219-
urlToPrefetch.when = urlToPrefetch.when.Add(24 * time.Hour)
193+
in, _, delayTillNextUpdate, err := fetchWithCache(urlToPrefetch.url, urlToPrefetch.cacheFile)
194+
if err == nil {
195+
AtomicFileWrite(urlToPrefetch.cacheFile, []byte(in))
220196
}
221-
return nil
197+
urlToPrefetch.when = time.Now().Add(delayTillNextUpdate)
198+
return err
222199
}

0 commit comments

Comments
 (0)