feat(tunnel): introduce persistent tunnel state dir (#294)

* feat(tunnel): introduce persistent tunnel state dir

This diff introduces a persistent state directory for tunnels, so that
we can bootstrap them more quickly after the first time.

Part of https://github.com/ooni/probe/issues/985

* fix: make tunnel dir optional

We have many tests where it does not make sense to explicitly
provide a tunnel dir because we're not using tunnels.

This should simplify setting up a session.

* fix(tunnel): repair tests

* final changes

* more cleanups
This commit is contained in:
Simone Basso 2021-04-05 11:27:41 +02:00 committed by GitHub
commit 8fe4e5410d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 166 additions and 105 deletions

View file

@ -3,18 +3,18 @@ package tunnel
import (
"context"
"fmt"
"io"
"net/url"
"path"
"path/filepath"
"strings"
"time"
"github.com/cretz/bine/tor"
)
// torProcess is a running tor process
// torProcess is a running tor process.
type torProcess interface {
// Close kills the running tor process
Close() error
io.Closer
}
// torTunnel is the Tor tunnel
@ -52,6 +52,9 @@ func (tt *torTunnel) Stop() {
}
}
// TODO(bassosimone): the current design is such that we have a bunch of
// torrc-$number and a growing tor.log file inside of stateDir.
// torStart starts the tor tunnel.
func torStart(ctx context.Context, config *Config) (Tunnel, error) {
select {
@ -59,14 +62,18 @@ func torStart(ctx context.Context, config *Config) (Tunnel, error) {
return nil, ctx.Err() // allows to write unit tests using this code
default:
}
logfile := LogFile(config.Session)
if config.TunnelDir == "" {
return nil, ErrEmptyTunnelDir
}
stateDir := filepath.Join(config.TunnelDir, "tor")
logfile := filepath.Join(stateDir, "tor.log")
extraArgs := append([]string{}, config.TorArgs...)
extraArgs = append(extraArgs, "Log")
extraArgs = append(extraArgs, "notice stderr")
extraArgs = append(extraArgs, "Log")
extraArgs = append(extraArgs, fmt.Sprintf(`notice file %s`, logfile))
instance, err := config.torStart(ctx, &tor.StartConf{
DataDir: path.Join(config.Session.TempDir(), "tor"),
DataDir: stateDir,
ExtraArgs: extraArgs,
ExePath: config.TorBinary,
NoHush: true,
@ -102,9 +109,3 @@ func torStart(ctx context.Context, config *Config) (Tunnel, error) {
proxy: &url.URL{Scheme: "socks5", Host: proxyAddress},
}, nil
}
// LogFile returns the name of tor logs given a specific session. The file
// is always located somewhere inside the sess.TempDir() directory.
func LogFile(sess Session) string {
return path.Join(sess.TempDir(), "tor.log")
}