Merge branch 'tor-attach' of dan/libricochet-go into master
This commit is contained in:
commit
328ffc9d76
|
@ -6,6 +6,9 @@ import (
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
||||||
"github.com/cretz/bine/control"
|
"github.com/cretz/bine/control"
|
||||||
"github.com/cretz/bine/tor"
|
"github.com/cretz/bine/tor"
|
||||||
|
bineed255192 "github.com/cretz/bine/torutil/ed25519"
|
||||||
|
"golang.org/x/crypto/ed25519"
|
||||||
|
"golang.org/x/crypto/sha3"
|
||||||
"net"
|
"net"
|
||||||
"net/textproto"
|
"net/textproto"
|
||||||
"os"
|
"os"
|
||||||
|
@ -94,16 +97,48 @@ func (tp *torProvider) WaitTillBootstrapped() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tp *torProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
|
func (tp *torProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
|
||||||
|
var onion = ""
|
||||||
|
var privkey ed25519.PrivateKey
|
||||||
|
|
||||||
|
switch pk := identity.(type) {
|
||||||
|
case ed25519.PrivateKey:
|
||||||
|
privkey = pk
|
||||||
|
gpubk := pk.Public()
|
||||||
|
switch pubk := gpubk.(type) {
|
||||||
|
case ed25519.PublicKey:
|
||||||
|
onion = utils.GetTorV3Hostname(pubk)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hack around tor detached onions not having a more obvious resume mechanism
|
||||||
|
// So we use deterministic ports
|
||||||
|
seedbytes := sha3.New224().Sum([]byte(onion))
|
||||||
|
localport := int(seedbytes[0]) + (int(seedbytes[1]) << 8)
|
||||||
|
if localport < 1024 { // this is not uniformly random, but we don't need it to be
|
||||||
|
localport += 1024
|
||||||
|
}
|
||||||
|
|
||||||
if tp.t == nil {
|
if tp.t == nil {
|
||||||
return nil, errors.New("Tor is offline")
|
return nil, errors.New("Tor is offline")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
localListener, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(localport))
|
||||||
|
|
||||||
tp.lock.Lock()
|
tp.lock.Lock()
|
||||||
defer tp.lock.Unlock()
|
defer tp.lock.Unlock()
|
||||||
conf := &tor.ListenConf{NoWait: true, Version3: true, Key: identity, RemotePorts: []int{port}, Detach: true, DiscardKey: true}
|
conf := &tor.ListenConf{NoWait: true, Version3: true, Key: identity, RemotePorts: []int{port}, Detach: true, DiscardKey: true, LocalListener: localListener}
|
||||||
os, err := tp.t.Listen(nil, conf)
|
os, err := tp.t.Listen(nil, conf)
|
||||||
|
if err != nil && strings.Contains(err.Error(), "550 Unspecified Tor error: Onion address collision") {
|
||||||
|
os = &tor.OnionService{Tor: tp.t, LocalListener: localListener, ID: onion, Version3: true, Key: bineed255192.FromCryptoPrivateKey(privkey), ClientAuths: make(map[string]string, 0), RemotePorts: []int{port}}
|
||||||
|
err = nil
|
||||||
|
}
|
||||||
|
// Not set in t.Listen if supplied, we want it to handle this however
|
||||||
|
os.CloseLocalListenerOnClose = true
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ols := &onionListenService{os: os, tp: tp}
|
ols := &onionListenService{os: os, tp: tp}
|
||||||
tp.childListeners[ols.AddressIdentity()] = ols
|
tp.childListeners[ols.AddressIdentity()] = ols
|
||||||
return ols, nil
|
return ols, nil
|
||||||
|
@ -198,7 +233,7 @@ func StartTor(appDirectory string, bundledTorPath string) (ACN, error) {
|
||||||
}
|
}
|
||||||
return tp, err
|
return tp, err
|
||||||
}
|
}
|
||||||
return nil, errors.New("Could not connect to or start Tor that met requirments")
|
return nil, errors.New("Could not connect to or start Tor that met requirments (min Tor version 0.3.5.x)")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tp *torProvider) unregisterListener(id string) {
|
func (tp *torProvider) unregisterListener(id string) {
|
||||||
|
|
|
@ -107,6 +107,9 @@ func TestApplicationIntegration(t *testing.T) {
|
||||||
t.Fatalf("Could not start tor: %v", err)
|
t.Fatalf("Could not start tor: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
acnStartGoRoutines := runtime.NumGoroutine()
|
||||||
|
|
||||||
messageStack := &Messages{}
|
messageStack := &Messages{}
|
||||||
messageStack.Init()
|
messageStack.Init()
|
||||||
|
|
||||||
|
@ -212,13 +215,16 @@ func TestApplicationIntegration(t *testing.T) {
|
||||||
fmt.Println("Shutting alice down...")
|
fmt.Println("Shutting alice down...")
|
||||||
alice.Shutdown()
|
alice.Shutdown()
|
||||||
time.Sleep(15 * time.Second)
|
time.Sleep(15 * time.Second)
|
||||||
|
aliceShutdownGoRoutines := runtime.NumGoroutine()
|
||||||
|
|
||||||
fmt.Println("Shutting down bine/tor")
|
fmt.Println("Shutting down bine/tor")
|
||||||
acn.Close()
|
acn.Close()
|
||||||
|
|
||||||
|
time.Sleep(5 * time.Second)
|
||||||
|
|
||||||
finalGoRoutines := runtime.NumGoroutine()
|
finalGoRoutines := runtime.NumGoroutine()
|
||||||
|
|
||||||
fmt.Printf("startGoRoutines: %v\nrunningGoRoutines: %v\nconnectedGoRoutines: %v\nBobShutdownGoRoutines: %v\nfinalGoRoutines: %v\n", startGoRoutines, runningGoRoutines, connectedGoRoutines, bobShutdownGoRoutines, finalGoRoutines)
|
fmt.Printf("startGoRoutines: %v\nacnStartedGoRoutines: %v\nrunningGoRoutines: %v\nconnectedGoRoutines: %v\nBobShutdownGoRoutines: %v\naliceShutdownGoRoutines: %v\nfinalGoRoutines: %v\n", startGoRoutines, acnStartGoRoutines, runningGoRoutines, connectedGoRoutines, bobShutdownGoRoutines, aliceShutdownGoRoutines, finalGoRoutines)
|
||||||
|
|
||||||
if finalGoRoutines != startGoRoutines {
|
if finalGoRoutines != startGoRoutines {
|
||||||
t.Errorf("After shutting alice and bob down, go routines were not at start value. Expected: %v Actual: %v", startGoRoutines, finalGoRoutines)
|
t.Errorf("After shutting alice and bob down, go routines were not at start value. Expected: %v Actual: %v", startGoRoutines, finalGoRoutines)
|
||||||
|
|
Reference in New Issue