cwtch/peer/connections/peerpeerconnection.go

111 lines
3.2 KiB
Go
Raw Normal View History

package connections
import (
2018-06-29 19:20:07 +00:00
"cwtch.im/cwtch/model"
2018-05-28 18:05:06 +00:00
"cwtch.im/cwtch/peer/peer"
"cwtch.im/cwtch/protocol"
2018-06-23 16:15:36 +00:00
"git.openprivacy.ca/openprivacy/libricochet-go"
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
"git.openprivacy.ca/openprivacy/libricochet-go/connection"
"git.openprivacy.ca/openprivacy/libricochet-go/identity"
2018-05-01 21:36:03 +00:00
"log"
2018-03-14 22:23:35 +00:00
"time"
)
// PeerPeerConnection encapsulates a single outgoing Peer->Peer connection
type PeerPeerConnection struct {
connection.AutoConnectionHandler
PeerHostname string
state ConnectionState
2018-05-20 18:29:46 +00:00
connection *connection.Connection
2018-03-14 22:23:35 +00:00
profile *model.Profile
}
// NewPeerPeerConnection creates a new peer connection for the given hostname and profile.
2018-03-11 19:05:35 +00:00
func NewPeerPeerConnection(peerhostname string, profile *model.Profile) *PeerPeerConnection {
ppc := new(PeerPeerConnection)
ppc.PeerHostname = peerhostname
2018-03-11 19:05:35 +00:00
ppc.profile = profile
ppc.Init()
return ppc
}
// GetState returns the current connection state
func (ppc *PeerPeerConnection) GetState() ConnectionState {
return ppc.state
}
// ClientIdentity passes the given CwtchIdentity packet to the profile.
2018-03-11 19:05:35 +00:00
func (ppc *PeerPeerConnection) ClientIdentity(ci *protocol.CwtchIdentity) {
2018-03-14 22:23:35 +00:00
ppc.profile.AddCwtchIdentity(ppc.PeerHostname, ci)
2018-03-11 19:05:35 +00:00
}
// HandleGroupInvite passes the given group invite tothe profile
2018-03-12 18:43:51 +00:00
func (ppc *PeerPeerConnection) HandleGroupInvite(gci *protocol.GroupChatInvite) {
ppc.profile.ProcessInvite(gci, ppc.PeerHostname)
2018-03-12 18:43:51 +00:00
}
// GetClientIdentityPacket returns nil to avoid peers constantly sending identity packets to eachother.
func (ppc *PeerPeerConnection) GetClientIdentityPacket() []byte {
return nil
}
// SendGroupInvite sends the given serialized invite packet to the Peer
2018-03-12 18:43:51 +00:00
func (ppc *PeerPeerConnection) SendGroupInvite(invite []byte) {
2018-03-14 22:23:35 +00:00
ppc.connection.Do(func() error {
channel := ppc.connection.Channel("im.cwtch.peer", channels.Outbound)
if channel != nil {
peerchannel, ok := channel.Handler.(*peer.CwtchPeerChannel)
if ok {
2018-05-01 21:36:03 +00:00
log.Printf("Sending group invite packet\n")
2018-03-14 22:23:35 +00:00
peerchannel.SendMessage(invite)
}
}
return nil
})
2018-03-11 19:05:35 +00:00
}
// Run manages the setup and teardown of a peer->peer connection
func (ppc *PeerPeerConnection) Run() error {
ppc.state = CONNECTING
rc, err := goricochet.Open(ppc.PeerHostname)
if err == nil {
rc.TraceLog(false)
2018-05-20 18:29:46 +00:00
ppc.connection = rc
ppc.state = CONNECTED
2018-05-20 18:29:46 +00:00
_, err := connection.HandleOutboundConnection(ppc.connection).ProcessAuthAsClient(identity.Initialize(ppc.profile.Name, ppc.profile.OnionPrivateKey))
2018-03-11 19:05:35 +00:00
if err == nil {
ppc.state = AUTHENTICATED
go func() {
ppc.connection.Do(func() error {
ppc.connection.RequestOpenChannel("im.cwtch.peer", &peer.CwtchPeerChannel{Handler: ppc})
return nil
})
2018-03-14 22:23:35 +00:00
time.Sleep(time.Second * 1)
ppc.connection.Do(func() error {
channel := ppc.connection.Channel("im.cwtch.peer", channels.Outbound)
if channel != nil {
peerchannel, ok := channel.Handler.(*peer.CwtchPeerChannel)
if ok {
peerchannel.SendMessage(ppc.profile.GetCwtchIdentityPacket())
}
}
return nil
})
2018-03-11 19:05:35 +00:00
}()
ppc.connection.Process(ppc)
}
}
ppc.state = FAILED
return err
}
// Close closes the connection
func (ppc *PeerPeerConnection) Close() {
ppc.state = KILLED
ppc.connection.Conn.Close()
}