add testing to versionCallback, fix versionCallback
continuous-integration/drone/push Build is pending Details
continuous-integration/drone/pr Build is failing Details

This commit is contained in:
Dan Ballard 2022-08-02 19:45:44 -07:00
parent 9d4e1e5ca5
commit 9992edadba
2 changed files with 47 additions and 21 deletions

View File

@ -75,6 +75,7 @@ type torProvider struct {
authenticator tor.Authenticator
isClosed bool
dataDir string
version string
}
func (ols *onionListenService) AddressFull() string {
@ -210,6 +211,12 @@ func (tp *torProvider) GetBootstrapStatus() (int, string) {
func (tp *torProvider) GetVersion() string {
tp.lock.Lock()
defer tp.lock.Unlock()
return tp.version
}
func (tp *torProvider) getVersionFromControlPort() string {
tp.lock.Lock()
defer tp.lock.Unlock()
if tp.t == nil {
return "No Tor"
@ -325,6 +332,7 @@ func (tp *torProvider) restart() {
// preserve status callback after shutdown
statusCallback := tp.statusCallback
versionCallback := tp.versionCallback
tp.t = nil
log.Debugf("Restarting Tor Process")
@ -335,6 +343,10 @@ func (tp *torProvider) restart() {
tp.t = newTp.t
tp.dialer = newTp.dialer
tp.statusCallback = statusCallback
tp.versionCallback = versionCallback
if tp.versionCallback != nil {
tp.versionCallback(tp.version)
}
tp.lastRestartTime = time.Now()
tp.isClosed = false
go tp.monitorRestart()
@ -412,14 +424,6 @@ func (tp *torProvider) callStatusCallback(prog int, status string) {
}
}
func (tp *torProvider) callVersionCallback(version string) {
tp.lock.Lock()
defer tp.lock.Unlock()
if tp.versionCallback != nil {
tp.versionCallback(version)
}
}
// NewTorACNWithAuth creates/starts a Tor ACN and returns a usable ACN object
func NewTorACNWithAuth(appDirectory string, bundledTorPath string, dataDir string, controlPort int, authenticator tor.Authenticator) (connectivity.ACN, error) {
tp, err := startTor(appDirectory, bundledTorPath, dataDir, controlPort, authenticator)
@ -444,7 +448,7 @@ func newHideCmd(exePath string) process.Creator {
})
}
func (tp *torProvider) checkVersion() error {
func (tp *torProvider) checkVersion() (string, error) {
// attempt connect to system tor
log.Debugf("dialing tor control port")
controlport, err := dialControlPort(tp.controlPort)
@ -457,13 +461,13 @@ func (tp *torProvider) checkVersion() error {
if err == nil {
if minTorVersionReqs(pinfo.TorVersion) {
log.Debugln("OK version " + pinfo.TorVersion)
return nil
return pinfo.TorVersion, nil
}
return fmt.Errorf("tor version not supported: %v", pinfo.TorVersion)
return pinfo.TorVersion, fmt.Errorf("tor version not supported: %v", pinfo.TorVersion)
}
}
}
return err
return "", err
}
func startTor(appDirectory string, bundledTorPath string, dataDir string, controlPort int, authenticator tor.Authenticator) (*torProvider, error) {
@ -471,10 +475,11 @@ func startTor(appDirectory string, bundledTorPath string, dataDir string, contro
os.MkdirAll(torDir, 0700)
tp := &torProvider{authenticator: authenticator, controlPort: controlPort, appDirectory: appDirectory, bundeledTorPath: bundledTorPath, childListeners: make(map[string]*onionListenService), breakChan: make(chan bool, 1), statusCallback: nil, lastRestartTime: time.Now().Add(-restartCooldown)}
tp := &torProvider{authenticator: authenticator, controlPort: controlPort, appDirectory: appDirectory, bundeledTorPath: bundledTorPath, childListeners: make(map[string]*onionListenService), breakChan: make(chan bool, 1), statusCallback: nil, versionCallback: nil, lastRestartTime: time.Now().Add(-restartCooldown)}
log.Debugf("checking if there is a running system tor")
if err := tp.checkVersion(); err == nil {
if version, err := tp.checkVersion(); err == nil {
tp.version = version
controlport, err := dialControlPort(tp.controlPort)
if err == nil {
log.Debugf("creating tor handler from system tor")
@ -493,7 +498,7 @@ func startTor(appDirectory string, bundledTorPath string, dataDir string, contro
// if not, try bundled tor, then running system tor
log.Debugln("checking if we can run bundled tor or system installed tor")
if bundledTorPath != "" && checkCmdlineTorVersion(bundledTorPath) {
if version, pass := checkCmdlineTorVersion(bundledTorPath); pass {
log.Debugln("bundled tor appears viable, attempting to use '" + bundledTorPath + "'")
t, err := tor.Start(context.TODO(), &tor.StartConf{ControlPort: tp.controlPort, DisableCookieAuth: true, UseEmbeddedControlConn: false, DisableEagerAuth: true, EnableNetwork: true, DataDir: dataDir, TorrcFile: path.Join(torDir, "torrc"), ExePath: bundledTorPath, DebugWriter: nil, ProcessCreator: newHideCmd(bundledTorPath)})
if err != nil {
@ -501,23 +506,25 @@ func startTor(appDirectory string, bundledTorPath string, dataDir string, contro
return nil, err
}
tp.t = t
} else if checkCmdlineTorVersion("tor") {
tp.version = version
} else if version, pass := checkCmdlineTorVersion("tor"); pass {
t, err := tor.Start(context.TODO(), &tor.StartConf{ControlPort: tp.controlPort, DisableCookieAuth: true, UseEmbeddedControlConn: false, DisableEagerAuth: true, EnableNetwork: true, DataDir: dataDir, TorrcFile: path.Join(torDir, "torrc"), DebugWriter: nil, ProcessCreator: newHideCmd("tor")})
if err != nil {
log.Debugf("Error connecting to self-run system tor: %v\n", err)
return nil, err
}
tp.t = t
tp.version = version
} else {
log.Debugln("Could not find a viable tor running or to run")
return nil, fmt.Errorf("could not connect to or start Tor that met requirements (min Tor version 0.3.5.x)")
}
err := tp.checkVersion()
version, err := tp.checkVersion()
if err == nil {
tp.t.DeleteDataDirOnClose = false // caller is responsible for dealing with cached information...
tp.dialer, err = tp.t.Dialer(context.TODO(), &tor.DialConf{Authenticator: tp.authenticator})
tp.callVersionCallback(tp.GetVersion())
tp.version = version
return tp, err
}
return nil, fmt.Errorf("could not connect to running tor: %v", err)
@ -588,7 +595,10 @@ func createFromExisting(controlport *control.Conn, datadir string) *tor.Tor {
return t
}
func checkCmdlineTorVersion(torCmd string) bool {
func checkCmdlineTorVersion(torCmd string) (string, bool) {
if torCmd == "" {
return "", false
}
// ideally we would use CommandContext with Timeout here
// but it doesn't work with programs that may launch other processes via scripts e.g. exec
// and the workout is more complex than just implementing the logic ourselves...
@ -615,13 +625,13 @@ func checkCmdlineTorVersion(torCmd string) bool {
if err != nil {
log.Debugf("tor process timed out")
return false
return "", false
}
re := regexp.MustCompile(`[0-1]\.[0-9]\.[0-9]\.[0-9]`)
sysTorVersion := re.Find(outb.Bytes())
log.Infof("tor version: %v", string(sysTorVersion))
return minTorVersionReqs(string(sysTorVersion))
return string(sysTorVersion), minTorVersionReqs(string(sysTorVersion))
}
// returns true if supplied version meets our min requirments

View File

@ -19,11 +19,19 @@ func getStatusCallback(progChan chan int) func(int, string) {
}
}
func getVersionCallback(verChan chan string) func(string) {
return func(version string) {
fmt.Printf("version: %v\n", version)
verChan <- version
}
}
func TestTorProvider(t *testing.T) {
goRoutineStart := runtime.NumGoroutine()
progChan := make(chan int, 10)
verChan := make(chan string, 10)
log.SetLevel(log.LevelDebug)
torpath := path.Join("..", "tmp/tor")
@ -43,6 +51,7 @@ func TestTorProvider(t *testing.T) {
return
}
acn.SetStatusCallback(getStatusCallback(progChan))
acn.SetVersionCallback(getVersionCallback(verChan))
progress := 0
for progress < 100 {
@ -57,6 +66,13 @@ func TestTorProvider(t *testing.T) {
progress = <-progChan
t.Logf("progress: %v", progress)
}
log.Debugf("Pulling tor version from version callback chan...\n")
version := <-verChan
if version == "" {
t.Errorf("failed to get tor version, got empty string\n")
} else {
log.Debugf("Tor version: %v\n", version)
}
// Test opening the OP Server
_, _, err = acn.Open("isbr2t6bflul2zyi6hjtnuezb2xvfr42svzjg2q3gyqfgg3wmnrbkkqd")