fix(sessionresolver): honour the proxy (#250)

In reality, we are not going to use the sessionresolver when we're
using a proxy (I just tested). But, it nonetheless feels a lot more
robust to write a correct sessionresolver that handles the proxy
in the most correct way. That is, the sessionresolver will now skip
all the entries that cannot use a socks5 proxy (including among them
also the system resolver). What's more, it will construct a child
resolver that propagates the proxy.

We have confidence that this holds true because we have added a test
ensuring that we are really using the configured proxy.

See https://github.com/ooni/probe/issues/1381
This commit is contained in:
Simone Basso 2021-03-10 10:39:57 +01:00 committed by GitHub
commit f0110fe85a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 112 additions and 1 deletions

View file

@ -25,6 +25,7 @@ import (
"errors"
"fmt"
"math/rand"
"net/url"
"sync"
"time"
@ -39,6 +40,7 @@ type Resolver struct {
ByteCounter *bytecounter.Counter // optional
KVStore KVStore // optional
Logger Logger // optional
ProxyURL *url.URL // optional
codec codec
dnsClientMaker dnsclientmaker
mu sync.Mutex
@ -71,6 +73,9 @@ func (r *Resolver) LookupHost(ctx context.Context, hostname string) ([]string, e
defer r.writestate(state)
me := multierror.New(ErrLookupHost)
for _, e := range state {
if r.shouldSkipWithProxy(e) {
continue // we cannot proxy this URL so ignore it
}
addrs, err := r.lookupHost(ctx, e, hostname)
if err == nil {
return addrs, nil
@ -80,6 +85,19 @@ func (r *Resolver) LookupHost(ctx context.Context, hostname string) ([]string, e
return nil, me
}
func (r *Resolver) shouldSkipWithProxy(e *resolverinfo) bool {
URL, err := url.Parse(e.URL)
if err != nil {
return true // please skip
}
switch URL.Scheme {
case "https", "dot", "tcp":
return false // we can handle this
default:
return true // please skip
}
}
func (r *Resolver) lookupHost(ctx context.Context, ri *resolverinfo, hostname string) ([]string, error) {
const ewma = 0.9 // the last sample is very important
re, err := r.getresolver(ri.URL)