cleanup(jafar): do not depend on netx and urlgetter (#792)

There's no point in doing that. Also, once this change is merged, it becomes easier to cleanup/simplify netx.

See https://github.com/ooni/probe/issues/2121
This commit is contained in:
Simone Basso
2022-06-02 22:25:37 +02:00
committed by GitHub
parent 76b65893a1
commit 15da0f5344
19 changed files with 345 additions and 275 deletions
+10 -13
View File
@@ -8,7 +8,7 @@ any system but it really only works on Linux.
## Building
We use Go >= 1.16. Jafar also needs the C library headers,
We use Go >= 1.18. Jafar also needs the C library headers,
iptables installed, and root permissions.
With Linux Alpine edge, you can compile Jafar with:
@@ -198,24 +198,21 @@ the client Hello message will cause the TLS handshake to fail.
### uncensored
```bash
-uncensored-resolver-url string
URL of an hopefully uncensored resolver (default "dot://1.1.1.1:853")
-uncensored-resolver-doh string
URL of an hopefully uncensored DoH resolver (default "https://1.1.1.1/dns-query")
```
The HTTP, DNS, and TLS proxies need to resolve domain names. If you setup DNS
censorship, they may be affected as well. To avoid this issue, we use a different
resolver for them, which by default is `dot://1.1.1.1:853`. You can change such
default by using the `-uncensored-resolver-url` command line flag. The input
URL is `<transport>://<domain>[:<port>][/<path>]`. Here are some examples:
resolver for them, which by default is the one shown above. You can change such
default by using the `-uncensored-resolver-doh` command line flag. The input
URL is an HTTPS URL pointing to a DoH server. Here are some examples:
* `system:///` uses the system resolver (i.e. `getaddrinfo`)
* `udp://8.8.8.8:53` uses DNS over UDP
* `tcp://8.8.8.8:53` used DNS over TCP
* `dot://8.8.8.8:853` uses DNS over TLS
* `https://dns.google/dns-query` uses DNS over HTTPS
* `https://dns.google/dns-query`
* `https://dns.quad9.net/dns-query`
So, for example, if you are using Jafar to censor `1.1.1.1:853`, then you
most likely want to use `-uncensored-resolver-url`.
So, for example, if you are using Jafar to censor `1.1.1.1:443`, then you
most likely want to use `-uncensored-resolver-doh`.
## Examples
@@ -42,7 +42,7 @@ func TestLoop(t *testing.T) {
}
func TestListenError(t *testing.T) {
proxy := NewCensoringProxy([]string{""}, uncensored.DefaultClient)
proxy := NewCensoringProxy([]string{""}, uncensored.NewClient("https://1.1.1.1/dns-query"))
server, addr, err := proxy.Start("8.8.8.8:80")
if err == nil {
t.Fatal("expected an error here")
@@ -56,7 +56,7 @@ func TestListenError(t *testing.T) {
}
func newproxy(t *testing.T, blocked string) (*http.Server, net.Addr) {
proxy := NewCensoringProxy([]string{blocked}, uncensored.DefaultClient)
proxy := NewCensoringProxy([]string{blocked}, uncensored.NewClient("https://1.1.1.1/dns-query"))
server, addr, err := proxy.Start("127.0.0.1:0")
if err != nil {
t.Fatal(err)
@@ -240,7 +240,7 @@ func TestHijackDNS(t *testing.T) {
}
resolver := resolver.NewCensoringResolver(
[]string{"ooni.io"}, nil, nil,
uncensored.Must(uncensored.NewClient("dot://1.1.1.1:853")),
uncensored.NewClient("https://1.1.1.1/dns-query"),
)
server, err := resolver.Start("127.0.0.1:0")
if err != nil {
+5 -7
View File
@@ -61,7 +61,7 @@ var (
tlsProxyAddress *string
tlsProxyBlock flagx.StringArray
uncensoredResolverURL *string
uncensoredResolverDoH *string
)
func init() {
@@ -167,9 +167,9 @@ func init() {
)
// uncensored
uncensoredResolverURL = flag.String(
"uncensored-resolver-url", "dot://1.1.1.1:853",
"URL of an hopefully uncensored resolver",
uncensoredResolverDoH = flag.String(
"uncensored-resolver-doh", "https://1.1.1.1/dns-query",
"URL of an hopefully uncensored DoH resolver",
)
}
@@ -234,9 +234,7 @@ func tlsProxyStart(uncensored *uncensored.Client) net.Listener {
}
func newUncensoredClient() *uncensored.Client {
clnt, err := uncensored.NewClient(*uncensoredResolverURL)
runtimex.PanicOnError(err, "uncensored.NewClient failed")
return clnt
return uncensored.NewClient(*uncensoredResolverDoH)
}
func mustx(err error, message string, osExit func(int)) {
+3 -5
View File
@@ -45,14 +45,14 @@ func TestLookupFailure(t *testing.T) {
func TestFailureNoQuestion(t *testing.T) {
resolver := NewCensoringResolver(
nil, nil, nil, uncensored.DefaultClient,
nil, nil, nil, uncensored.NewClient("https://1.1.1.1/dns-query"),
)
resolver.ServeDNS(&fakeResponseWriter{t: t}, new(dns.Msg))
}
func TestListenFailure(t *testing.T) {
resolver := NewCensoringResolver(
nil, nil, nil, uncensored.DefaultClient,
nil, nil, nil, uncensored.NewClient("https://1.1.1.1/dns-query"),
)
server, err := resolver.Start("8.8.8.8:53")
if err == nil {
@@ -66,9 +66,7 @@ func TestListenFailure(t *testing.T) {
func newresolver(t *testing.T, blocked, hijacked, ignored []string) *dns.Server {
resolver := NewCensoringResolver(
blocked, hijacked, ignored,
// using faster dns because dot here causes miekg/dns's
// dns.Exchange to timeout and I don't want more complexity
uncensored.Must(uncensored.NewClient("system:///")),
uncensored.NewClient("https://1.1.1.1/dns-query"),
)
server, err := resolver.Start("127.0.0.1:0")
if err != nil {
+2 -2
View File
@@ -94,7 +94,7 @@ func TestFailWriteAfterConnect(t *testing.T) {
func TestListenError(t *testing.T) {
proxy := NewCensoringProxy(
[]string{""}, uncensored.DefaultClient,
[]string{""}, uncensored.NewClient("https://1.1.1.1/dns-query"),
)
listener, err := proxy.Start("8.8.8.8:80")
if err == nil {
@@ -107,7 +107,7 @@ func TestListenError(t *testing.T) {
func newproxy(t *testing.T, blocked string) net.Listener {
proxy := NewCensoringProxy(
[]string{blocked}, uncensored.DefaultClient,
[]string{blocked}, uncensored.NewClient("https://1.1.1.1/dns-query"),
)
listener, err := proxy.Start("127.0.0.1:0")
if err != nil {
+7 -33
View File
@@ -9,10 +9,8 @@ import (
"net/http"
"github.com/apex/log"
"github.com/ooni/probe-cli/v3/internal/engine/experiment/urlgetter"
"github.com/ooni/probe-cli/v3/internal/engine/netx"
"github.com/ooni/probe-cli/v3/internal/model"
"github.com/ooni/probe-cli/v3/internal/runtimex"
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
// Client is DNS, HTTP, and TCP client.
@@ -23,35 +21,15 @@ type Client struct {
}
// NewClient creates a new Client.
func NewClient(resolverURL string) (*Client, error) {
configuration, err := urlgetter.Configurer{
Config: urlgetter.Config{
ResolverURL: resolverURL,
},
Logger: log.Log,
}.NewConfiguration()
if err != nil {
return nil, err
}
func NewClient(resolverURL string) *Client {
dnsClient := netxlite.NewParallelDNSOverHTTPSResolver(log.Log, resolverURL)
return &Client{
dnsClient: configuration.DNSClient,
httpTransport: netx.NewHTTPTransport(configuration.HTTPConfig),
dialer: netx.NewDialer(configuration.HTTPConfig),
}, nil
dnsClient: dnsClient,
httpTransport: netxlite.NewHTTPTransportWithResolver(log.Log, dnsClient),
dialer: netxlite.NewDialerWithResolver(log.Log, dnsClient),
}
}
// Must panics if it's not possible to create a Client. Usually you should
// use it like `uncensored.Must(uncensored.NewClient(URL))`.
func Must(client *Client, err error) *Client {
runtimex.PanicOnError(err, "cannot create uncensored client")
return client
}
// DefaultClient is the default client for DNS, HTTP, and TCP.
var DefaultClient = Must(NewClient(""))
var _ model.Resolver = DefaultClient
// Address implements Resolver.Address
func (c *Client) Address() string {
return c.dnsClient.Address()
@@ -77,15 +55,11 @@ func (c *Client) Network() string {
return c.dnsClient.Network()
}
var _ model.Dialer = DefaultClient
// DialContext implements Dialer.DialContext
func (c *Client) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
return c.dialer.DialContext(ctx, network, address)
}
var _ model.HTTPTransport = DefaultClient
// CloseIdleConnections implement HTTPRoundTripper.CloseIdleConnections
func (c *Client) CloseIdleConnections() {
c.dnsClient.CloseIdleConnections()
@@ -10,16 +10,13 @@ import (
"github.com/ooni/probe-cli/v3/internal/netxlite"
)
func TestGood(t *testing.T) {
client, err := NewClient("dot://1.1.1.1:853")
if err != nil {
t.Fatal(err)
}
func TestNewClient(t *testing.T) {
client := NewClient("https://1.1.1.1/dns-query")
defer client.CloseIdleConnections()
if client.Address() != "1.1.1.1:853" {
if client.Address() != "https://1.1.1.1/dns-query" {
t.Fatal("invalid address")
}
if client.Network() != "dot" {
if client.Network() != "doh" {
t.Fatal("invalid network")
}
ctx := context.Background()
@@ -64,13 +61,3 @@ func TestGood(t *testing.T) {
t.Fatal("not the expected body")
}
}
func TestNewClientFailure(t *testing.T) {
clnt, err := NewClient("antani:///")
if err == nil {
t.Fatal("expected an error here")
}
if clnt != nil {
t.Fatal("expected nil client here")
}
}