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 authenticator tor.Authenticator
isClosed bool isClosed bool
dataDir string dataDir string
version string
} }
func (ols *onionListenService) AddressFull() string { func (ols *onionListenService) AddressFull() string {
@ -210,6 +211,12 @@ func (tp *torProvider) GetBootstrapStatus() (int, string) {
func (tp *torProvider) GetVersion() string { func (tp *torProvider) GetVersion() string {
tp.lock.Lock() tp.lock.Lock()
defer tp.lock.Unlock() defer tp.lock.Unlock()
return tp.version
}
func (tp *torProvider) getVersionFromControlPort() string {
tp.lock.Lock()
defer tp.lock.Unlock()
if tp.t == nil { if tp.t == nil {
return "No Tor" return "No Tor"
@ -325,6 +332,7 @@ func (tp *torProvider) restart() {
// preserve status callback after shutdown // preserve status callback after shutdown
statusCallback := tp.statusCallback statusCallback := tp.statusCallback
versionCallback := tp.versionCallback
tp.t = nil tp.t = nil
log.Debugf("Restarting Tor Process") log.Debugf("Restarting Tor Process")
@ -335,6 +343,10 @@ func (tp *torProvider) restart() {
tp.t = newTp.t tp.t = newTp.t
tp.dialer = newTp.dialer tp.dialer = newTp.dialer
tp.statusCallback = statusCallback tp.statusCallback = statusCallback
tp.versionCallback = versionCallback
if tp.versionCallback != nil {
tp.versionCallback(tp.version)
}
tp.lastRestartTime = time.Now() tp.lastRestartTime = time.Now()
tp.isClosed = false tp.isClosed = false
go tp.monitorRestart() 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 // 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) { func NewTorACNWithAuth(appDirectory string, bundledTorPath string, dataDir string, controlPort int, authenticator tor.Authenticator) (connectivity.ACN, error) {
tp, err := startTor(appDirectory, bundledTorPath, dataDir, controlPort, authenticator) 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 // attempt connect to system tor
log.Debugf("dialing tor control port") log.Debugf("dialing tor control port")
controlport, err := dialControlPort(tp.controlPort) controlport, err := dialControlPort(tp.controlPort)
@ -457,13 +461,13 @@ func (tp *torProvider) checkVersion() error {
if err == nil { if err == nil {
if minTorVersionReqs(pinfo.TorVersion) { if minTorVersionReqs(pinfo.TorVersion) {
log.Debugln("OK version " + 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) { 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) 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") 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) controlport, err := dialControlPort(tp.controlPort)
if err == nil { if err == nil {
log.Debugf("creating tor handler from system tor") 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 // if not, try bundled tor, then running system tor
log.Debugln("checking if we can run bundled tor or system installed 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 + "'") 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)}) 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 { if err != nil {
@ -501,23 +506,25 @@ func startTor(appDirectory string, bundledTorPath string, dataDir string, contro
return nil, err return nil, err
} }
tp.t = t 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")}) 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 { if err != nil {
log.Debugf("Error connecting to self-run system tor: %v\n", err) log.Debugf("Error connecting to self-run system tor: %v\n", err)
return nil, err return nil, err
} }
tp.t = t tp.t = t
tp.version = version
} else { } else {
log.Debugln("Could not find a viable tor running or to run") 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)") 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 { if err == nil {
tp.t.DeleteDataDirOnClose = false // caller is responsible for dealing with cached information... 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.dialer, err = tp.t.Dialer(context.TODO(), &tor.DialConf{Authenticator: tp.authenticator})
tp.callVersionCallback(tp.GetVersion()) tp.version = version
return tp, err return tp, err
} }
return nil, fmt.Errorf("could not connect to running tor: %v", 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 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 // 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 // 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... // and the workout is more complex than just implementing the logic ourselves...
@ -615,13 +625,13 @@ func checkCmdlineTorVersion(torCmd string) bool {
if err != nil { if err != nil {
log.Debugf("tor process timed out") log.Debugf("tor process timed out")
return false return "", false
} }
re := regexp.MustCompile(`[0-1]\.[0-9]\.[0-9]\.[0-9]`) re := regexp.MustCompile(`[0-1]\.[0-9]\.[0-9]\.[0-9]`)
sysTorVersion := re.Find(outb.Bytes()) sysTorVersion := re.Find(outb.Bytes())
log.Infof("tor version: %v", string(sysTorVersion)) 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 // 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) { func TestTorProvider(t *testing.T) {
goRoutineStart := runtime.NumGoroutine() goRoutineStart := runtime.NumGoroutine()
progChan := make(chan int, 10) progChan := make(chan int, 10)
verChan := make(chan string, 10)
log.SetLevel(log.LevelDebug) log.SetLevel(log.LevelDebug)
torpath := path.Join("..", "tmp/tor") torpath := path.Join("..", "tmp/tor")
@ -43,6 +51,7 @@ func TestTorProvider(t *testing.T) {
return return
} }
acn.SetStatusCallback(getStatusCallback(progChan)) acn.SetStatusCallback(getStatusCallback(progChan))
acn.SetVersionCallback(getVersionCallback(verChan))
progress := 0 progress := 0
for progress < 100 { for progress < 100 {
@ -57,6 +66,13 @@ func TestTorProvider(t *testing.T) {
progress = <-progChan progress = <-progChan
t.Logf("progress: %v", progress) 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 // Test opening the OP Server
_, _, err = acn.Open("isbr2t6bflul2zyi6hjtnuezb2xvfr42svzjg2q3gyqfgg3wmnrbkkqd") _, _, err = acn.Open("isbr2t6bflul2zyi6hjtnuezb2xvfr42svzjg2q3gyqfgg3wmnrbkkqd")