97d2b5a0e3
I have experimented with a new approach for embedding psiphon in
7fc0bcd97c
.
It seems the build is still building and the experiment is still
running. With the new approach, we're now vendoring less dependencies,
which hopefully puts us in the right track to, one day, import
Psiphon as a normal Go dependency.
I'll make sure to report to the Psiphon team what is currently
preventing us from importing their ClientLibrary directly.
This work is part of https://github.com/ooni/probe/issues/1894.
As part of running the update, I run `go get -u -v ./...`, which
led to go-cmp also being updated in the process.
77 lines
1.8 KiB
Go
77 lines
1.8 KiB
Go
package tunnel
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"path/filepath"
|
|
"time"
|
|
|
|
"github.com/ooni/psiphon/tunnel-core/ClientLibrary/clientlib"
|
|
)
|
|
|
|
// psiphonTunnel is a psiphon tunnel
|
|
type psiphonTunnel struct {
|
|
// bootstrapTime is the bootstrapTime of the bootstrap
|
|
bootstrapTime time.Duration
|
|
|
|
// tunnel is the underlying psiphon tunnel
|
|
tunnel *clientlib.PsiphonTunnel
|
|
}
|
|
|
|
// psiphonMakeWorkingDir creates the working directory
|
|
func psiphonMakeWorkingDir(config *Config) (string, error) {
|
|
workdir := filepath.Join(config.TunnelDir, config.Name)
|
|
if err := config.mkdirAll(workdir, 0700); err != nil {
|
|
return "", err
|
|
}
|
|
return workdir, nil
|
|
}
|
|
|
|
// psiphonStart starts the psiphon tunnel.
|
|
func psiphonStart(ctx context.Context, config *Config) (Tunnel, error) {
|
|
select {
|
|
case <-ctx.Done():
|
|
return nil, ctx.Err() // simplifies unit testing this code
|
|
default:
|
|
}
|
|
if config.TunnelDir == "" {
|
|
return nil, ErrEmptyTunnelDir
|
|
}
|
|
configJSON, err := config.Session.FetchPsiphonConfig(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
workdir, err := psiphonMakeWorkingDir(config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
start := time.Now()
|
|
tunnel, err := config.startPsiphon(ctx, configJSON, workdir)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
stop := time.Now()
|
|
return &psiphonTunnel{tunnel: tunnel, bootstrapTime: stop.Sub(start)}, nil
|
|
}
|
|
|
|
// Stop is an idempotent method that shuts down the tunnel
|
|
func (t *psiphonTunnel) Stop() {
|
|
t.tunnel.Stop()
|
|
}
|
|
|
|
// SOCKS5ProxyURL returns the SOCKS5 proxy URL.
|
|
func (t *psiphonTunnel) SOCKS5ProxyURL() *url.URL {
|
|
return &url.URL{
|
|
Scheme: "socks5",
|
|
Host: net.JoinHostPort(
|
|
"127.0.0.1", fmt.Sprintf("%d", t.tunnel.SOCKSProxyPort)),
|
|
}
|
|
}
|
|
|
|
// BootstrapTime returns the bootstrap time
|
|
func (t *psiphonTunnel) BootstrapTime() time.Duration {
|
|
return t.bootstrapTime
|
|
}
|