chore: merge probe-engine into probe-cli (#201)
This is how I did it: 1. `git clone https://github.com/ooni/probe-engine internal/engine` 2. ``` (cd internal/engine && git describe --tags) v0.23.0 ``` 3. `nvim go.mod` (merging `go.mod` with `internal/engine/go.mod` 4. `rm -rf internal/.git internal/engine/go.{mod,sum}` 5. `git add internal/engine` 6. `find . -type f -name \*.go -exec sed -i 's@/ooni/probe-engine@/ooni/probe-cli/v3/internal/engine@g' {} \;` 7. `go build ./...` (passes) 8. `go test -race ./...` (temporary failure on RiseupVPN) 9. `go mod tidy` 10. this commit message Once this piece of work is done, we can build a new version of `ooniprobe` that is using `internal/engine` directly. We need to do more work to ensure all the other functionality in `probe-engine` (e.g. making mobile packages) are still WAI. Part of https://github.com/ooni/probe/issues/1335
This commit is contained in:
parent
b1ce300c8d
commit
d57c78bc71
535 changed files with 66182 additions and 23 deletions
94
internal/engine/netx/dialer/proxy.go
Normal file
94
internal/engine/netx/dialer/proxy.go
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
package dialer
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"net"
|
||||
"net/url"
|
||||
|
||||
"golang.org/x/net/proxy"
|
||||
)
|
||||
|
||||
// ProxyDialer is a dialer that uses a proxy. If the ProxyURL is not configured, this
|
||||
// dialer is a passthrough for the next Dialer in chain. Otherwise, it will internally
|
||||
// create a SOCKS5 dialer that will connect to the proxy using the underlying Dialer.
|
||||
//
|
||||
// As a special case, you can force a proxy to be used only extemporarily. To this end,
|
||||
// you can use the WithProxyURL function, to store the proxy URL in the context. This
|
||||
// will take precedence over any otherwise configured proxy. The use case for this
|
||||
// functionality is when you need a tunnel to contact OONI probe services.
|
||||
type ProxyDialer struct {
|
||||
Dialer
|
||||
ProxyURL *url.URL
|
||||
}
|
||||
|
||||
type proxyKey struct{}
|
||||
|
||||
// ContextProxyURL retrieves the proxy URL from the context. This is mainly used
|
||||
// to force a tunnel when we fail contacting OONI probe services otherwise.
|
||||
func ContextProxyURL(ctx context.Context) *url.URL {
|
||||
url, _ := ctx.Value(proxyKey{}).(*url.URL)
|
||||
return url
|
||||
}
|
||||
|
||||
// WithProxyURL assigns the proxy URL to the context
|
||||
func WithProxyURL(ctx context.Context, url *url.URL) context.Context {
|
||||
return context.WithValue(ctx, proxyKey{}, url)
|
||||
}
|
||||
|
||||
// DialContext implements Dialer.DialContext
|
||||
func (d ProxyDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
|
||||
url := ContextProxyURL(ctx) // context URL takes precendence
|
||||
if url == nil {
|
||||
url = d.ProxyURL
|
||||
}
|
||||
if url == nil {
|
||||
return d.Dialer.DialContext(ctx, network, address)
|
||||
}
|
||||
if url.Scheme != "socks5" {
|
||||
return nil, errors.New("Scheme is not socks5")
|
||||
}
|
||||
// the code at proxy/socks5.go never fails; see https://git.io/JfJ4g
|
||||
child, _ := proxy.SOCKS5(
|
||||
network, url.Host, nil, proxyDialerWrapper{Dialer: d.Dialer})
|
||||
return d.dial(ctx, child, network, address)
|
||||
}
|
||||
|
||||
func (d ProxyDialer) dial(
|
||||
ctx context.Context, child proxy.Dialer, network, address string) (net.Conn, error) {
|
||||
connch := make(chan net.Conn)
|
||||
errch := make(chan error, 1)
|
||||
go func() {
|
||||
conn, err := child.Dial(network, address)
|
||||
if err != nil {
|
||||
errch <- err
|
||||
return
|
||||
}
|
||||
select {
|
||||
case connch <- conn:
|
||||
default:
|
||||
conn.Close()
|
||||
}
|
||||
}()
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, ctx.Err()
|
||||
case err := <-errch:
|
||||
return nil, err
|
||||
case conn := <-connch:
|
||||
return conn, nil
|
||||
}
|
||||
}
|
||||
|
||||
// proxyDialerWrapper is required because SOCKS5 expects a Dialer.Dial type but internally
|
||||
// it checks whether DialContext is available and prefers that. So, we need to use this
|
||||
// structure to cast our inner Dialer the way in which SOCKS5 likes it.
|
||||
//
|
||||
// See https://git.io/JfJ4g.
|
||||
type proxyDialerWrapper struct {
|
||||
Dialer
|
||||
}
|
||||
|
||||
func (d proxyDialerWrapper) Dial(network, address string) (net.Conn, error) {
|
||||
return d.DialContext(context.Background(), network, address)
|
||||
}
|
||||
Loading…
Reference in a new issue