Merge branch 'acn2' of dan/libricochet-go into master
This commit is contained in:
commit
232849e304
|
@ -23,15 +23,15 @@ type RicochetApplication struct {
|
||||||
v3identity identity.Identity
|
v3identity identity.Identity
|
||||||
name string
|
name string
|
||||||
ls connectivity.ListenService
|
ls connectivity.ListenService
|
||||||
mn connectivity.ACN
|
acn connectivity.ACN
|
||||||
instances []*ApplicationInstance
|
instances []*ApplicationInstance
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
aif ApplicationInstanceFactory
|
aif ApplicationInstanceFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init initializes the underlying RicochetApplication datastructure, making it ready for use
|
// 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) {
|
func (ra *RicochetApplication) Init(acn connectivity.ACN, name string, v3identity identity.Identity, af ApplicationInstanceFactory, cm ContactManagerInterface) {
|
||||||
ra.mn = mn
|
ra.acn = acn
|
||||||
ra.name = name
|
ra.name = name
|
||||||
ra.v3identity = v3identity
|
ra.v3identity = v3identity
|
||||||
ra.aif = af
|
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)
|
// 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) {
|
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)
|
rc.TraceLog(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error in application.Open(): %v\n", err)
|
log.Printf("Error in application.Open(): %v\n", err)
|
||||||
|
|
|
@ -70,13 +70,13 @@ func main() {
|
||||||
echobot := new(application.RicochetApplication)
|
echobot := new(application.RicochetApplication)
|
||||||
cpubk, cprivk, err := ed25519.GenerateKey(rand.Reader)
|
cpubk, cprivk, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
|
||||||
mn, err := connectivity.StartTor(".", "")
|
acn, err := connectivity.StartTor(".", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Panicf("Unable to start Tor: %v", err)
|
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 {
|
if err != nil {
|
||||||
log.Fatalf("error setting up onion service: %v", err)
|
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())
|
log.Printf("echobot listening on %s", listenService.AddressFull())
|
||||||
go echobot.Run(listenService)
|
go echobot.Run(listenService)
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ func main() {
|
||||||
////////////
|
////////////
|
||||||
|
|
||||||
//alicebot should nominally be in another package to prevent initializing it directly
|
//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("be gay")
|
||||||
alice.SendMessage("do crime")
|
alice.SendMessage("do crime")
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ func main() {
|
||||||
time.Sleep(time.Second * 30)
|
time.Sleep(time.Second * 30)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAliceBot(mn connectivity.ACN, onion string) alicebot {
|
func NewAliceBot(acn connectivity.ACN, onion string) alicebot {
|
||||||
alice := alicebot{}
|
alice := alicebot{}
|
||||||
alice.messages = make(map[uint32]string)
|
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)
|
log.Fatalf("[alice] error generating key: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rc, err := goricochet.Open(mn, onion)
|
rc, err := goricochet.Open(acn, onion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("[alice] error connecting to echobot: %v", err)
|
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
|
// ACN is Anonymous Communication Network implementation wrapper that supports Open for new connections and Listen to accept connections
|
||||||
type ACN interface {
|
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 takes a hostname and returns a net.Conn to the derived endpoint
|
||||||
// Open allows a client to resolve various hostnames to connections
|
// Open allows a client to resolve various hostnames to connections
|
||||||
// The supported types are onions address are:
|
// The supported types are onions address are:
|
||||||
|
|
|
@ -29,6 +29,15 @@ func (ls *localListenService) Close() {
|
||||||
ls.l.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) {
|
func (lp *localProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
|
||||||
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%v", port))
|
l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%v", port))
|
||||||
return &localListenService{l}, err
|
return &localListenService{l}, err
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -51,6 +52,41 @@ func (ols *onionListenService) Close() {
|
||||||
ols.os.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) {
|
func (tp *torProvider) Listen(identity PrivateKey, port int) (ListenService, error) {
|
||||||
tp.lock.Lock()
|
tp.lock.Lock()
|
||||||
defer tp.lock.Unlock()
|
defer tp.lock.Unlock()
|
||||||
|
|
|
@ -1,12 +1,24 @@
|
||||||
package connectivity
|
package connectivity
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
func TestTorProvider(t *testing.T) {
|
func TestTorProvider(t *testing.T) {
|
||||||
m, err := StartTor(".", "")
|
acn, err := StartTor(".", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
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.
|
// will be closed. This function blocks until version negotiation has completed.
|
||||||
// The application should call Process() on the returned OpenConnection to continue
|
// The application should call Process() on the returned OpenConnection to continue
|
||||||
// handling protocol messages.
|
// handling protocol messages.
|
||||||
func Open(mn connectivity.ACN, remoteHostname string) (*connection.Connection, error) {
|
func Open(acn connectivity.ACN, remoteHostname string) (*connection.Connection, error) {
|
||||||
conn, remoteHostname, err := mn.Open(remoteHostname)
|
conn, remoteHostname, err := acn.Open(remoteHostname)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -19,12 +19,12 @@ func SimpleServer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRicochetOpen(t *testing.T) {
|
func TestRicochetOpen(t *testing.T) {
|
||||||
mn := connectivity.LocalProvider()
|
acn := connectivity.LocalProvider()
|
||||||
go SimpleServer()
|
go SimpleServer()
|
||||||
// Wait for Server to Initialize
|
// Wait for Server to Initialize
|
||||||
time.Sleep(time.Second)
|
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 err == nil {
|
||||||
if rc.IsInbound {
|
if rc.IsInbound {
|
||||||
t.Errorf("RicochetConnection declares itself as an Inbound connection after an Outbound attempt...that shouldn't happen")
|
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) {
|
func TestRicochetOpenWithError(t *testing.T) {
|
||||||
mn := connectivity.LocalProvider()
|
acn := connectivity.LocalProvider()
|
||||||
go BadServer()
|
go BadServer()
|
||||||
// Wait for Server to Initialize
|
// Wait for Server to Initialize
|
||||||
time.Sleep(time.Second)
|
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 {
|
if err == nil {
|
||||||
t.Errorf("Open should have failed because of bad version negotiation.")
|
t.Errorf("Open should have failed because of bad version negotiation.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRicochetOpenWithNoServer(t *testing.T) {
|
func TestRicochetOpenWithNoServer(t *testing.T) {
|
||||||
mn := connectivity.LocalProvider()
|
acn := connectivity.LocalProvider()
|
||||||
_, err := Open(mn, "127.0.0.1:11002|abcdefghijklmno.onion")
|
_, err := Open(acn, "127.0.0.1:11002|abcdefghijklmno.onion")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("Open should have failed because of bad version negotiation.")
|
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) {
|
func TestApplicationIntegration(t *testing.T) {
|
||||||
mn, err := connectivity.StartTor(".", "")
|
acn, err := connectivity.StartTor(".", "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Could not start tor: %v", err)
|
t.Fatalf("Could not start tor: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -124,7 +124,7 @@ func TestApplicationIntegration(t *testing.T) {
|
||||||
apubk, apk, _ := utils.GeneratePrivateKeyV3()
|
apubk, apk, _ := utils.GeneratePrivateKeyV3()
|
||||||
aliceAddr := utils.GetTorV3Hostname(apubk)
|
aliceAddr := utils.GetTorV3Hostname(apubk)
|
||||||
fmt.Println("Seting up alice's onion " + aliceAddr + "...")
|
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 {
|
if err != nil {
|
||||||
t.Fatalf("Could not setup Onion for Alice: %v", err)
|
t.Fatalf("Could not setup Onion for Alice: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -137,7 +137,7 @@ func TestApplicationIntegration(t *testing.T) {
|
||||||
return chat
|
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...")
|
fmt.Println("Running alice...")
|
||||||
go alice.Run(al)
|
go alice.Run(al)
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ func TestApplicationIntegration(t *testing.T) {
|
||||||
}
|
}
|
||||||
bobAddr := utils.GetTorV3Hostname(bpubk)
|
bobAddr := utils.GetTorV3Hostname(bpubk)
|
||||||
fmt.Println("Seting up bob's onion " + bobAddr + "...")
|
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 {
|
af.AddHandler("im.ricochet.chat", func(rai *application.ApplicationInstance) func() channels.Handler {
|
||||||
return func() channels.Handler {
|
return func() channels.Handler {
|
||||||
chat := new(channels.ChatChannel)
|
chat := new(channels.ChatChannel)
|
||||||
|
@ -157,7 +157,7 @@ func TestApplicationIntegration(t *testing.T) {
|
||||||
return chat
|
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)
|
go bob.Run(bl)
|
||||||
|
|
||||||
fmt.Println("Waiting for alice and bob hidden services to percolate...")
|
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)
|
time.Sleep(15 * time.Second)
|
||||||
|
|
||||||
fmt.Println("Shutting down bine/tor")
|
fmt.Println("Shutting down bine/tor")
|
||||||
mn.Close()
|
acn.Close()
|
||||||
|
|
||||||
finalGoRoutines := runtime.NumGoroutine()
|
finalGoRoutines := runtime.NumGoroutine()
|
||||||
|
|
||||||
|
|
Reference in New Issue