Skip to content

Commit 7e75102

Browse files
committed
pan callers: reuse context where available in call to pan.ResolveUDPAddr
Add a context to all callers of ResolveUDPAddr
1 parent 77c6ddd commit 7e75102

File tree

14 files changed

+52
-78
lines changed

14 files changed

+52
-78
lines changed

_examples/helloquic/helloquic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ func workSession(session quic.Session) error {
106106
}
107107

108108
func runClient(address string, count int) error {
109-
addr, err := pan.ResolveUDPAddr(address)
109+
addr, err := pan.ResolveUDPAddr(context.TODO(), address)
110110
if err != nil {
111111
return err
112112
}

_examples/helloworld/helloworld.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ func runServer(listen netaddr.IPPort) error {
7575
}
7676

7777
func runClient(address string, count int) error {
78-
addr, err := pan.ResolveUDPAddr(address)
78+
addr, err := pan.ResolveUDPAddr(context.TODO(), address)
7979
if err != nil {
8080
return err
8181
}

netcat/quic.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func DoListenQUIC(port uint16) (chan io.ReadWriteCloser, error) {
6565

6666
// DoDialQUIC dials with a QUIC socket
6767
func DoDialQUIC(remote string, policy pan.Policy) (io.ReadWriteCloser, error) {
68-
remoteAddr, err := pan.ResolveUDPAddr(remote)
68+
remoteAddr, err := pan.ResolveUDPAddr(context.TODO(), remote)
6969
if err != nil {
7070
return nil, err
7171
}

netcat/udp.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (conn *udpListenConn) Close() error {
5555

5656
// DoDialUDP dials with a UDP socket
5757
func DoDialUDP(remote string, policy pan.Policy) (io.ReadWriteCloser, error) {
58-
remoteAddr, err := pan.ResolveUDPAddr(remote)
58+
remoteAddr, err := pan.ResolveUDPAddr(context.TODO(), remote)
5959
if err != nil {
6060
return nil, err
6161
}

pkg/pan/dns_txt.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package pan
1616

1717
import (
1818
"context"
19+
"errors"
1920
"fmt"
2021
"net"
2122
"strings"
@@ -49,8 +50,9 @@ func queryTXTRecord(ctx context.Context, host string) (addresses []string, err e
4950
}
5051
resolver := net.Resolver{}
5152
txtRecords, err := resolver.LookupHost(ctx, host)
52-
if dnsError, ok := err.(*net.DNSError); ok {
53-
if dnsError.IsNotFound {
53+
var errDNSError *net.DNSError
54+
if errors.As(err, &errDNSError) {
55+
if errDNSError.IsNotFound {
5456
return addresses, HostNotFoundError{host}
5557
}
5658
}

pkg/pan/hosts.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ var (
2626
resolveEtcHosts resolver = &hostsfileResolver{"/etc/hosts"}
2727
resolveEtcScionHosts resolver = &hostsfileResolver{"/etc/scion/hosts"}
2828
resolveRains resolver = nil
29-
resolveDnsTxt resolver = &dnsResolver{}
29+
resolveDNSTxt resolver = &dnsResolver{}
3030
)
3131

3232
// resolveUDPAddrAt parses the address and resolves the hostname.
@@ -66,7 +66,7 @@ func defaultResolver() resolver {
6666
resolveEtcHosts,
6767
resolveEtcScionHosts,
6868
resolveRains,
69-
resolveDnsTxt,
69+
resolveDNSTxt,
7070
}
7171
}
7272

pkg/pan/hostsfile.go

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,21 @@ import (
2020
"fmt"
2121
"os"
2222
"strings"
23-
"sync"
24-
"time"
2523
)
2624

2725
type hostsTable map[string]scionAddr
2826

29-
var cachedHostsTable struct {
30-
mapping hostsTable
31-
updated time.Time
32-
sync.Mutex
33-
}
34-
3527
// hostsfileResolver is an implementation of the resolver interface, backed
3628
// by an /etc/hosts-like file.
3729
type hostsfileResolver struct {
3830
path string
3931
}
4032

41-
var _ resolver = &hostsfileResolver{}
42-
4333
func (r *hostsfileResolver) Resolve(ctx context.Context, name string) (scionAddr, error) {
44-
cachedHostsTable.Lock()
45-
defer cachedHostsTable.Unlock()
34+
// Note: obviously not perfectly elegant to parse the entire file for
35+
// every query. However, properly caching this and still always provide
36+
// fresh results after changes to the hosts file seems like a bigger task and
37+
// for now that would be overkill.
4638
table, err := loadHostsFile(r.path)
4739
if err != nil {
4840
return scionAddr{}, fmt.Errorf("error loading %s: %w", r.path, err)
@@ -54,34 +46,17 @@ func (r *hostsfileResolver) Resolve(ctx context.Context, name string) (scionAddr
5446
return addr, nil
5547
}
5648

57-
// loadHostsFile provides a cached copy of the hostsTable or loads and parses the host file at path if it was modified
58-
// since the last update.
5949
func loadHostsFile(path string) (hostsTable, error) {
60-
stat, err := os.Stat(path)
50+
file, err := os.Open(path)
6151
if os.IsNotExist(err) {
6252
// not existing file treated like an empty file,
6353
// just return an empty table
6454
return hostsTable(nil), nil
65-
}
66-
if err != nil {
67-
return hostsTable(nil), err
68-
}
69-
if stat.ModTime().Before(cachedHostsTable.updated) {
70-
return cachedHostsTable.mapping, nil
71-
}
72-
73-
file, err := os.Open(path)
74-
if err != nil {
75-
return hostsTable(nil), err
55+
} else if err != nil {
56+
return nil, err
7657
}
7758
defer file.Close()
78-
mapping, err := parseHostsFile(file)
79-
if err != nil {
80-
return hostsTable(nil), err
81-
}
82-
cachedHostsTable.mapping = mapping
83-
cachedHostsTable.updated = time.Now()
84-
return cachedHostsTable.mapping, nil
59+
return parseHostsFile(file)
8560
}
8661

8762
func parseHostsFile(file *os.File) (hostsTable, error) {

pkg/pan/pan.go

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -105,11 +105,8 @@ package pan
105105
import (
106106
"context"
107107
"fmt"
108-
"time"
109108
)
110109

111-
var defaultResolveTimeout = time.Second
112-
113110
// ResolveUDPAddr parses the address and resolves the hostname.
114111
// The address can be of the form of a SCION address (i.e. of the form "ISD-AS,[IP]:port")
115112
// or in the form of "hostname:port".
@@ -123,25 +120,8 @@ var defaultResolveTimeout = time.Second
123120
// - DNS TXT records using the local DNS resolver (depending on OS config, see "Name Resolution" in net package docs)
124121
//
125122
// Returns HostNotFoundError if none of the sources did resolve the hostname.
126-
func ResolveUDPAddr(address string) (addr UDPAddr, err error) {
127-
ctx, cancel := context.WithTimeout(context.Background(), defaultResolveTimeout)
128-
defer cancel()
129-
return ResolveUDPAddrContext(ctx, address)
130-
}
131-
132-
// ResolveUDPAddrContext resolves address, taking a context and a cancel function, see ResolveUDPAddr.
133-
func ResolveUDPAddrContext(ctx context.Context, address string) (addr UDPAddr, err error) {
134-
done := make(chan struct{})
135-
go func() {
136-
defer close(done)
137-
addr, err = resolveUDPAddrAt(ctx, address, defaultResolver())
138-
}()
139-
select {
140-
case <-ctx.Done():
141-
return UDPAddr{}, context.DeadlineExceeded
142-
case <-done:
143-
}
144-
return
123+
func ResolveUDPAddr(ctx context.Context, address string) (UDPAddr, error) {
124+
return resolveUDPAddrAt(ctx, address, defaultResolver())
145125
}
146126

147127
// HostNotFoundError is returned by ResolveUDPAddr when the name was not found, but

pkg/pan/rains.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ func readRainsConfig() (UDPAddr, error) {
6464
return address, nil
6565
}
6666

67-
func rainsQuery(ctx context.Context, server UDPAddr, hostname string) (scionAddr, error) {
67+
func rainsQuery(ctx context.Context, server UDPAddr, hostname string) (addr scionAddr, err error) {
6868
const (
6969
rainsCtx = "." // use global context
7070
qType = rains.OTScionAddr // request SCION addresses
@@ -79,17 +79,34 @@ func rainsQuery(ctx context.Context, server UDPAddr, hostname string) (scionAddr
7979
// TODO(chaehni): This call can sometimes cause a timeout even though the server is reachable (see issue #221)
8080
// The timeout value has been decreased to counter this behavior until the problem is resolved.
8181
srv := server.snetUDPAddr()
82-
reply, err := rains.Query(hostname, rainsCtx, []rains.Type{qType}, qOpts, expire, timeout, srv)
83-
if err != nil {
84-
return scionAddr{}, fmt.Errorf("address for host %q not found: %w", hostname, err)
85-
}
86-
addrStr, ok := reply[qType]
87-
if !ok {
88-
return scionAddr{}, &HostNotFoundError{hostname}
82+
83+
done := make(chan struct{})
84+
go func() {
85+
defer close(done)
86+
var reply map[rains.Type]string
87+
reply, err = rains.Query(hostname, rainsCtx, []rains.Type{qType}, qOpts, expire, timeout, srv)
88+
if err != nil {
89+
err = fmt.Errorf("address for host %q not found: %w", hostname, err)
90+
return
91+
}
92+
addrStr, ok := reply[qType]
93+
if !ok {
94+
err = &HostNotFoundError{hostname}
95+
return
96+
}
97+
addr, err = parseSCIONAddr(addrStr)
98+
if err != nil {
99+
err = fmt.Errorf("address for host %q invalid: %w", hostname, err)
100+
addr = scionAddr{}
101+
}
102+
}()
103+
select {
104+
case <-ctx.Done():
105+
return scionAddr{}, context.DeadlineExceeded
106+
case <-done:
89107
}
90-
addr, err := parseSCIONAddr(addrStr)
91108
if err != nil {
92-
return scionAddr{}, fmt.Errorf("address for host %q invalid: %w", hostname, err)
109+
return scionAddr{}, err
93110
}
94111
return addr, nil
95112
}

pkg/shttp/transport.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ func (d *Dialer) DialContext(ctx context.Context, network, addr string) (net.Con
7979
InsecureSkipVerify: true,
8080
}
8181

82-
remote, err := pan.ResolveUDPAddr(pan.UnmangleSCIONAddr(addr))
82+
remote, err := pan.ResolveUDPAddr(ctx, pan.UnmangleSCIONAddr(addr))
8383
if err != nil {
8484
return nil, err
8585
}

0 commit comments

Comments
 (0)