-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor(netxlite): introduce the getaddrinfo transport (#775)
This diff modifies the system resolver to use a getaddrinf transport. Obviously the transport is a fake, but its existence will allow us to observe DNS events more naturally. A lookup using the system resolver would be a ANY lookup that will contain all the resolved IP addresses into the same response. This change was also part of websteps-illustrated, albeit the way in which I did it there was less clean than what we have here. Ref issue: ooni/probe#2096
- Loading branch information
1 parent
7e0b473
commit 923d81c
Showing
14 changed files
with
432 additions
and
163 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package netxlite | ||
|
||
// | ||
// DNS over getaddrinfo: fake transport to allow us to observe | ||
// lookups using getaddrinfo as a DNSTransport. | ||
// | ||
|
||
import ( | ||
"context" | ||
"net" | ||
"time" | ||
|
||
"github.com/miekg/dns" | ||
"github.com/ooni/probe-cli/v3/internal/model" | ||
) | ||
|
||
// dnsOverGetaddrinfoTransport is a DNSTransport using getaddrinfo. | ||
type dnsOverGetaddrinfoTransport struct { | ||
testableTimeout time.Duration | ||
testableLookupHost func(ctx context.Context, domain string) ([]string, error) | ||
} | ||
|
||
var _ model.DNSTransport = &dnsOverGetaddrinfoTransport{} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) RoundTrip( | ||
ctx context.Context, query model.DNSQuery) (model.DNSResponse, error) { | ||
if query.Type() != dns.TypeANY { | ||
return nil, ErrNoDNSTransport | ||
} | ||
addrs, err := txp.lookup(ctx, query.Domain()) | ||
if err != nil { | ||
return nil, err | ||
} | ||
resp := &dnsOverGetaddrinfoResponse{ | ||
addrs: addrs, | ||
query: query, | ||
} | ||
return resp, nil | ||
} | ||
|
||
type dnsOverGetaddrinfoResponse struct { | ||
addrs []string | ||
query model.DNSQuery | ||
} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) lookup( | ||
ctx context.Context, hostname string) ([]string, error) { | ||
// This code forces adding a shorter timeout to the domain name | ||
// resolutions when using the system resolver. We have seen cases | ||
// in which such a timeout becomes too large. One such case is | ||
// described in https://github.com/ooni/probe/issues/1726. | ||
addrsch, errch := make(chan []string, 1), make(chan error, 1) | ||
ctx, cancel := context.WithTimeout(ctx, txp.timeout()) | ||
defer cancel() | ||
go func() { | ||
addrs, err := txp.lookupfn()(ctx, hostname) | ||
if err != nil { | ||
errch <- err | ||
return | ||
} | ||
addrsch <- addrs | ||
}() | ||
select { | ||
case <-ctx.Done(): | ||
return nil, ctx.Err() | ||
case addrs := <-addrsch: | ||
return addrs, nil | ||
case err := <-errch: | ||
return nil, err | ||
} | ||
} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) timeout() time.Duration { | ||
if txp.testableTimeout > 0 { | ||
return txp.testableTimeout | ||
} | ||
return 15 * time.Second | ||
} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) lookupfn() func(ctx context.Context, domain string) ([]string, error) { | ||
if txp.testableLookupHost != nil { | ||
return txp.testableLookupHost | ||
} | ||
return TProxy.DefaultResolver().LookupHost | ||
} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) RequiresPadding() bool { | ||
return false | ||
} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) Network() string { | ||
return TProxy.DefaultResolver().Network() | ||
} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) Address() string { | ||
return "" | ||
} | ||
|
||
func (txp *dnsOverGetaddrinfoTransport) CloseIdleConnections() { | ||
// nothing | ||
} | ||
|
||
func (r *dnsOverGetaddrinfoResponse) Query() model.DNSQuery { | ||
return r.query | ||
} | ||
|
||
func (r *dnsOverGetaddrinfoResponse) Bytes() []byte { | ||
return nil | ||
} | ||
|
||
func (r *dnsOverGetaddrinfoResponse) Rcode() int { | ||
return 0 | ||
} | ||
|
||
func (r *dnsOverGetaddrinfoResponse) DecodeHTTPS() (*model.HTTPSSvc, error) { | ||
return nil, ErrNoDNSTransport | ||
} | ||
|
||
func (r *dnsOverGetaddrinfoResponse) DecodeLookupHost() ([]string, error) { | ||
return r.addrs, nil | ||
} | ||
|
||
func (r *dnsOverGetaddrinfoResponse) DecodeNS() ([]*net.NS, error) { | ||
return nil, ErrNoDNSTransport | ||
} |
Oops, something went wrong.