rename local variables acn; Add bootstrap status support to ACN/torprovider

This commit is contained in:
Dan Ballard 2018-11-21 22:15:35 -08:00
parent b8a7cd702a
commit 38cff4212d
9 changed files with 90 additions and 28 deletions

View File

@ -23,15 +23,15 @@ type RicochetApplication struct {
v3identity identity.Identity
name string
ls connectivity.ListenService
mn connectivity.ACN
acn connectivity.ACN
instances []*ApplicationInstance
lock sync.Mutex
aif ApplicationInstanceFactory
}
// Init initializes the underlying RicochetApplication datastructure, making it ready for use
func (ra *RicochetApplication) Init(mn connectivity.ACN, name string, v3identity identity.Identity, af ApplicationInstanceFactory, cm ContactManagerInterface) {
ra.mn = mn
func (ra *RicochetApplication) Init(acn connectivity.ACN, name string, v3identity identity.Identity, af ApplicationInstanceFactory, cm ContactManagerInterface) {
ra.acn = acn
ra.name = name
ra.v3identity = v3identity
ra.aif = af
@ -84,7 +84,7 @@ func (ra *RicochetApplication) HandleApplicationInstance(rai *ApplicationInstanc
// Open a connection to another Ricochet peer at onionAddress. If they are unknown to use, use requestMessage (otherwise can be blank)
func (ra *RicochetApplication) Open(onionAddress string, requestMessage string) (*ApplicationInstance, error) {
rc, err := goricochet.Open(ra.mn, onionAddress)
rc, err := goricochet.Open(ra.acn, onionAddress)
rc.TraceLog(true)
if err != nil {
log.Printf("Error in application.Open(): %v\n", err)

View File

@ -70,13 +70,13 @@ func main() {
echobot := new(application.RicochetApplication)
cpubk, cprivk, err := ed25519.GenerateKey(rand.Reader)
mn, err := connectivity.StartTor(".", "")
acn, err := connectivity.StartTor(".", "")
if err != nil {
log.Panicf("Unable to start Tor: %v", err)
}
defer mn.Close()
defer acn.Close()
listenService, err := mn.Listen(cprivk, application.RicochetPort)
listenService, err := acn.Listen(cprivk, application.RicochetPort)
if err != nil {
log.Fatalf("error setting up onion service: %v", err)
@ -94,7 +94,7 @@ func main() {
}
})
echobot.Init(mn, "echobot", identity.InitializeV3("echobot", &cprivk, &cpubk), af, new(application.AcceptAllContactManager))
echobot.Init(acn, "echobot", identity.InitializeV3("echobot", &cprivk, &cpubk), af, new(application.AcceptAllContactManager))
log.Printf("echobot listening on %s", listenService.AddressFull())
go echobot.Run(listenService)
@ -106,7 +106,7 @@ func main() {
////////////
//alicebot should nominally be in another package to prevent initializing it directly
alice := NewAliceBot(mn, listenService.AddressIdentity())
alice := NewAliceBot(acn, listenService.AddressIdentity())
alice.SendMessage("be gay")
alice.SendMessage("do crime")
@ -114,7 +114,7 @@ func main() {
time.Sleep(time.Second * 30)
}
func NewAliceBot(mn connectivity.ACN, onion string) alicebot {
func NewAliceBot(acn connectivity.ACN, onion string) alicebot {
alice := alicebot{}
alice.messages = make(map[uint32]string)
@ -124,7 +124,7 @@ func NewAliceBot(mn connectivity.ACN, onion string) alicebot {
log.Fatalf("[alice] error generating key: %v", err)
}
rc, err := goricochet.Open(mn, onion)
rc, err := goricochet.Open(acn, onion)
if err != nil {
log.Fatalf("[alice] error connecting to echobot: %v", err)
}

View File

@ -21,6 +21,11 @@ type ListenService interface {
// ACN is Anonymous Communication Network implementation wrapper that supports Open for new connections and Listen to accept connections
type ACN interface {
// GetBootstrapStatus returns an int 0-100 on the percent the bootstrapping of the underlying network is at and an optional string message
GetBootstrapStatus() (int, string)
// WaitTillBootstrapped Blocks until underlying network is bootstrapped
WaitTillBootstrapped()
// Open takes a hostname and returns a net.Conn to the derived endpoint
// Open allows a client to resolve various hostnames to connections
// The supported types are onions address are:

View File

@ -29,6 +29,15 @@ func (ls *localListenService) Close() {
ls.l.Close()
}
// GetBootstrapStatus returns an int 0-100 on the percent the bootstrapping of the underlying network is at and an optional string message
func (lp *localProvider) GetBootstrapStatus() (int, string) {
return 100, "Done"
}
// WaitTillBootstrapped Blocks until underlying network is bootstrapped
func (lp *localProvider) WaitTillBootstrapped() {
}
func (lp *localProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%v", port))
return &localListenService{l}, err

View File

@ -15,6 +15,7 @@ import (
"strconv"
"strings"
"sync"
"time"
)
const (
@ -51,6 +52,41 @@ func (ols *onionListenService) Close() {
ols.os.Close()
}
// GetBootstrapStatus returns an int 0-100 on the percent the bootstrapping of the underlying network is at and an optional string message
func (tp *torProvider) GetBootstrapStatus() (int, string) {
kvs, err := tp.t.Control.GetInfo("status/bootstrap-phase")
if err != nil {
return 0, "error"
}
progress := 0
status := ""
if len(kvs) > 0 {
progRe := regexp.MustCompile("PROGRESS=([0-9]*)")
sumRe := regexp.MustCompile("SUMMARY=\"(.*)\"$")
if progMatches := progRe.FindStringSubmatch(kvs[0].Val); len(progMatches) > 1 {
progress, _ = strconv.Atoi(progMatches[1])
}
if statusMatches := sumRe.FindStringSubmatch(kvs[0].Val); len(statusMatches) > 1 {
status = statusMatches[1]
}
}
return progress, status
}
// WaitTillBootstrapped Blocks until underlying network is bootstrapped
func (tp *torProvider) WaitTillBootstrapped() {
for true {
progress, _ := tp.GetBootstrapStatus()
if progress == 100 {
break
}
time.Sleep(100 * time.Millisecond)
}
}
func (tp *torProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
tp.lock.Lock()
defer tp.lock.Unlock()

View File

@ -1,12 +1,24 @@
package connectivity
import "testing"
import (
"fmt"
"testing"
"time"
)
func TestTorProvider(t *testing.T) {
m, err := StartTor(".", "")
acn, err := StartTor(".", "")
if err != nil {
t.Error(err)
}
m.Close()
progress := 0
status := ""
for progress < 100 {
progress, status = acn.GetBootstrapStatus()
fmt.Printf("%v %v\n", progress, status)
time.Sleep(100)
}
acn.Close()
}

View File

@ -13,8 +13,8 @@ import (
// will be closed. This function blocks until version negotiation has completed.
// The application should call Process() on the returned OpenConnection to continue
// handling protocol messages.
func Open(mn connectivity.ACN, remoteHostname string) (*connection.Connection, error) {
conn, remoteHostname, err := mn.Open(remoteHostname)
func Open(acn connectivity.ACN, remoteHostname string) (*connection.Connection, error) {
conn, remoteHostname, err := acn.Open(remoteHostname)
if err != nil {
return nil, err

View File

@ -19,12 +19,12 @@ func SimpleServer() {
}
func TestRicochetOpen(t *testing.T) {
mn := connectivity.LocalProvider()
acn := connectivity.LocalProvider()
go SimpleServer()
// Wait for Server to Initialize
time.Sleep(time.Second)
rc, err := Open(mn, "127.0.0.1:11000|abcdefghijklmno.onion")
rc, err := Open(acn, "127.0.0.1:11000|abcdefghijklmno.onion")
if err == nil {
if rc.IsInbound {
t.Errorf("RicochetConnection declares itself as an Inbound connection after an Outbound attempt...that shouldn't happen")
@ -46,19 +46,19 @@ func BadServer() {
}
func TestRicochetOpenWithError(t *testing.T) {
mn := connectivity.LocalProvider()
acn := connectivity.LocalProvider()
go BadServer()
// Wait for Server to Initialize
time.Sleep(time.Second)
_, err := Open(mn, "127.0.0.1:11001|abcdefghijklmno.onion")
_, err := Open(acn, "127.0.0.1:11001|abcdefghijklmno.onion")
if err == nil {
t.Errorf("Open should have failed because of bad version negotiation.")
}
}
func TestRicochetOpenWithNoServer(t *testing.T) {
mn := connectivity.LocalProvider()
_, err := Open(mn, "127.0.0.1:11002|abcdefghijklmno.onion")
acn := connectivity.LocalProvider()
_, err := Open(acn, "127.0.0.1:11002|abcdefghijklmno.onion")
if err == nil {
t.Errorf("Open should have failed because of bad version negotiation.")
}

View File

@ -98,7 +98,7 @@ func (bot *ChatEchoBot) ChatMessageAck(messageID uint32, accepted bool) {
}
func TestApplicationIntegration(t *testing.T) {
mn, err := connectivity.StartTor(".", "")
acn, err := connectivity.StartTor(".", "")
if err != nil {
t.Fatalf("Could not start tor: %v", err)
}
@ -124,7 +124,7 @@ func TestApplicationIntegration(t *testing.T) {
apubk, apk, _ := utils.GeneratePrivateKeyV3()
aliceAddr := utils.GetTorV3Hostname(apubk)
fmt.Println("Seting up alice's onion " + aliceAddr + "...")
al, err := mn.Listen(apk, application.RicochetPort)
al, err := acn.Listen(apk, application.RicochetPort)
if err != nil {
t.Fatalf("Could not setup Onion for Alice: %v", err)
}
@ -137,7 +137,7 @@ func TestApplicationIntegration(t *testing.T) {
return chat
}
})
alice.Init(mn, "Alice", identity.InitializeV3("Alice", &apk, &apubk), af, new(application.AcceptAllContactManager))
alice.Init(acn, "Alice", identity.InitializeV3("Alice", &apk, &apubk), af, new(application.AcceptAllContactManager))
fmt.Println("Running alice...")
go alice.Run(al)
@ -149,7 +149,7 @@ func TestApplicationIntegration(t *testing.T) {
}
bobAddr := utils.GetTorV3Hostname(bpubk)
fmt.Println("Seting up bob's onion " + bobAddr + "...")
bl, _ := mn.Listen(bpk, application.RicochetPort)
bl, _ := acn.Listen(bpk, application.RicochetPort)
af.AddHandler("im.ricochet.chat", func(rai *application.ApplicationInstance) func() channels.Handler {
return func() channels.Handler {
chat := new(channels.ChatChannel)
@ -157,7 +157,7 @@ func TestApplicationIntegration(t *testing.T) {
return chat
}
})
bob.Init(mn, "Bob", identity.InitializeV3("Bob", &bpk, &bpubk), af, new(application.AcceptAllContactManager))
bob.Init(acn, "Bob", identity.InitializeV3("Bob", &bpk, &bpubk), af, new(application.AcceptAllContactManager))
go bob.Run(bl)
fmt.Println("Waiting for alice and bob hidden services to percolate...")
@ -209,7 +209,7 @@ func TestApplicationIntegration(t *testing.T) {
time.Sleep(15 * time.Second)
fmt.Println("Shutting down bine/tor")
mn.Close()
acn.Close()
finalGoRoutines := runtime.NumGoroutine()