Skip to content

Commit 6680faf

Browse files
vbauersterjedisct1
authored andcommitted
make sure tcp/udp Conn are closed on stop signal
1 parent 220d418 commit 6680faf

7 files changed

Lines changed: 69 additions & 46 deletions

File tree

dnscrypt-proxy/config.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ func ConfigLoad(proxy *Proxy, svcFlag *string) error {
477477
}
478478
proxy.showCerts = *showCerts || len(os.Getenv("SHOW_CERTS")) > 0
479479
if proxy.showCerts {
480-
proxy.listenAddresses = nil
480+
proxy.listenAddresses = proxy.listenAddresses[0:0]
481481
}
482482
dlog.Noticef("dnscrypt-proxy %s", AppVersion)
483483
if err := NetProbe(netprobeAddress, netprobeTimeout); err != nil {
@@ -628,11 +628,11 @@ func (config *Config) loadSource(proxy *Proxy, requiredProps stamps.ServerInform
628628
cfgSource.RefreshDelay = 72
629629
}
630630
source, sourceUrlsToPrefetch, err := NewSource(proxy.xTransport, cfgSource.URLs, cfgSource.MinisignKeyStr, cfgSource.CacheFile, cfgSource.FormatStr, time.Duration(cfgSource.RefreshDelay)*time.Hour)
631-
proxy.urlsToPrefetch = append(proxy.urlsToPrefetch, sourceUrlsToPrefetch...)
632631
if err != nil {
633632
dlog.Criticalf("Unable to retrieve source [%s]: [%s]", cfgSourceName, err)
634633
return err
635634
}
635+
proxy.urlsToPrefetch = append(proxy.urlsToPrefetch, sourceUrlsToPrefetch...)
636636
registeredServers, err := source.Parse(cfgSource.Prefix)
637637
if err != nil {
638638
if len(registeredServers) == 0 {

dnscrypt-proxy/main.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,7 @@ func (app *App) Stop(service service.Service) error {
111111

112112
func (app *App) appMain() {
113113
pidfile.Write()
114-
app.proxy.StartProxy()
115-
<-app.quit
114+
app.proxy.StartProxy(app.quit)
116115
app.wg.Done()
117116
}
118117

dnscrypt-proxy/proxy.go

Lines changed: 31 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type Proxy struct {
6060
forwardFile string
6161
cloakFile string
6262
pluginsGlobals PluginsGlobals
63-
urlsToPrefetch []URLToPrefetch
63+
urlsToPrefetch []*URLToPrefetch
6464
clientsCount uint32
6565
maxClients uint32
6666
xTransport *XTransport
@@ -74,7 +74,7 @@ type Proxy struct {
7474
showCerts bool
7575
}
7676

77-
func (proxy *Proxy) StartProxy() {
77+
func (proxy *Proxy) StartProxy(quit <-chan struct{}) {
7878
proxy.questionSizeEstimator = NewQuestionSizeEstimator()
7979
if _, err := crypto_rand.Read(proxy.proxySecretKey[:]); err != nil {
8080
dlog.Fatal(err)
@@ -96,12 +96,16 @@ func (proxy *Proxy) StartProxy() {
9696

9797
// if 'userName' is not set, continue as before
9898
if !(len(proxy.userName) > 0) {
99-
if err := proxy.udpListenerFromAddr(listenUDPAddr); err != nil {
99+
udpCloser, err := proxy.udpListenerFromAddr(listenUDPAddr)
100+
if err != nil {
100101
dlog.Fatal(err)
101102
}
102-
if err := proxy.tcpListenerFromAddr(listenTCPAddr); err != nil {
103+
tcpCloser, err := proxy.tcpListenerFromAddr(listenTCPAddr)
104+
if err != nil {
103105
dlog.Fatal(err)
104106
}
107+
defer udpCloser.Close()
108+
defer tcpCloser.Close()
105109
} else {
106110
// if 'userName' is set and we are the parent process
107111
if !proxy.child {
@@ -156,9 +160,11 @@ func (proxy *Proxy) StartProxy() {
156160
if len(proxy.userName) > 0 && !proxy.child {
157161
proxy.dropPrivilege(proxy.userName, FileDescriptors)
158162
}
159-
if err := proxy.SystemDListeners(); err != nil {
163+
sdc, err := proxy.SystemDListeners()
164+
if err != nil {
160165
dlog.Fatal(err)
161166
}
167+
defer sdc.Close()
162168
liveServers, err := proxy.serversInfo.refresh(proxy)
163169
if liveServers > 0 {
164170
proxy.certIgnoreTimestamp = false
@@ -177,7 +183,7 @@ func (proxy *Proxy) StartProxy() {
177183
dlog.Error(err)
178184
dlog.Notice("dnscrypt-proxy is waiting for at least one server to be reachable")
179185
}
180-
proxy.prefetcher(&proxy.urlsToPrefetch)
186+
go proxy.prefetcher()
181187
if len(proxy.serversInfo.registeredServers) > 0 {
182188
go func() {
183189
for {
@@ -193,30 +199,27 @@ func (proxy *Proxy) StartProxy() {
193199
}
194200
}()
195201
}
202+
<-quit
196203
}
197204

198-
func (proxy *Proxy) prefetcher(urlsToPrefetch *[]URLToPrefetch) {
199-
go func() {
200-
for {
201-
now := time.Now()
202-
for i := range *urlsToPrefetch {
203-
urlToPrefetch := &(*urlsToPrefetch)[i]
204-
if now.After(urlToPrefetch.when) {
205-
dlog.Debugf("Prefetching [%s]", urlToPrefetch.url)
206-
if err := PrefetchSourceURL(proxy.xTransport, urlToPrefetch); err != nil {
207-
dlog.Debugf("Prefetching [%s] failed: %s", urlToPrefetch.url, err)
208-
} else {
209-
dlog.Debugf("Prefetching [%s] succeeded. Next refresh scheduled for %v", urlToPrefetch.url, urlToPrefetch.when)
210-
}
205+
func (proxy *Proxy) prefetcher() {
206+
for {
207+
now := time.Now()
208+
for _, urlToPrefetch := range proxy.urlsToPrefetch {
209+
if now.After(urlToPrefetch.when) {
210+
dlog.Debugf("Prefetching [%s]", urlToPrefetch.url)
211+
if err := PrefetchSourceURL(proxy.xTransport, urlToPrefetch); err != nil {
212+
dlog.Debugf("Prefetching [%s] failed: %s", urlToPrefetch.url, err)
213+
} else {
214+
dlog.Debugf("Prefetching [%s] succeeded. Next refresh scheduled for %v", urlToPrefetch.url, urlToPrefetch.when)
211215
}
212216
}
213-
clocksmith.Sleep(60 * time.Second)
214217
}
215-
}()
218+
clocksmith.Sleep(60 * time.Second)
219+
}
216220
}
217221

218222
func (proxy *Proxy) udpListener(clientPc *net.UDPConn) {
219-
defer clientPc.Close()
220223
for {
221224
buffer := make([]byte, MaxDNSPacketSize-1)
222225
length, clientAddr, err := clientPc.ReadFrom(buffer)
@@ -236,18 +239,17 @@ func (proxy *Proxy) udpListener(clientPc *net.UDPConn) {
236239
}
237240
}
238241

239-
func (proxy *Proxy) udpListenerFromAddr(listenAddr *net.UDPAddr) error {
242+
func (proxy *Proxy) udpListenerFromAddr(listenAddr *net.UDPAddr) (io.Closer, error) {
240243
clientPc, err := net.ListenUDP("udp", listenAddr)
241244
if err != nil {
242-
return err
245+
return nil, err
243246
}
244247
dlog.Noticef("Now listening to %v [UDP]", listenAddr)
245248
go proxy.udpListener(clientPc)
246-
return nil
249+
return clientPc, nil
247250
}
248251

249252
func (proxy *Proxy) tcpListener(acceptPc *net.TCPListener) {
250-
defer acceptPc.Close()
251253
for {
252254
clientPc, err := acceptPc.Accept()
253255
if err != nil {
@@ -272,14 +274,14 @@ func (proxy *Proxy) tcpListener(acceptPc *net.TCPListener) {
272274
}
273275
}
274276

275-
func (proxy *Proxy) tcpListenerFromAddr(listenAddr *net.TCPAddr) error {
277+
func (proxy *Proxy) tcpListenerFromAddr(listenAddr *net.TCPAddr) (io.Closer, error) {
276278
acceptPc, err := net.ListenTCP("tcp", listenAddr)
277279
if err != nil {
278-
return err
280+
return nil, err
279281
}
280282
dlog.Noticef("Now listening to %v [TCP]", listenAddr)
281283
go proxy.tcpListener(acceptPc)
282-
return nil
284+
return acceptPc, nil
283285
}
284286

285287
func (proxy *Proxy) prepareForRelay(ip net.IP, port int, encryptedQuery *[]byte) {

dnscrypt-proxy/sources.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,19 @@ type URLToPrefetch struct {
127127
when time.Time
128128
}
129129

130-
func NewSource(xTransport *XTransport, urls []string, minisignKeyStr string, cacheFile string, formatStr string, refreshDelay time.Duration) (Source, []URLToPrefetch, error) {
130+
func NewSource(xTransport *XTransport, urls []string, minisignKeyStr string, cacheFile string, formatStr string, refreshDelay time.Duration) (Source, []*URLToPrefetch, error) {
131+
urlsToPrefetch := []*URLToPrefetch{}
131132
source := Source{urls: urls}
132133
if formatStr == "v2" {
133134
source.format = SourceFormatV2
134135
} else {
135-
return source, []URLToPrefetch{}, fmt.Errorf("Unsupported source format: [%s]", formatStr)
136+
return source, urlsToPrefetch, fmt.Errorf("Unsupported source format: [%s]", formatStr)
136137
}
137138
minisignKey, err := minisign.NewPublicKey(minisignKeyStr)
138139
if err != nil {
139-
return source, []URLToPrefetch{}, err
140+
return source, urlsToPrefetch, err
140141
}
141142
now := time.Now()
142-
urlsToPrefetch := []URLToPrefetch{}
143143
sigCacheFile := cacheFile + ".minisig"
144144

145145
var sigStr, in string
@@ -166,8 +166,8 @@ func NewSource(xTransport *XTransport, urls []string, minisignKeyStr string, cac
166166
if len(preloadURL) > 0 {
167167
url := preloadURL
168168
sigURL := url + ".minisig"
169-
urlsToPrefetch = append(urlsToPrefetch, URLToPrefetch{url: url, cacheFile: cacheFile, when: now.Add(delayTillNextUpdate)})
170-
urlsToPrefetch = append(urlsToPrefetch, URLToPrefetch{url: sigURL, cacheFile: sigCacheFile, when: now.Add(sigDelayTillNextUpdate)})
169+
urlsToPrefetch = append(urlsToPrefetch, &URLToPrefetch{url: url, cacheFile: cacheFile, when: now.Add(delayTillNextUpdate)})
170+
urlsToPrefetch = append(urlsToPrefetch, &URLToPrefetch{url: sigURL, cacheFile: sigCacheFile, when: now.Add(sigDelayTillNextUpdate)})
171171
}
172172
if sigErr != nil && err == nil {
173173
err = sigErr

dnscrypt-proxy/systemd_android.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
package main
22

3-
func (proxy *Proxy) SystemDListeners() error {
4-
return nil
3+
import (
4+
"io"
5+
)
6+
7+
func (proxy *Proxy) SystemDListeners() (io.Closer, error) {
8+
return ioutil.NopCloser(nil), nil
59
}

dnscrypt-proxy/systemd_free.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
package main
44

5-
func (proxy *Proxy) SystemDListeners() error {
6-
return nil
5+
import (
6+
"io"
7+
"io/ioutil"
8+
)
9+
10+
func (proxy *Proxy) SystemDListeners() (io.Closer, error) {
11+
return ioutil.NopCloser(nil), nil
712
}

dnscrypt-proxy/systemd_linux.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,23 @@ package main
44

55
import (
66
"fmt"
7+
"io"
78
"net"
89

910
"github.com/coreos/go-systemd/activation"
1011
"github.com/jedisct1/dlog"
1112
)
1213

13-
func (proxy *Proxy) SystemDListeners() error {
14+
type multiCloser []io.Closer
15+
16+
func (mc multiCloser) Close() (err error) {
17+
for _, c := range mc {
18+
err = c.Close()
19+
}
20+
return err
21+
}
22+
23+
func (proxy *Proxy) SystemDListeners() (io.Closer, error) {
1424
files := activation.Files(true)
1525

1626
if len(files) > 0 {
@@ -19,22 +29,25 @@ func (proxy *Proxy) SystemDListeners() error {
1929
}
2030
dlog.Warn("Systemd sockets are untested and unsupported - use at your own risk")
2131
}
32+
var mc multiCloser
2233
for i, file := range files {
2334
defer file.Close()
2435
ok := false
2536
if listener, err := net.FileListener(file); err == nil {
2637
dlog.Noticef("Wiring systemd TCP socket #%d, %s, %s", i, file.Name(), listener.Addr())
2738
ok = true
39+
mc = append(mc, listener)
2840
go proxy.tcpListener(listener.(*net.TCPListener))
2941
} else if pc, err := net.FilePacketConn(file); err == nil {
3042
dlog.Noticef("Wiring systemd UDP socket #%d, %s, %s", i, file.Name(), pc.LocalAddr())
3143
ok = true
44+
mc = append(mc, pc)
3245
go proxy.udpListener(pc.(*net.UDPConn))
3346
}
3447
if !ok {
35-
return fmt.Errorf("Could not wire systemd socket #%d, %s", i, file.Name())
48+
return nil, fmt.Errorf("Could not wire systemd socket #%d, %s", i, file.Name())
3649
}
3750
}
3851

39-
return nil
52+
return mc, nil
4053
}

0 commit comments

Comments
 (0)