rename local variables acn; Add bootstrap status support to ACN/torprovider
This commit is contained in:
parent
b8a7cd702a
commit
38cff4212d
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.")
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Reference in New Issue