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:
@@ -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 {
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user