Merge branch 'race' of dan/cwtch into master
the build was successful
Details
the build was successful
Details
This commit is contained in:
commit
dc7b1caef3
|
@ -43,7 +43,7 @@ pipeline:
|
||||||
commands:
|
commands:
|
||||||
- ./tor -f ./torrc
|
- ./tor -f ./torrc
|
||||||
- sleep 15
|
- sleep 15
|
||||||
- go test -v cwtch.im/cwtch/testing/
|
- go test -race -v cwtch.im/cwtch/testing/
|
||||||
notify-email:
|
notify-email:
|
||||||
image: drillster/drone-email
|
image: drillster/drone-email
|
||||||
host: build.openprivacy.ca
|
host: build.openprivacy.ca
|
||||||
|
|
|
@ -83,8 +83,8 @@ func (ac *applicationClient) newPeer(localID, key, salt string, reload bool) {
|
||||||
peer := peer.FromProfile(profile)
|
peer := peer.FromProfile(profile)
|
||||||
peer.Init(eventBus)
|
peer.Init(eventBus)
|
||||||
|
|
||||||
ac.acmutex.Lock()
|
ac.peerLock.Lock()
|
||||||
defer ac.acmutex.Unlock()
|
defer ac.peerLock.Unlock()
|
||||||
ac.peers[profile.Onion] = peer
|
ac.peers[profile.Onion] = peer
|
||||||
ac.eventBuses[profile.Onion] = eventBus
|
ac.eventBuses[profile.Onion] = eventBus
|
||||||
npEvent := event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: profile.Onion})
|
npEvent := event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: profile.Onion})
|
||||||
|
|
|
@ -150,6 +150,8 @@ func (as *applicationService) getACNStatusHandler() func(int, string) {
|
||||||
return func(progress int, status string) {
|
return func(progress int, status string) {
|
||||||
progStr := strconv.Itoa(progress)
|
progStr := strconv.Itoa(progress)
|
||||||
as.bridge.Write(&event.IPCMessage{Dest: DestApp, Message: event.NewEventList(event.ACNStatus, event.Progreess, progStr, event.Status, status)})
|
as.bridge.Write(&event.IPCMessage{Dest: DestApp, Message: event.NewEventList(event.ACNStatus, event.Progreess, progStr, event.Status, status)})
|
||||||
|
as.applicationCore.coremutex.Lock()
|
||||||
|
defer as.applicationCore.coremutex.Unlock()
|
||||||
for _, bus := range as.eventBuses {
|
for _, bus := range as.eventBuses {
|
||||||
bus.Publish(event.NewEventList(event.ACNStatus, event.Progreess, progStr, event.Status, status))
|
bus.Publish(event.NewEventList(event.ACNStatus, event.Progreess, progStr, event.Status, status))
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type appletPeers struct {
|
type appletPeers struct {
|
||||||
|
peerLock sync.Mutex
|
||||||
peers map[string]peer.CwtchPeer
|
peers map[string]peer.CwtchPeer
|
||||||
launched bool // bit hacky, place holder while we transition to full multi peer support and a better api
|
launched bool // bit hacky, place holder while we transition to full multi peer support and a better api
|
||||||
}
|
}
|
||||||
|
@ -46,13 +47,19 @@ func (ap *appletPeers) init() {
|
||||||
// LaunchPeers starts each peer Listening and connecting to peers and groups
|
// LaunchPeers starts each peer Listening and connecting to peers and groups
|
||||||
func (ap *appletPeers) LaunchPeers() {
|
func (ap *appletPeers) LaunchPeers() {
|
||||||
log.Debugf("appletPeers LaunchPeers\n")
|
log.Debugf("appletPeers LaunchPeers\n")
|
||||||
|
ap.peerLock.Lock()
|
||||||
|
defer ap.peerLock.Unlock()
|
||||||
if ap.launched {
|
if ap.launched {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, p := range ap.peers {
|
for pid, p := range ap.peers {
|
||||||
|
log.Debugf("Launching %v\n", pid)
|
||||||
p.Listen()
|
p.Listen()
|
||||||
|
log.Debugf("done Listen() for %v\n", pid)
|
||||||
p.StartPeersConnections()
|
p.StartPeersConnections()
|
||||||
|
log.Debugf("done StartPeersConnections() for %v\n", pid)
|
||||||
p.StartGroupConnections()
|
p.StartGroupConnections()
|
||||||
|
log.Debugf("done StartGroupConnections() for %v\n", pid)
|
||||||
}
|
}
|
||||||
ap.launched = true
|
ap.launched = true
|
||||||
}
|
}
|
||||||
|
@ -60,8 +67,11 @@ func (ap *appletPeers) LaunchPeers() {
|
||||||
// ListPeers returns a map of onions to their profile's Name
|
// ListPeers returns a map of onions to their profile's Name
|
||||||
func (ap *appletPeers) ListPeers() map[string]string {
|
func (ap *appletPeers) ListPeers() map[string]string {
|
||||||
keys := map[string]string{}
|
keys := map[string]string{}
|
||||||
|
|
||||||
|
ap.peerLock.Lock()
|
||||||
|
defer ap.peerLock.Unlock()
|
||||||
for k, p := range ap.peers {
|
for k, p := range ap.peers {
|
||||||
keys[k] = p.GetProfile().Name
|
keys[k] = p.GetName()
|
||||||
}
|
}
|
||||||
return keys
|
return keys
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,14 +14,14 @@ import (
|
||||||
|
|
||||||
func waitForPeerGroupConnection(peer peer.CwtchPeer, groupID string) error {
|
func waitForPeerGroupConnection(peer peer.CwtchPeer, groupID string) error {
|
||||||
for {
|
for {
|
||||||
_, ok := peer.GetProfile().Groups[groupID]
|
group := peer.GetGroup(groupID)
|
||||||
if ok {
|
if group != nil {
|
||||||
state := peer.GetGroupState(groupID)
|
state, _ := peer.GetGroupState(groupID)
|
||||||
if state == connections.FAILED {
|
if state == connections.FAILED {
|
||||||
return errors.New("Connection to group " + groupID + " failed!")
|
return errors.New("Connection to group " + groupID + " failed!")
|
||||||
}
|
}
|
||||||
if state != connections.AUTHENTICATED {
|
if state != connections.AUTHENTICATED {
|
||||||
fmt.Printf("peer %v waiting to authenticate with group %v 's server, current state: %v\n", peer.GetProfile().Onion, groupID, connections.ConnectionStateName[state])
|
fmt.Printf("peer %v waiting to authenticate with group %v 's server, current state: %v\n", peer.GetOnion(), groupID, connections.ConnectionStateName[state])
|
||||||
time.Sleep(time.Second * 10)
|
time.Sleep(time.Second * 10)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -84,8 +84,8 @@ func printMessage(m model.Message) {
|
||||||
name := "unknown"
|
name := "unknown"
|
||||||
if p != nil {
|
if p != nil {
|
||||||
name = p.Name
|
name = p.Name
|
||||||
} else if peer.GetProfile().Onion == m.PeerID {
|
} else if peer.GetOnion() == m.PeerID {
|
||||||
name = peer.GetProfile().Name
|
name = peer.GetName()
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Printf("%v %v (%v): %v\n", m.Timestamp, name, m.PeerID, m.Message)
|
fmt.Printf("%v %v (%v): %v\n", m.Timestamp, name, m.PeerID, m.Message)
|
||||||
|
@ -221,7 +221,7 @@ func handleAppEvents(em event.Manager) {
|
||||||
p := app.GetPeer(onion)
|
p := app.GetPeer(onion)
|
||||||
app.LaunchPeers()
|
app.LaunchPeers()
|
||||||
|
|
||||||
fmt.Printf("\nLoaded profile %v (%v)\n", p.GetProfile().Name, p.GetProfile().Onion)
|
fmt.Printf("\nLoaded profile %v (%v)\n", p.GetName(), p.GetOnion())
|
||||||
suggestions = append(suggestionsBase, suggestionsSelectedProfile...)
|
suggestions = append(suggestionsBase, suggestionsSelectedProfile...)
|
||||||
|
|
||||||
profiles := app.ListPeers()
|
profiles := app.ListPeers()
|
||||||
|
@ -304,9 +304,9 @@ func main() {
|
||||||
|
|
||||||
prmpt = "cwtch> "
|
prmpt = "cwtch> "
|
||||||
if group != nil {
|
if group != nil {
|
||||||
prmpt = fmt.Sprintf("cwtch %v (%v) [%v] say> ", peer.GetProfile().Name, peer.GetProfile().Onion, group.GroupID)
|
prmpt = fmt.Sprintf("cwtch %v (%v) [%v] say> ", peer.GetName(), peer.GetOnion(), group.GroupID)
|
||||||
} else if peer != nil {
|
} else if peer != nil {
|
||||||
prmpt = fmt.Sprintf("cwtch %v (%v)> ", peer.GetProfile().Name, peer.GetProfile().Onion)
|
prmpt = fmt.Sprintf("cwtch %v (%v)> ", peer.GetName(), peer.GetOnion())
|
||||||
}
|
}
|
||||||
|
|
||||||
text := prompt.Input(prmpt, completer, prompt.OptionSuggestionBGColor(prompt.Purple),
|
text := prompt.Input(prmpt, completer, prompt.OptionSuggestionBGColor(prompt.Purple),
|
||||||
|
@ -409,7 +409,7 @@ func main() {
|
||||||
// Auto cwtchPeer / Join Server
|
// Auto cwtchPeer / Join Server
|
||||||
// TODO There are some privacy implications with this that we should
|
// TODO There are some privacy implications with this that we should
|
||||||
// think over.
|
// think over.
|
||||||
for _, name := range p.GetProfile().GetContacts() {
|
for _, name := range p.GetContacts() {
|
||||||
profile := p.GetContact(name)
|
profile := p.GetContact(name)
|
||||||
if profile.Trusted && !profile.Blocked {
|
if profile.Trusted && !profile.Blocked {
|
||||||
p.PeerWithOnion(profile.Onion)
|
p.PeerWithOnion(profile.Onion)
|
||||||
|
@ -428,7 +428,7 @@ func main() {
|
||||||
}
|
}
|
||||||
case "/info":
|
case "/info":
|
||||||
if peer != nil {
|
if peer != nil {
|
||||||
fmt.Printf("Address cwtch:%v\n", peer.GetProfile().Onion)
|
fmt.Printf("Address cwtch:%v\n", peer.GetOnion())
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Profile needs to be set\n")
|
fmt.Printf("Profile needs to be set\n")
|
||||||
}
|
}
|
||||||
|
@ -594,7 +594,7 @@ func main() {
|
||||||
for i := 0; i < 100; i++ {
|
for i := 0; i < 100; i++ {
|
||||||
found := false
|
found := false
|
||||||
for _, m := range timeline {
|
for _, m := range timeline {
|
||||||
if m.Message == fmt.Sprintf("this is message %v", i) && m.PeerID == peer.GetProfile().Onion {
|
if m.Message == fmt.Sprintf("this is message %v", i) && m.PeerID == peer.GetOnion() {
|
||||||
found = true
|
found = true
|
||||||
latency := m.Received.Sub(m.Timestamp)
|
latency := m.Received.Sub(m.Timestamp)
|
||||||
fmt.Printf("Latency for Message %v was %v\n", i, latency)
|
fmt.Printf("Latency for Message %v was %v\n", i, latency)
|
||||||
|
|
|
@ -26,7 +26,7 @@ func main() {
|
||||||
app.CreatePeer("alice", "be gay, do crimes")
|
app.CreatePeer("alice", "be gay, do crimes")
|
||||||
alice := utils.WaitGetPeer(app, "alice")
|
alice := utils.WaitGetPeer(app, "alice")
|
||||||
app.LaunchPeers()
|
app.LaunchPeers()
|
||||||
eventBus := app.GetEventBus(alice.GetProfile().Onion)
|
eventBus := app.GetEventBus(alice.GetOnion())
|
||||||
queue := event.NewQueue()
|
queue := event.NewQueue()
|
||||||
eventBus.Subscribe(event.NewMessageFromPeer, queue)
|
eventBus.Subscribe(event.NewMessageFromPeer, queue)
|
||||||
|
|
||||||
|
|
|
@ -3,17 +3,16 @@
|
||||||
package bridge
|
package bridge
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/protocol/connections"
|
"cwtch.im/cwtch/protocol/connections"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
|
||||||
"syscall"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"cwtch.im/cwtch/event"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
/* pipeBridge creates a pair of named pipes
|
/* pipeBridge creates a pair of named pipes
|
||||||
|
@ -76,23 +75,37 @@ func NewPipeBridgeService(inFilename, outFilename string) event.IPCBridge {
|
||||||
return pb
|
return pb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pb *pipeBridge) setState(state connections.ConnectionState) {
|
||||||
|
pb.lock.Lock()
|
||||||
|
defer pb.lock.Unlock()
|
||||||
|
|
||||||
|
pb.state = state
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pb *pipeBridge) getState() connections.ConnectionState {
|
||||||
|
pb.lock.Lock()
|
||||||
|
defer pb.lock.Unlock()
|
||||||
|
|
||||||
|
return pb.state
|
||||||
|
}
|
||||||
|
|
||||||
func (pb *pipeBridge) connectionManager() {
|
func (pb *pipeBridge) connectionManager() {
|
||||||
for pb.state != connections.KILLED {
|
for pb.getState() != connections.KILLED {
|
||||||
log.Debugf("clientConnManager loop start init\n")
|
log.Debugf("clientConnManager loop start init\n")
|
||||||
pb.state = connections.CONNECTING
|
pb.setState(connections.CONNECTING)
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
log.Debugf("%v open file infile\n", pb.name)
|
log.Debugf("%v open file infile\n", pb.name)
|
||||||
pb.in, err = os.OpenFile(pb.infile, os.O_RDWR, 0600)
|
pb.in, err = os.OpenFile(pb.infile, os.O_RDWR, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pb.state = connections.DISCONNECTED
|
pb.setState(connections.DISCONNECTED)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("%v open file outfile\n", pb.name)
|
log.Debugf("%v open file outfile\n", pb.name)
|
||||||
pb.out, err = os.OpenFile(pb.outfile, os.O_RDWR, 0600)
|
pb.out, err = os.OpenFile(pb.outfile, os.O_RDWR, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
pb.state = connections.DISCONNECTED
|
pb.setState(connections.DISCONNECTED)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,12 +180,12 @@ func (pb *pipeBridge) threeShakeClient() bool {
|
||||||
func (pb *pipeBridge) handleConns() {
|
func (pb *pipeBridge) handleConns() {
|
||||||
|
|
||||||
if !pb.threeShake() {
|
if !pb.threeShake() {
|
||||||
pb.state = connections.FAILED
|
pb.setState(connections.FAILED)
|
||||||
pb.closeReset()
|
pb.closeReset()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
pb.state = connections.AUTHENTICATED
|
pb.setState(connections.AUTHENTICATED)
|
||||||
|
|
||||||
pb.closedChan = make(chan bool, 5)
|
pb.closedChan = make(chan bool, 5)
|
||||||
|
|
||||||
|
@ -183,8 +196,8 @@ func (pb *pipeBridge) handleConns() {
|
||||||
|
|
||||||
<-pb.closedChan
|
<-pb.closedChan
|
||||||
log.Debugf("handleConns <-closedChan (%v)\n", pb.name)
|
log.Debugf("handleConns <-closedChan (%v)\n", pb.name)
|
||||||
if pb.state != connections.KILLED {
|
if pb.getState() != connections.KILLED {
|
||||||
pb.state = connections.FAILED
|
pb.setState(connections.FAILED)
|
||||||
}
|
}
|
||||||
pb.closeReset()
|
pb.closeReset()
|
||||||
log.Debugf("handleConns done for %v, exit\n", pb.name)
|
log.Debugf("handleConns done for %v, exit\n", pb.name)
|
||||||
|
@ -196,7 +209,7 @@ func (pb *pipeBridge) closeReset() {
|
||||||
close(pb.read)
|
close(pb.read)
|
||||||
pb.write.Close()
|
pb.write.Close()
|
||||||
|
|
||||||
if pb.state != connections.KILLED {
|
if pb.getState() != connections.KILLED {
|
||||||
pb.read = make(chan event.IPCMessage, maxBufferSize)
|
pb.read = make(chan event.IPCMessage, maxBufferSize)
|
||||||
pb.write = newInfiniteChannel()
|
pb.write = newInfiniteChannel()
|
||||||
}
|
}
|
||||||
|
@ -219,7 +232,7 @@ func (pb *pipeBridge) handleWrite() {
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("handleWrite <- message: %v\n", message)
|
log.Debugf("handleWrite <- message: %v\n", message)
|
||||||
}
|
}
|
||||||
if pb.state == connections.AUTHENTICATED {
|
if pb.getState() == connections.AUTHENTICATED {
|
||||||
encMessage := &event.IPCMessage{Dest: message.Dest, Message: event.Event{EventType: message.Message.EventType, EventID: message.Message.EventID, Data: make(map[event.Field]string)}}
|
encMessage := &event.IPCMessage{Dest: message.Dest, Message: event.Event{EventType: message.Message.EventType, EventID: message.Message.EventID, Data: make(map[event.Field]string)}}
|
||||||
for k, v := range message.Message.Data {
|
for k, v := range message.Message.Data {
|
||||||
encMessage.Message.Data[k] = base64.StdEncoding.EncodeToString([]byte(v))
|
encMessage.Message.Data[k] = base64.StdEncoding.EncodeToString([]byte(v))
|
||||||
|
@ -276,7 +289,7 @@ func (pb *pipeBridge) Read() (*event.IPCMessage, bool) {
|
||||||
log.Debugf("Read() %v...\n", pb.name)
|
log.Debugf("Read() %v...\n", pb.name)
|
||||||
var ok = false
|
var ok = false
|
||||||
var message event.IPCMessage
|
var message event.IPCMessage
|
||||||
for !ok && pb.state != connections.KILLED {
|
for !ok && pb.getState() != connections.KILLED {
|
||||||
message, ok = <-pb.read
|
message, ok = <-pb.read
|
||||||
if message.Message.EventType == event.EncryptedGroupMessage || message.Message.EventType == event.SendMessageToGroup || message.Message.EventType == event.NewMessageFromGroup {
|
if message.Message.EventType == event.EncryptedGroupMessage || message.Message.EventType == event.SendMessageToGroup || message.Message.EventType == event.NewMessageFromGroup {
|
||||||
log.Debugf("Read %v: %v %v ...\n", pb.name, message.Dest, message.Message.EventType)
|
log.Debugf("Read %v: %v %v ...\n", pb.name, message.Dest, message.Message.EventType)
|
||||||
|
@ -284,7 +297,7 @@ func (pb *pipeBridge) Read() (*event.IPCMessage, bool) {
|
||||||
log.Debugf("Read %v: %v\n", pb.name, message)
|
log.Debugf("Read %v: %v\n", pb.name, message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &message, pb.state != connections.KILLED
|
return &message, pb.getState() != connections.KILLED
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pb *pipeBridge) Write(message *event.IPCMessage) {
|
func (pb *pipeBridge) Write(message *event.IPCMessage) {
|
||||||
|
@ -298,7 +311,7 @@ func (pb *pipeBridge) Write(message *event.IPCMessage) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pb *pipeBridge) Shutdown() {
|
func (pb *pipeBridge) Shutdown() {
|
||||||
log.Debugf("pb.Shutdown() for %v currently in state: %v\n", pb.name, connections.ConnectionStateName[pb.state])
|
log.Debugf("pb.Shutdown() for %v currently in state: %v\n", pb.name, connections.ConnectionStateName[pb.getState()])
|
||||||
pb.state = connections.KILLED
|
pb.state = connections.KILLED
|
||||||
pb.closedChan <- true
|
pb.closedChan <- true
|
||||||
log.Debugf("Done Shutdown for %v\n", pb.name)
|
log.Debugf("Done Shutdown for %v\n", pb.name)
|
||||||
|
|
13
go.mod
13
go.mod
|
@ -2,17 +2,16 @@ module cwtch.im/cwtch
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cwtch.im/tapir v0.1.14
|
cwtch.im/tapir v0.1.14
|
||||||
git.openprivacy.ca/openprivacy/libricochet-go v1.0.9
|
git.openprivacy.ca/openprivacy/libricochet-go v1.0.10
|
||||||
github.com/c-bata/go-prompt v0.2.3
|
github.com/c-bata/go-prompt v0.2.3
|
||||||
github.com/golang/protobuf v1.3.3
|
github.com/golang/protobuf v1.3.3
|
||||||
github.com/mattn/go-colorable v0.1.2 // indirect
|
github.com/mattn/go-runewidth v0.0.8 // indirect
|
||||||
github.com/mattn/go-runewidth v0.0.4 // indirect
|
github.com/mattn/go-tty v0.0.3 // indirect
|
||||||
github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859 // indirect
|
|
||||||
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 // indirect
|
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 // indirect
|
||||||
github.com/struCoder/pidusage v0.1.2
|
github.com/struCoder/pidusage v0.1.3
|
||||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
|
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 // indirect
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
42
go.sum
42
go.sum
|
@ -1,9 +1,8 @@
|
||||||
cwtch.im/tapir v0.1.14 h1:lg+reZNT998l++4Q4RQBLXYv3ukqWffhI0Wed9RSjuA=
|
cwtch.im/tapir v0.1.14 h1:lg+reZNT998l++4Q4RQBLXYv3ukqWffhI0Wed9RSjuA=
|
||||||
cwtch.im/tapir v0.1.14/go.mod h1:QwERb982YIes9UOxDqIthm1HZ1xy0YQetD2+XxDbg9Y=
|
cwtch.im/tapir v0.1.14/go.mod h1:QwERb982YIes9UOxDqIthm1HZ1xy0YQetD2+XxDbg9Y=
|
||||||
git.openprivacy.ca/openprivacy/libricochet-go v1.0.4 h1:GWLMJ5jBSIC/gFXzdbbeVz7fIAn2FTgW8+wBci6/3Ek=
|
|
||||||
git.openprivacy.ca/openprivacy/libricochet-go v1.0.4/go.mod h1:yMSG1gBaP4f1U+RMZXN85d29D39OK5s8aTpyVRoH5FY=
|
git.openprivacy.ca/openprivacy/libricochet-go v1.0.4/go.mod h1:yMSG1gBaP4f1U+RMZXN85d29D39OK5s8aTpyVRoH5FY=
|
||||||
git.openprivacy.ca/openprivacy/libricochet-go v1.0.9 h1:saqwSfxx8MJ16KT10F3wSiMi8iWvgFdrCkUk5WZVGzs=
|
git.openprivacy.ca/openprivacy/libricochet-go v1.0.10 h1:yxEqFJH4EdacPwGuOXx+QieYqIPDyzWP50H27EI7fxI=
|
||||||
git.openprivacy.ca/openprivacy/libricochet-go v1.0.9/go.mod h1:jJdxIwYDCcM4w4HAydeHuksPRTirUnyERAloPL0qtic=
|
git.openprivacy.ca/openprivacy/libricochet-go v1.0.10/go.mod h1:jJdxIwYDCcM4w4HAydeHuksPRTirUnyERAloPL0qtic=
|
||||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
|
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412 h1:w1UutsfOrms1J05zt7ISrnJIXKzwaspym5BTKGx93EI=
|
||||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||||
github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s=
|
github.com/c-bata/go-prompt v0.2.3 h1:jjCS+QhG/sULBhAaBdjb2PlMRVaKXQgn+4yzaauvs2s=
|
||||||
|
@ -15,21 +14,28 @@ github.com/cretz/bine v0.1.1-0.20200124154328-f9f678b84cca/go.mod h1:6PF6fWAvYtw
|
||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
|
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||||
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||||
|
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||||
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||||
github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
|
github.com/gtank/merlin v0.1.1 h1:eQ90iG7K9pOhtereWsmyRJ6RAwcP4tHTDBHXNg+u5is=
|
||||||
github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
|
github.com/gtank/merlin v0.1.1/go.mod h1:T86dnYJhcGOh5BjZFCJWTDeTK7XW8uE+E21Cy/bIQ+s=
|
||||||
github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
|
github.com/gtank/ristretto255 v0.1.2 h1:JEqUCPA1NvLq5DwYtuzigd7ss8fwbYay9fi4/5uMzcc=
|
||||||
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
|
github.com/gtank/ristretto255 v0.1.2/go.mod h1:Ph5OpO6c7xKUGROZfWVLiJf9icMDwUeIvY4OmlYW69o=
|
||||||
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
|
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
|
||||||
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
|
||||||
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
|
||||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||||
github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y=
|
github.com/mattn/go-isatty v0.0.10 h1:qxFzApOv4WsAL965uUPIsXzAKCZxN2p9UqdhFS4ZW10=
|
||||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
|
||||||
github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859 h1:smQbSzmT3EHl4EUwtFwFGmGIpiYgIiiPeVv1uguIQEE=
|
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
github.com/mattn/go-tty v0.0.0-20190424173100-523744f04859/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
|
github.com/mattn/go-runewidth v0.0.8 h1:3tS41NlGYSmhhe/8fhGRzc+z3AYCw1Fe1WAyLuujKs0=
|
||||||
|
github.com/mattn/go-runewidth v0.0.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||||
|
github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI=
|
||||||
|
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
|
||||||
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
|
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0=
|
||||||
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
|
github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM=
|
||||||
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0=
|
github.com/pkg/term v0.0.0-20190109203006-aa71e9d9e942 h1:A7GG7zcGjl3jqAqGPmcNjd/D9hzL95SuoOQAaFNdLU0=
|
||||||
|
@ -39,8 +45,8 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||||
github.com/struCoder/pidusage v0.1.2 h1:fFPTThlcWFQyizv3xKs5Lyq1lpG5lZ36arEGNhWz2Vs=
|
github.com/struCoder/pidusage v0.1.3 h1:pZcSa6asBE38TJtW0Nui6GeCjLTpaT/jAnNP7dUTLSQ=
|
||||||
github.com/struCoder/pidusage v0.1.2/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI=
|
github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI=
|
||||||
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
|
||||||
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
|
||||||
golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b h1:Ib/yptP38nXZFMwqWSip+OKuMP9OkyDe3p+DssP8n9w=
|
golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b h1:Ib/yptP38nXZFMwqWSip+OKuMP9OkyDe3p+DssP8n9w=
|
||||||
|
@ -48,19 +54,25 @@ golang.org/x/crypto v0.0.0-20190128193316-c7b33c32a30b/go.mod h1:6SG95UA2DQfeDnf
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
|
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
|
||||||
|
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
|
||||||
|
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
|
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
|
||||||
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa h1:F+8P+gmewFQYRk6JoLQLwjBCTu3mcIURZfNkVweuRKA=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
|
||||||
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI=
|
||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9 h1:1/DFK4b7JH8DmkqhUk48onnSfrPzImPoVxuomtbT2nk=
|
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0=
|
||||||
|
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
|
|
@ -40,6 +40,7 @@ type CwtchPeer interface {
|
||||||
TrustPeer(string) error
|
TrustPeer(string) error
|
||||||
BlockPeer(string) error
|
BlockPeer(string) error
|
||||||
UnblockPeer(string) error
|
UnblockPeer(string) error
|
||||||
|
ProcessInvite(string, string) (string, error)
|
||||||
AcceptInvite(string) error
|
AcceptInvite(string) error
|
||||||
RejectInvite(string)
|
RejectInvite(string)
|
||||||
DeleteContact(string)
|
DeleteContact(string)
|
||||||
|
@ -49,8 +50,11 @@ type CwtchPeer interface {
|
||||||
SendMessageToGroup(string, string) error
|
SendMessageToGroup(string, string) error
|
||||||
SendMessageToGroupTracked(string, string) (string, error)
|
SendMessageToGroupTracked(string, string) (string, error)
|
||||||
|
|
||||||
GetProfile() *model.Profile
|
GetName() string
|
||||||
GetPeerState(string) connections.ConnectionState
|
SetName(string)
|
||||||
|
GetOnion() string
|
||||||
|
|
||||||
|
GetPeerState(string) (connections.ConnectionState, bool)
|
||||||
|
|
||||||
StartGroup(string) (string, []byte, error)
|
StartGroup(string) (string, []byte, error)
|
||||||
|
|
||||||
|
@ -58,7 +62,7 @@ type CwtchPeer interface {
|
||||||
ExportGroup(string) (string, error)
|
ExportGroup(string) (string, error)
|
||||||
|
|
||||||
GetGroup(string) *model.Group
|
GetGroup(string) *model.Group
|
||||||
GetGroupState(string) connections.ConnectionState
|
GetGroupState(string) (connections.ConnectionState, bool)
|
||||||
GetGroups() []string
|
GetGroups() []string
|
||||||
AddContact(nick, onion string, trusted bool)
|
AddContact(nick, onion string, trusted bool)
|
||||||
GetContacts() []string
|
GetContacts() []string
|
||||||
|
@ -131,6 +135,8 @@ func (cp *cwtchPeer) ImportGroup(exportedInvite string) (err error) {
|
||||||
|
|
||||||
// ExportGroup serializes a group invite so it can be given offline
|
// ExportGroup serializes a group invite so it can be given offline
|
||||||
func (cp *cwtchPeer) ExportGroup(groupID string) (string, error) {
|
func (cp *cwtchPeer) ExportGroup(groupID string) (string, error) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
group := cp.Profile.GetGroup(groupID)
|
group := cp.Profile.GetGroup(groupID)
|
||||||
if group != nil {
|
if group != nil {
|
||||||
invite, err := group.Invite(group.GetInitialMessage())
|
invite, err := group.Invite(group.GetInitialMessage())
|
||||||
|
@ -149,7 +155,9 @@ func (cp *cwtchPeer) StartGroup(server string) (string, []byte, error) {
|
||||||
|
|
||||||
// StartGroupWithMessage create a new group linked to the given server and returns the group ID, an invite or an error.
|
// StartGroupWithMessage create a new group linked to the given server and returns the group ID, an invite or an error.
|
||||||
func (cp *cwtchPeer) StartGroupWithMessage(server string, initialMessage []byte) (groupID string, invite []byte, err error) {
|
func (cp *cwtchPeer) StartGroupWithMessage(server string, initialMessage []byte) (groupID string, invite []byte, err error) {
|
||||||
|
cp.mutex.Lock()
|
||||||
groupID, invite, err = cp.Profile.StartGroupWithMessage(server, initialMessage)
|
groupID, invite, err = cp.Profile.StartGroupWithMessage(server, initialMessage)
|
||||||
|
cp.mutex.Unlock()
|
||||||
if err == nil {
|
if err == nil {
|
||||||
group := cp.GetGroup(groupID)
|
group := cp.GetGroup(groupID)
|
||||||
jsobj, err := json.Marshal(group)
|
jsobj, err := json.Marshal(group)
|
||||||
|
@ -166,18 +174,24 @@ func (cp *cwtchPeer) StartGroupWithMessage(server string, initialMessage []byte)
|
||||||
|
|
||||||
// GetGroups returns an unordered list of all group IDs.
|
// GetGroups returns an unordered list of all group IDs.
|
||||||
func (cp *cwtchPeer) GetGroups() []string {
|
func (cp *cwtchPeer) GetGroups() []string {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
return cp.Profile.GetGroups()
|
return cp.Profile.GetGroups()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetGroup returns a pointer to a specific group, nil if no group exists.
|
// GetGroup returns a pointer to a specific group, nil if no group exists.
|
||||||
func (cp *cwtchPeer) GetGroup(groupID string) *model.Group {
|
func (cp *cwtchPeer) GetGroup(groupID string) *model.Group {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
return cp.Profile.GetGroup(groupID)
|
return cp.Profile.GetGroup(groupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *cwtchPeer) AddContact(nick, onion string, trusted bool) {
|
func (cp *cwtchPeer) AddContact(nick, onion string, trusted bool) {
|
||||||
decodedPub, _ := base32.StdEncoding.DecodeString(strings.ToUpper(onion))
|
decodedPub, _ := base32.StdEncoding.DecodeString(strings.ToUpper(onion))
|
||||||
pp := &model.PublicProfile{Name: nick, Ed25519PublicKey: decodedPub, Trusted: trusted, Blocked: false, Onion: onion, Attributes: map[string]string{"nick": nick}}
|
pp := &model.PublicProfile{Name: nick, Ed25519PublicKey: decodedPub, Trusted: trusted, Blocked: false, Onion: onion, Attributes: map[string]string{"nick": nick}}
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.AddContact(onion, pp)
|
cp.Profile.AddContact(onion, pp)
|
||||||
|
cp.mutex.Unlock()
|
||||||
pd, _ := json.Marshal(pp)
|
pd, _ := json.Marshal(pp)
|
||||||
cp.eventBus.Publish(event.NewEvent(event.PeerCreated, map[event.Field]string{
|
cp.eventBus.Publish(event.NewEvent(event.PeerCreated, map[event.Field]string{
|
||||||
event.Data: string(pd),
|
event.Data: string(pd),
|
||||||
|
@ -187,51 +201,85 @@ func (cp *cwtchPeer) AddContact(nick, onion string, trusted bool) {
|
||||||
|
|
||||||
// GetContacts returns an unordered list of onions
|
// GetContacts returns an unordered list of onions
|
||||||
func (cp *cwtchPeer) GetContacts() []string {
|
func (cp *cwtchPeer) GetContacts() []string {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
return cp.Profile.GetContacts()
|
return cp.Profile.GetContacts()
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetContact returns a given contact, nil is no such contact exists
|
// GetContact returns a given contact, nil is no such contact exists
|
||||||
func (cp *cwtchPeer) GetContact(onion string) *model.PublicProfile {
|
func (cp *cwtchPeer) GetContact(onion string) *model.PublicProfile {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
contact, _ := cp.Profile.GetContact(onion)
|
contact, _ := cp.Profile.GetContact(onion)
|
||||||
return contact
|
return contact
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetProfile returns the profile associated with this cwtchPeer.
|
func (cp *cwtchPeer) GetName() string {
|
||||||
func (cp *cwtchPeer) GetProfile() *model.Profile {
|
cp.mutex.Lock()
|
||||||
return cp.Profile
|
defer cp.mutex.Unlock()
|
||||||
|
return cp.Profile.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *cwtchPeer) GetPeerState(onion string) connections.ConnectionState {
|
func (cp *cwtchPeer) SetName(newName string) {
|
||||||
return connections.ConnectionStateToType[cp.Profile.Contacts[onion].State]
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
|
cp.Profile.Name = newName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cp *cwtchPeer) GetGroupState(groupid string) connections.ConnectionState {
|
func (cp *cwtchPeer) GetOnion() string {
|
||||||
return connections.ConnectionStateToType[cp.Profile.Groups[groupid].State]
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
|
return cp.Profile.Onion
|
||||||
|
}
|
||||||
|
func (cp *cwtchPeer) GetPeerState(onion string) (connections.ConnectionState, bool) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
|
if peer, ok := cp.Profile.Contacts[onion]; ok {
|
||||||
|
return connections.ConnectionStateToType[peer.State], true
|
||||||
|
}
|
||||||
|
return connections.DISCONNECTED, false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cp *cwtchPeer) GetGroupState(groupid string) (connections.ConnectionState, bool) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
|
if group, ok := cp.Profile.Groups[groupid]; ok {
|
||||||
|
return connections.ConnectionStateToType[group.State], true
|
||||||
|
}
|
||||||
|
return connections.DISCONNECTED, false
|
||||||
}
|
}
|
||||||
|
|
||||||
// PeerWithOnion is the entry point for cwtchPeer relationships
|
// PeerWithOnion is the entry point for cwtchPeer relationships
|
||||||
func (cp *cwtchPeer) PeerWithOnion(onion string) {
|
func (cp *cwtchPeer) PeerWithOnion(onion string) {
|
||||||
|
cp.mutex.Lock()
|
||||||
if _, exists := cp.Profile.GetContact(onion); !exists {
|
if _, exists := cp.Profile.GetContact(onion); !exists {
|
||||||
cp.AddContact(onion, onion, false)
|
cp.AddContact(onion, onion, false)
|
||||||
}
|
}
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
cp.eventBus.Publish(event.NewEvent(event.PeerRequest, map[event.Field]string{event.RemotePeer: onion}))
|
cp.eventBus.Publish(event.NewEvent(event.PeerRequest, map[event.Field]string{event.RemotePeer: onion}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteContact deletes a peer from the profile, storage, and handling
|
// DeleteContact deletes a peer from the profile, storage, and handling
|
||||||
func (cp *cwtchPeer) DeleteContact(onion string) {
|
func (cp *cwtchPeer) DeleteContact(onion string) {
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.DeleteContact(onion)
|
cp.Profile.DeleteContact(onion)
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
cp.eventBus.Publish(event.NewEventList(event.DeleteContact, event.RemotePeer, onion))
|
cp.eventBus.Publish(event.NewEventList(event.DeleteContact, event.RemotePeer, onion))
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteGroup deletes a Group from the profile, storage, and handling
|
// DeleteGroup deletes a Group from the profile, storage, and handling
|
||||||
func (cp *cwtchPeer) DeleteGroup(groupID string) {
|
func (cp *cwtchPeer) DeleteGroup(groupID string) {
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.DeleteGroup(groupID)
|
cp.Profile.DeleteGroup(groupID)
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
cp.eventBus.Publish(event.NewEventList(event.DeleteGroup, event.GroupID, groupID))
|
cp.eventBus.Publish(event.NewEventList(event.DeleteGroup, event.GroupID, groupID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InviteOnionToGroup kicks off the invite process
|
// InviteOnionToGroup kicks off the invite process
|
||||||
func (cp *cwtchPeer) InviteOnionToGroup(onion string, groupid string) error {
|
func (cp *cwtchPeer) InviteOnionToGroup(onion string, groupid string) error {
|
||||||
|
cp.mutex.Lock()
|
||||||
group := cp.Profile.GetGroup(groupid)
|
group := cp.Profile.GetGroup(groupid)
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
if group == nil {
|
if group == nil {
|
||||||
return errors.New("invalid group id")
|
return errors.New("invalid group id")
|
||||||
}
|
}
|
||||||
|
@ -258,7 +306,10 @@ func (cp *cwtchPeer) SendMessageToGroup(groupid string, message string) error {
|
||||||
// SendMessageToGroup attempts to sent the given message to the given group id.
|
// SendMessageToGroup attempts to sent the given message to the given group id.
|
||||||
// It returns the signature of the message which can be used to identify it in any UX layer.
|
// It returns the signature of the message which can be used to identify it in any UX layer.
|
||||||
func (cp *cwtchPeer) SendMessageToGroupTracked(groupid string, message string) (string, error) {
|
func (cp *cwtchPeer) SendMessageToGroupTracked(groupid string, message string) (string, error) {
|
||||||
|
cp.mutex.Lock()
|
||||||
group := cp.Profile.GetGroup(groupid)
|
group := cp.Profile.GetGroup(groupid)
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
|
|
||||||
if group == nil {
|
if group == nil {
|
||||||
return "", errors.New("invalid group id")
|
return "", errors.New("invalid group id")
|
||||||
}
|
}
|
||||||
|
@ -275,13 +326,17 @@ func (cp *cwtchPeer) SendMessageToPeer(onion string, message string) string {
|
||||||
event := event.NewEvent(event.SendMessageToPeer, map[event.Field]string{event.RemotePeer: onion, event.Data: message})
|
event := event.NewEvent(event.SendMessageToPeer, map[event.Field]string{event.RemotePeer: onion, event.Data: message})
|
||||||
cp.eventBus.Publish(event)
|
cp.eventBus.Publish(event)
|
||||||
|
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.AddSentMessageToContactTimeline(onion, message, time.Now(), event.EventID)
|
cp.Profile.AddSentMessageToContactTimeline(onion, message, time.Now(), event.EventID)
|
||||||
|
cp.mutex.Unlock()
|
||||||
|
|
||||||
return event.EventID
|
return event.EventID
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrustPeer sets an existing peer relationship to trusted
|
// TrustPeer sets an existing peer relationship to trusted
|
||||||
func (cp *cwtchPeer) TrustPeer(peer string) error {
|
func (cp *cwtchPeer) TrustPeer(peer string) error {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
err := cp.Profile.TrustPeer(peer)
|
err := cp.Profile.TrustPeer(peer)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cp.PeerWithOnion(peer)
|
cp.PeerWithOnion(peer)
|
||||||
|
@ -291,21 +346,34 @@ func (cp *cwtchPeer) TrustPeer(peer string) error {
|
||||||
|
|
||||||
// BlockPeer blocks an existing peer relationship.
|
// BlockPeer blocks an existing peer relationship.
|
||||||
func (cp *cwtchPeer) BlockPeer(peer string) error {
|
func (cp *cwtchPeer) BlockPeer(peer string) error {
|
||||||
|
cp.mutex.Lock()
|
||||||
err := cp.Profile.BlockPeer(peer)
|
err := cp.Profile.BlockPeer(peer)
|
||||||
|
cp.mutex.Unlock()
|
||||||
cp.eventBus.Publish(event.NewEvent(event.BlockPeer, map[event.Field]string{event.RemotePeer: peer}))
|
cp.eventBus.Publish(event.NewEvent(event.BlockPeer, map[event.Field]string{event.RemotePeer: peer}))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// UnblockPeer blocks an existing peer relationship.
|
// UnblockPeer blocks an existing peer relationship.
|
||||||
func (cp *cwtchPeer) UnblockPeer(peer string) error {
|
func (cp *cwtchPeer) UnblockPeer(peer string) error {
|
||||||
|
cp.mutex.Lock()
|
||||||
err := cp.Profile.UnblockPeer(peer)
|
err := cp.Profile.UnblockPeer(peer)
|
||||||
|
cp.mutex.Unlock()
|
||||||
cp.eventBus.Publish(event.NewEvent(event.UnblockPeer, map[event.Field]string{event.RemotePeer: peer}))
|
cp.eventBus.Publish(event.NewEvent(event.UnblockPeer, map[event.Field]string{event.RemotePeer: peer}))
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ProcessInvite adds a new group invite to the profile. returns the new group ID
|
||||||
|
func (cp *cwtchPeer) ProcessInvite(invite string, remotePeer string) (string, error) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
|
return cp.Profile.ProcessInvite(invite, remotePeer)
|
||||||
|
}
|
||||||
|
|
||||||
// AcceptInvite accepts a given existing group invite
|
// AcceptInvite accepts a given existing group invite
|
||||||
func (cp *cwtchPeer) AcceptInvite(groupID string) error {
|
func (cp *cwtchPeer) AcceptInvite(groupID string) error {
|
||||||
|
cp.mutex.Lock()
|
||||||
err := cp.Profile.AcceptInvite(groupID)
|
err := cp.Profile.AcceptInvite(groupID)
|
||||||
|
cp.mutex.Unlock()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -317,6 +385,8 @@ func (cp *cwtchPeer) AcceptInvite(groupID string) error {
|
||||||
|
|
||||||
// RejectInvite rejects a given group invite.
|
// RejectInvite rejects a given group invite.
|
||||||
func (cp *cwtchPeer) RejectInvite(groupID string) {
|
func (cp *cwtchPeer) RejectInvite(groupID string) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
cp.Profile.RejectInvite(groupID)
|
cp.Profile.RejectInvite(groupID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -339,17 +409,21 @@ func (cp *cwtchPeer) StartGroupConnections() {
|
||||||
for _, groupID := range cp.GetGroups() {
|
for _, groupID := range cp.GetGroups() {
|
||||||
// Only send a join server packet if we haven't joined this server yet...
|
// Only send a join server packet if we haven't joined this server yet...
|
||||||
group := cp.GetGroup(groupID)
|
group := cp.GetGroup(groupID)
|
||||||
|
cp.mutex.Lock()
|
||||||
if joined := joinedServers[groupID]; group.Accepted && !joined {
|
if joined := joinedServers[groupID]; group.Accepted && !joined {
|
||||||
log.Infof("Join Server %v (%v)\n", group.GroupServer, joined)
|
log.Infof("Join Server %v (%v)\n", group.GroupServer, joined)
|
||||||
cp.JoinServer(group.GroupServer)
|
cp.JoinServer(group.GroupServer)
|
||||||
joinedServers[group.GroupServer] = true
|
joinedServers[group.GroupServer] = true
|
||||||
}
|
}
|
||||||
|
cp.mutex.Unlock()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAttribute sets an attribute for this profile and emits an event
|
// SetAttribute sets an attribute for this profile and emits an event
|
||||||
func (cp *cwtchPeer) SetAttribute(key string, val string) {
|
func (cp *cwtchPeer) SetAttribute(key string, val string) {
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.SetAttribute(key, val)
|
cp.Profile.SetAttribute(key, val)
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
cp.eventBus.Publish(event.NewEvent(event.SetAttribute, map[event.Field]string{
|
cp.eventBus.Publish(event.NewEvent(event.SetAttribute, map[event.Field]string{
|
||||||
event.Key: key,
|
event.Key: key,
|
||||||
event.Data: val,
|
event.Data: val,
|
||||||
|
@ -358,11 +432,15 @@ func (cp *cwtchPeer) SetAttribute(key string, val string) {
|
||||||
|
|
||||||
// GetAttribute gets an attribute for the profile
|
// GetAttribute gets an attribute for the profile
|
||||||
func (cp *cwtchPeer) GetAttribute(key string) (string, bool) {
|
func (cp *cwtchPeer) GetAttribute(key string) (string, bool) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
return cp.Profile.GetAttribute(key)
|
return cp.Profile.GetAttribute(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetContactAttribute sets an attribute for the indicated contact and emits an event
|
// SetContactAttribute sets an attribute for the indicated contact and emits an event
|
||||||
func (cp *cwtchPeer) SetContactAttribute(onion string, key string, val string) {
|
func (cp *cwtchPeer) SetContactAttribute(onion string, key string, val string) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
if contact, ok := cp.Profile.GetContact(onion); ok {
|
if contact, ok := cp.Profile.GetContact(onion); ok {
|
||||||
contact.SetAttribute(key, val)
|
contact.SetAttribute(key, val)
|
||||||
cp.eventBus.Publish(event.NewEvent(event.SetPeerAttribute, map[event.Field]string{
|
cp.eventBus.Publish(event.NewEvent(event.SetPeerAttribute, map[event.Field]string{
|
||||||
|
@ -375,6 +453,8 @@ func (cp *cwtchPeer) SetContactAttribute(onion string, key string, val string) {
|
||||||
|
|
||||||
// GetContactAttribute gets an attribute for the indicated contact
|
// GetContactAttribute gets an attribute for the indicated contact
|
||||||
func (cp *cwtchPeer) GetContactAttribute(onion string, key string) (string, bool) {
|
func (cp *cwtchPeer) GetContactAttribute(onion string, key string) (string, bool) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
if contact, ok := cp.Profile.GetContact(onion); ok {
|
if contact, ok := cp.Profile.GetContact(onion); ok {
|
||||||
return contact.GetAttribute(key)
|
return contact.GetAttribute(key)
|
||||||
}
|
}
|
||||||
|
@ -383,6 +463,8 @@ func (cp *cwtchPeer) GetContactAttribute(onion string, key string) (string, bool
|
||||||
|
|
||||||
// SetGroupAttribute sets an attribute for the indicated group and emits an event
|
// SetGroupAttribute sets an attribute for the indicated group and emits an event
|
||||||
func (cp *cwtchPeer) SetGroupAttribute(gid string, key string, val string) {
|
func (cp *cwtchPeer) SetGroupAttribute(gid string, key string, val string) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
if group := cp.Profile.GetGroup(gid); group != nil {
|
if group := cp.Profile.GetGroup(gid); group != nil {
|
||||||
group.SetAttribute(key, val)
|
group.SetAttribute(key, val)
|
||||||
cp.eventBus.Publish(event.NewEvent(event.SetGroupAttribute, map[event.Field]string{
|
cp.eventBus.Publish(event.NewEvent(event.SetGroupAttribute, map[event.Field]string{
|
||||||
|
@ -395,6 +477,8 @@ func (cp *cwtchPeer) SetGroupAttribute(gid string, key string, val string) {
|
||||||
|
|
||||||
// GetGroupAttribute gets an attribute for the indicated group
|
// GetGroupAttribute gets an attribute for the indicated group
|
||||||
func (cp *cwtchPeer) GetGroupAttribute(gid string, key string) (string, bool) {
|
func (cp *cwtchPeer) GetGroupAttribute(gid string, key string) (string, bool) {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
if group := cp.Profile.GetGroup(gid); group != nil {
|
if group := cp.Profile.GetGroup(gid); group != nil {
|
||||||
return group.GetAttribute(key)
|
return group.GetAttribute(key)
|
||||||
}
|
}
|
||||||
|
@ -403,6 +487,8 @@ func (cp *cwtchPeer) GetGroupAttribute(gid string, key string) (string, bool) {
|
||||||
|
|
||||||
// Shutdown kills all connections and cleans up all goroutines for the peer
|
// Shutdown kills all connections and cleans up all goroutines for the peer
|
||||||
func (cp *cwtchPeer) Shutdown() {
|
func (cp *cwtchPeer) Shutdown() {
|
||||||
|
cp.mutex.Lock()
|
||||||
|
defer cp.mutex.Unlock()
|
||||||
cp.shutdown = true
|
cp.shutdown = true
|
||||||
cp.queue.Shutdown()
|
cp.queue.Shutdown()
|
||||||
}
|
}
|
||||||
|
@ -416,39 +502,54 @@ func (cp *cwtchPeer) eventHandler() {
|
||||||
|
|
||||||
case event.EncryptedGroupMessage:
|
case event.EncryptedGroupMessage:
|
||||||
// If successful, a side effect is the message is added to the group's timeline
|
// If successful, a side effect is the message is added to the group's timeline
|
||||||
|
cp.mutex.Lock()
|
||||||
ok, groupID, message, seen := cp.Profile.AttemptDecryption([]byte(ev.Data[event.Ciphertext]), []byte(ev.Data[event.Signature]))
|
ok, groupID, message, seen := cp.Profile.AttemptDecryption([]byte(ev.Data[event.Ciphertext]), []byte(ev.Data[event.Signature]))
|
||||||
|
cp.mutex.Unlock()
|
||||||
if ok && !seen {
|
if ok && !seen {
|
||||||
cp.eventBus.Publish(event.NewEvent(event.NewMessageFromGroup, map[event.Field]string{event.TimestampReceived: message.Received.Format(time.RFC3339Nano), event.TimestampSent: message.Timestamp.Format(time.RFC3339Nano), event.Data: message.Message, event.GroupID: groupID, event.Signature: string(message.Signature), event.PreviousSignature: string(message.PreviousMessageSig), event.RemotePeer: message.PeerID}))
|
cp.eventBus.Publish(event.NewEvent(event.NewMessageFromGroup, map[event.Field]string{event.TimestampReceived: message.Received.Format(time.RFC3339Nano), event.TimestampSent: message.Timestamp.Format(time.RFC3339Nano), event.Data: message.Message, event.GroupID: groupID, event.Signature: string(message.Signature), event.PreviousSignature: string(message.PreviousMessageSig), event.RemotePeer: message.PeerID}))
|
||||||
}
|
}
|
||||||
|
|
||||||
case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data
|
case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data
|
||||||
ts, _ := time.Parse(time.RFC3339Nano, ev.Data[event.TimestampReceived])
|
ts, _ := time.Parse(time.RFC3339Nano, ev.Data[event.TimestampReceived])
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.AddMessageToContactTimeline(ev.Data[event.RemotePeer], ev.Data[event.Data], ts)
|
cp.Profile.AddMessageToContactTimeline(ev.Data[event.RemotePeer], ev.Data[event.Data], ts)
|
||||||
|
cp.mutex.Unlock()
|
||||||
|
|
||||||
case event.PeerAcknowledgement:
|
case event.PeerAcknowledgement:
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.AckSentMessageToPeer(ev.Data[event.RemotePeer], ev.Data[event.EventID])
|
cp.Profile.AckSentMessageToPeer(ev.Data[event.RemotePeer], ev.Data[event.EventID])
|
||||||
|
cp.mutex.Unlock()
|
||||||
|
|
||||||
case event.SendMessageToGroupError:
|
case event.SendMessageToGroupError:
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.AddGroupSentMessageError(ev.Data[event.GroupServer], ev.Data[event.Signature], ev.Data[event.Error])
|
cp.Profile.AddGroupSentMessageError(ev.Data[event.GroupServer], ev.Data[event.Signature], ev.Data[event.Error])
|
||||||
|
cp.mutex.Unlock()
|
||||||
|
|
||||||
case event.SendMessageToPeerError:
|
case event.SendMessageToPeerError:
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.ErrorSentMessageToPeer(ev.Data[event.RemotePeer], ev.Data[event.EventID], ev.Data[event.Error])
|
cp.Profile.ErrorSentMessageToPeer(ev.Data[event.RemotePeer], ev.Data[event.EventID], ev.Data[event.Error])
|
||||||
|
cp.mutex.Unlock()
|
||||||
|
|
||||||
/***** Non default but requestable handlable events *****/
|
/***** Non default but requestable handlable events *****/
|
||||||
|
|
||||||
case event.NewGroupInvite:
|
case event.NewGroupInvite:
|
||||||
|
cp.mutex.Lock()
|
||||||
cp.Profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer])
|
cp.Profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer])
|
||||||
|
cp.mutex.Unlock()
|
||||||
case event.PeerStateChange:
|
case event.PeerStateChange:
|
||||||
|
cp.mutex.Lock()
|
||||||
if _, exists := cp.Profile.Contacts[ev.Data[event.RemotePeer]]; exists {
|
if _, exists := cp.Profile.Contacts[ev.Data[event.RemotePeer]]; exists {
|
||||||
cp.Profile.Contacts[ev.Data[event.RemotePeer]].State = ev.Data[event.ConnectionState]
|
cp.Profile.Contacts[ev.Data[event.RemotePeer]].State = ev.Data[event.ConnectionState]
|
||||||
}
|
}
|
||||||
|
cp.mutex.Unlock()
|
||||||
case event.ServerStateChange:
|
case event.ServerStateChange:
|
||||||
|
cp.mutex.Lock()
|
||||||
for _, group := range cp.Profile.Groups {
|
for _, group := range cp.Profile.Groups {
|
||||||
if group.GroupServer == ev.Data[event.GroupServer] {
|
if group.GroupServer == ev.Data[event.GroupServer] {
|
||||||
group.State = ev.Data[event.ConnectionState]
|
group.State = ev.Data[event.ConnectionState]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cp.mutex.Unlock()
|
||||||
default:
|
default:
|
||||||
if ev.EventType != "" {
|
if ev.EventType != "" {
|
||||||
log.Errorf("peer event handler received an event it was not subscribed for: %v", ev.EventType)
|
log.Errorf("peer event handler received an event it was not subscribed for: %v", ev.EventType)
|
||||||
|
|
|
@ -209,6 +209,7 @@ func (e *engine) Shutdown() {
|
||||||
// peerWithOnion is the entry point for cwtchPeer relationships
|
// peerWithOnion is the entry point for cwtchPeer relationships
|
||||||
// needs to be run in a goroutine as will block on Open.
|
// needs to be run in a goroutine as will block on Open.
|
||||||
func (e *engine) peerWithOnion(onion string) {
|
func (e *engine) peerWithOnion(onion string) {
|
||||||
|
log.Infof("PEER WITH ONION: %v\n", onion)
|
||||||
blocked, known := e.blocked.Load(onion)
|
blocked, known := e.blocked.Load(onion)
|
||||||
if known && !(blocked.(bool)) {
|
if known && !(blocked.(bool)) {
|
||||||
e.ignoreOnShutdown(e.peerConnecting)(onion)
|
e.ignoreOnShutdown(e.peerConnecting)(onion)
|
||||||
|
|
|
@ -2,18 +2,15 @@ package groups
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/model"
|
||||||
"cwtch.im/cwtch/peer"
|
|
||||||
"golang.org/x/crypto/nacl/secretbox"
|
"golang.org/x/crypto/nacl/secretbox"
|
||||||
"io"
|
"io"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Fuzz various group related functions
|
// Fuzz various group related functions
|
||||||
func Fuzz(data []byte) int {
|
func Fuzz(data []byte) int {
|
||||||
peer := peer.NewCwtchPeer("fuzz")
|
profile := model.GenerateNewProfile("fuzz")
|
||||||
peer.Init(event.NewEventManager())
|
inviteid, err := profile.ProcessInvite(string(data), profile.Onion)
|
||||||
|
|
||||||
inviteid, err := peer.GetProfile().ProcessInvite(string(data), peer.GetProfile().Onion)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if inviteid != "" {
|
if inviteid != "" {
|
||||||
|
@ -22,15 +19,16 @@ func Fuzz(data []byte) int {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
id, _, _ := peer.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
id, _, _ := profile.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
||||||
var nonce [24]byte
|
var nonce [24]byte
|
||||||
io.ReadFull(rand.Reader, nonce[:])
|
io.ReadFull(rand.Reader, nonce[:])
|
||||||
encrypted := secretbox.Seal(nonce[:], data, &nonce, &peer.GetGroup(id).GroupKey)
|
encrypted := secretbox.Seal(nonce[:], data, &nonce, &profile.GetGroup(id).GroupKey)
|
||||||
ok, _, _, _ := peer.GetProfile().AttemptDecryption(encrypted, data)
|
|
||||||
|
ok, _, _, _ := profile.AttemptDecryption(encrypted, data)
|
||||||
if ok {
|
if ok {
|
||||||
panic("this probably shouldn't happen")
|
panic("this probably shouldn't happen")
|
||||||
}
|
}
|
||||||
ok = peer.GetProfile().VerifyGroupMessage(string(data), string(data), string(data), 0, encrypted, data)
|
ok = profile.VerifyGroupMessage(string(data), string(data), string(data), 0, encrypted, data)
|
||||||
if ok {
|
if ok {
|
||||||
panic("this probably shouldn't happen")
|
panic("this probably shouldn't happen")
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func TestCounter(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < max; i++ {
|
for i := 0; i < max; i++ {
|
||||||
<- done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
||||||
val := c.Count()
|
val := c.Count()
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"github.com/struCoder/pidusage"
|
"github.com/struCoder/pidusage"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,8 +37,19 @@ func (mp *Monitors) Start(ra *application.RicochetApplication, configDir string,
|
||||||
mp.breakChannel = make(chan bool)
|
mp.breakChannel = make(chan bool)
|
||||||
mp.MessageCounter = NewCounter()
|
mp.MessageCounter = NewCounter()
|
||||||
mp.Messages = NewMonitorHistory(Count, Cumulative, func() (c float64) { c = float64(mp.MessageCounter.Count()); mp.MessageCounter.Reset(); return })
|
mp.Messages = NewMonitorHistory(Count, Cumulative, func() (c float64) { c = float64(mp.MessageCounter.Count()); mp.MessageCounter.Reset(); return })
|
||||||
mp.CPU = NewMonitorHistory(Percent, Average, func() float64 { sysInfo, _ := pidusage.GetStat(os.Getpid()); return float64(sysInfo.CPU) })
|
var pidUsageLock sync.Mutex
|
||||||
mp.Memory = NewMonitorHistory(MegaBytes, Average, func() float64 { sysInfo, _ := pidusage.GetStat(os.Getpid()); return float64(sysInfo.Memory) })
|
mp.CPU = NewMonitorHistory(Percent, Average, func() float64 {
|
||||||
|
pidUsageLock.Lock()
|
||||||
|
defer pidUsageLock.Unlock()
|
||||||
|
sysInfo, _ := pidusage.GetStat(os.Getpid())
|
||||||
|
return float64(sysInfo.CPU)
|
||||||
|
})
|
||||||
|
mp.Memory = NewMonitorHistory(MegaBytes, Average, func() float64 {
|
||||||
|
pidUsageLock.Lock()
|
||||||
|
defer pidUsageLock.Unlock()
|
||||||
|
sysInfo, _ := pidusage.GetStat(os.Getpid())
|
||||||
|
return float64(sysInfo.Memory)
|
||||||
|
})
|
||||||
mp.ClientConns = NewMonitorHistory(Count, Average, func() float64 { return float64(ra.ConnectionCount()) })
|
mp.ClientConns = NewMonitorHistory(Count, Average, func() float64 { return float64(ra.ConnectionCount()) })
|
||||||
|
|
||||||
if mp.log {
|
if mp.log {
|
||||||
|
|
|
@ -2,7 +2,6 @@ package testing
|
||||||
|
|
||||||
import (
|
import (
|
||||||
app2 "cwtch.im/cwtch/app"
|
app2 "cwtch.im/cwtch/app"
|
||||||
"cwtch.im/cwtch/app/plugins"
|
|
||||||
"cwtch.im/cwtch/app/utils"
|
"cwtch.im/cwtch/app/utils"
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/event/bridge"
|
"cwtch.im/cwtch/event/bridge"
|
||||||
|
@ -15,6 +14,8 @@ import (
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
"golang.org/x/net/proxy"
|
"golang.org/x/net/proxy"
|
||||||
"os"
|
"os"
|
||||||
|
"os/user"
|
||||||
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
"runtime/pprof"
|
"runtime/pprof"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -61,45 +62,43 @@ func serverCheck(t *testing.T, serverAddr string) bool {
|
||||||
|
|
||||||
func waitForPeerGroupConnection(t *testing.T, peer peer.CwtchPeer, groupID string) {
|
func waitForPeerGroupConnection(t *testing.T, peer peer.CwtchPeer, groupID string) {
|
||||||
for {
|
for {
|
||||||
_, ok := peer.GetProfile().Groups[groupID]
|
fmt.Printf("%v checking group conection...\n", peer.GetName())
|
||||||
|
state, ok := peer.GetGroupState(groupID)
|
||||||
if ok {
|
if ok {
|
||||||
state := peer.GetGroupState(groupID)
|
fmt.Printf("Waiting for Peer %v to join group %v - state: %v\n", peer.GetName(), groupID, state)
|
||||||
//log.Infof("Waiting for Peer %v to join group %v - state: %v\n", peer.GetProfile().Name, groupID, state)
|
|
||||||
if state == connections.FAILED {
|
if state == connections.FAILED {
|
||||||
t.Fatalf("%v could not connect to %v", peer.GetProfile().Onion, groupID)
|
t.Fatalf("%v could not connect to %v", peer.GetOnion(), groupID)
|
||||||
}
|
}
|
||||||
if state != connections.SYNCED {
|
if state != connections.SYNCED {
|
||||||
fmt.Printf("peer %v waiting connect to group %v, currently: %v\n", peer.GetProfile().Onion, groupID, connections.ConnectionStateName[state])
|
fmt.Printf("peer %v %v waiting connect to group %v, currently: %v\n", peer.GetName(), peer.GetOnion(), groupID, connections.ConnectionStateName[state])
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 5)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
|
fmt.Printf("peer %v %v CONNECTED to group %v\n", peer.GetName(), peer.GetOnion(), groupID)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} // It might take a second for the server to show up as it is now going through the event bus
|
}
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForPeerPeerConnection(t *testing.T, peera peer.CwtchPeer, peerb peer.CwtchPeer) {
|
func waitForPeerPeerConnection(t *testing.T, peera peer.CwtchPeer, peerb peer.CwtchPeer) {
|
||||||
for {
|
for {
|
||||||
//peers := peera.GetPeers()
|
state, ok := peera.GetPeerState(peerb.GetOnion())
|
||||||
_, ok := peera.GetProfile().Contacts[peerb.GetProfile().Onion]
|
|
||||||
if ok {
|
if ok {
|
||||||
state := peera.GetPeerState(peerb.GetProfile().Onion)
|
|
||||||
//log.Infof("Waiting for Peer %v to peer with peer: %v - state: %v\n", peera.GetProfile().Name, peerb.GetProfile().Name, state)
|
//log.Infof("Waiting for Peer %v to peer with peer: %v - state: %v\n", peera.GetProfile().Name, peerb.GetProfile().Name, state)
|
||||||
if state == connections.FAILED {
|
if state == connections.FAILED {
|
||||||
t.Fatalf("%v could not connect to %v", peera.GetProfile().Onion, peerb.GetProfile().Onion)
|
t.Fatalf("%v could not connect to %v", peera.GetOnion(), peerb.GetOnion())
|
||||||
}
|
}
|
||||||
if state != connections.AUTHENTICATED {
|
if state != connections.AUTHENTICATED {
|
||||||
fmt.Printf("peer% v waiting connect to peer %v, currently: %v\n", peera.GetProfile().Onion, peerb.GetProfile().Onion, connections.ConnectionStateName[state])
|
fmt.Printf("peer %v waiting connect to peer %v, currently: %v\n", peera.GetOnion(), peerb.GetOnion(), connections.ConnectionStateName[state])
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 5)
|
||||||
continue
|
continue
|
||||||
} else {
|
} else {
|
||||||
|
fmt.Printf("%v CONNECTED and AUTHED to %v\n", peera.GetName(), peerb.GetName())
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} // It might take a second for the peer to show up as it is now going through the event bus
|
}
|
||||||
time.Sleep(time.Second)
|
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -113,6 +112,8 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
log.ExcludeFromPattern("outbound/3dhauthchannel")
|
log.ExcludeFromPattern("outbound/3dhauthchannel")
|
||||||
log.ExcludeFromPattern("event/eventmanager")
|
log.ExcludeFromPattern("event/eventmanager")
|
||||||
log.ExcludeFromPattern("pipeBridge")
|
log.ExcludeFromPattern("pipeBridge")
|
||||||
|
log.ExcludeFromPattern("tapir")
|
||||||
|
os.RemoveAll("tor")
|
||||||
acn, 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)
|
||||||
|
@ -145,8 +146,13 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
|
|
||||||
app := app2.NewApp(acn, "./storage")
|
app := app2.NewApp(acn, "./storage")
|
||||||
|
|
||||||
bridgeClient := bridge.NewPipeBridgeClient("./clientPipe", "./servicePipe")
|
usr, _ := user.Current()
|
||||||
bridgeService := bridge.NewPipeBridgeService("./servicePipe", "./clientPipe")
|
cwtchDir := path.Join(usr.HomeDir, ".cwtch")
|
||||||
|
os.Mkdir(cwtchDir, 0700)
|
||||||
|
os.RemoveAll(path.Join(cwtchDir, "testing"))
|
||||||
|
os.Mkdir(path.Join(cwtchDir, "testing"), 0700)
|
||||||
|
bridgeClient := bridge.NewPipeBridgeClient(path.Join(cwtchDir, "testing/clientPipe"), path.Join(cwtchDir, "testing/servicePipe"))
|
||||||
|
bridgeService := bridge.NewPipeBridgeService(path.Join(cwtchDir, "testing/servicePipe"), path.Join(cwtchDir, "testing/clientPipe"))
|
||||||
appClient := app2.NewAppClient("./storage", bridgeClient)
|
appClient := app2.NewAppClient("./storage", bridgeClient)
|
||||||
appService := app2.NewAppService(acn, "./storage", bridgeService)
|
appService := app2.NewAppService(acn, "./storage", bridgeService)
|
||||||
|
|
||||||
|
@ -164,27 +170,37 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
appClient.CreatePeer("carol", "asdfasdf")
|
appClient.CreatePeer("carol", "asdfasdf")
|
||||||
|
|
||||||
alice := utils.WaitGetPeer(app, "alice")
|
alice := utils.WaitGetPeer(app, "alice")
|
||||||
app.AddPeerPlugin(alice.GetProfile().Onion, plugins.NETWORKCHECK)
|
fmt.Println("Alice created:", alice.GetOnion())
|
||||||
fmt.Println("Alice created:", alice.GetProfile().Onion)
|
|
||||||
alice.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
alice.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
||||||
|
|
||||||
bob := utils.WaitGetPeer(app, "bob")
|
bob := utils.WaitGetPeer(app, "bob")
|
||||||
fmt.Println("Bob created:", bob.GetProfile().Onion)
|
fmt.Println("Bob created:", bob.GetOnion())
|
||||||
bob.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
bob.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
||||||
|
|
||||||
carol := utils.WaitGetPeer(appClient, "carol")
|
carol := utils.WaitGetPeer(appClient, "carol")
|
||||||
fmt.Println("Carol created:", carol.GetProfile().Onion)
|
fmt.Println("Carol created:", carol.GetOnion())
|
||||||
carol.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
carol.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
||||||
|
|
||||||
app.LaunchPeers()
|
app.LaunchPeers()
|
||||||
appClient.LaunchPeers()
|
appClient.LaunchPeers()
|
||||||
|
|
||||||
fmt.Println("Waiting for Alice, Bob, and Carol to connect with onion network...")
|
fmt.Println("Waiting for Alice, Bob, and Carol to connect with onion network...")
|
||||||
time.Sleep(time.Second * 90)
|
time.Sleep(time.Second * 60)
|
||||||
numGoRoutinesPostPeerStart := runtime.NumGoroutine()
|
numGoRoutinesPostPeerStart := runtime.NumGoroutine()
|
||||||
|
|
||||||
// ***** Peering, server joining, group creation / invite *****
|
// ***** Peering, server joining, group creation / invite *****
|
||||||
|
|
||||||
|
fmt.Println("Alice joining server...")
|
||||||
|
alice.JoinServer(serverAddr)
|
||||||
|
|
||||||
|
fmt.Println("Alice peering with Bob...")
|
||||||
|
alice.AddContact("Bob", bob.GetOnion(), false) // Add contact so we can track connection state
|
||||||
|
alice.PeerWithOnion(bob.GetOnion())
|
||||||
|
|
||||||
|
fmt.Println("Alice peering with Carol...")
|
||||||
|
alice.AddContact("Carol", carol.GetOnion(), false)
|
||||||
|
alice.PeerWithOnion(carol.GetOnion())
|
||||||
|
|
||||||
fmt.Println("Creating group on ", serverAddr, "...")
|
fmt.Println("Creating group on ", serverAddr, "...")
|
||||||
groupID, _, err := alice.StartGroup(serverAddr)
|
groupID, _, err := alice.StartGroup(serverAddr)
|
||||||
fmt.Printf("Created group: %v!\n", groupID)
|
fmt.Printf("Created group: %v!\n", groupID)
|
||||||
|
@ -193,37 +209,19 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Alice peering with Bob...")
|
|
||||||
alice.AddContact("Bob", bob.GetProfile().Onion, false) // Add contact so we can track connection state
|
|
||||||
alice.PeerWithOnion(bob.GetProfile().Onion)
|
|
||||||
fmt.Println("Alice peering with Carol...")
|
|
||||||
alice.AddContact("Carol", carol.GetProfile().Onion, false)
|
|
||||||
alice.PeerWithOnion(carol.GetProfile().Onion)
|
|
||||||
|
|
||||||
fmt.Println("Alice joining server...")
|
|
||||||
alice.JoinServer(serverAddr)
|
|
||||||
fmt.Println("Bob joining server...")
|
|
||||||
bob.JoinServer(serverAddr)
|
|
||||||
|
|
||||||
fmt.Println("Waiting for alice to join server...")
|
fmt.Println("Waiting for alice to join server...")
|
||||||
waitForPeerGroupConnection(t, alice, groupID)
|
waitForPeerGroupConnection(t, alice, groupID)
|
||||||
|
|
||||||
//fmt.Println("Waiting for bob to join server...")
|
|
||||||
//waitForPeerGroupConnection(t, bob, groupID)
|
|
||||||
|
|
||||||
fmt.Println("Waiting for alice and Bob to peer...")
|
fmt.Println("Waiting for alice and Bob to peer...")
|
||||||
waitForPeerPeerConnection(t, alice, bob)
|
waitForPeerPeerConnection(t, alice, bob)
|
||||||
|
|
||||||
/*fmt.Println("Waiting for peerings and server joins...")
|
|
||||||
time.Sleep(time.Second * 240)*/
|
|
||||||
|
|
||||||
fmt.Println("Alice inviting Bob to group...")
|
fmt.Println("Alice inviting Bob to group...")
|
||||||
err = alice.InviteOnionToGroup(bob.GetProfile().Onion, groupID)
|
err = alice.InviteOnionToGroup(bob.GetOnion(), groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error for Alice inviting Bob to group: %v", err)
|
t.Fatalf("Error for Alice inviting Bob to group: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(time.Second * 10)
|
time.Sleep(time.Second * 5)
|
||||||
|
|
||||||
fmt.Println("Bob examining groups and accepting invites...")
|
fmt.Println("Bob examining groups and accepting invites...")
|
||||||
for _, groupID := range bob.GetGroups() {
|
for _, groupID := range bob.GetGroups() {
|
||||||
|
@ -234,15 +232,9 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
bob.AcceptInvite(group.GroupID)
|
bob.AcceptInvite(group.GroupID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 5)
|
|
||||||
|
|
||||||
numGoRoutinesPostServerConnect := runtime.NumGoroutine()
|
numGoRoutinesPostServerConnect := runtime.NumGoroutine()
|
||||||
|
|
||||||
// Wait for them to join the server
|
|
||||||
waitForPeerGroupConnection(t, alice, groupID)
|
|
||||||
waitForPeerGroupConnection(t, bob, groupID)
|
|
||||||
//numGouRoutinesPostServerConnect := runtime.NumGoroutine()
|
|
||||||
|
|
||||||
// ***** Conversation *****
|
// ***** Conversation *****
|
||||||
|
|
||||||
fmt.Println("Starting conversation in group...")
|
fmt.Println("Starting conversation in group...")
|
||||||
|
@ -270,7 +262,7 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
time.Sleep(time.Second * 10)
|
time.Sleep(time.Second * 10)
|
||||||
|
|
||||||
fmt.Println("Alice inviting Carol to group...")
|
fmt.Println("Alice inviting Carol to group...")
|
||||||
err = alice.InviteOnionToGroup(carol.GetProfile().Onion, groupID)
|
err = alice.InviteOnionToGroup(carol.GetOnion(), groupID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error for Alice inviting Carol to group: %v", err)
|
t.Fatalf("Error for Alice inviting Carol to group: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -286,7 +278,7 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Shutting down Alice...")
|
fmt.Println("Shutting down Alice...")
|
||||||
app.ShutdownPeer(alice.GetProfile().Onion)
|
app.ShutdownPeer(alice.GetOnion())
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 5)
|
||||||
numGoRoutinesPostAlice := runtime.NumGoroutine()
|
numGoRoutinesPostAlice := runtime.NumGoroutine()
|
||||||
|
|
||||||
|
@ -374,7 +366,7 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("Shutting down Bob...")
|
fmt.Println("Shutting down Bob...")
|
||||||
app.ShutdownPeer(bob.GetProfile().Onion)
|
app.ShutdownPeer(bob.GetOnion())
|
||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
numGoRoutinesPostBob := runtime.NumGoroutine()
|
numGoRoutinesPostBob := runtime.NumGoroutine()
|
||||||
if server != nil {
|
if server != nil {
|
||||||
|
@ -385,7 +377,7 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
numGoRoutinesPostServerShutdown := runtime.NumGoroutine()
|
numGoRoutinesPostServerShutdown := runtime.NumGoroutine()
|
||||||
|
|
||||||
fmt.Println("Shutting down Carol...")
|
fmt.Println("Shutting down Carol...")
|
||||||
appClient.ShutdownPeer(carol.GetProfile().Onion)
|
appClient.ShutdownPeer(carol.GetOnion())
|
||||||
time.Sleep(time.Second * 3)
|
time.Sleep(time.Second * 3)
|
||||||
numGoRoutinesPostCarol := runtime.NumGoroutine()
|
numGoRoutinesPostCarol := runtime.NumGoroutine()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue