package peer import ( "encoding/json" "git.mascherari.press/cwtch/model" "git.mascherari.press/cwtch/peer/connections" "git.mascherari.press/cwtch/peer/peer" "git.mascherari.press/cwtch/protocol" "github.com/s-rah/go-ricochet/application" "github.com/s-rah/go-ricochet/channels" "github.com/s-rah/go-ricochet/connection" "io/ioutil" "sync" ) /** PeerConnectionPool Background thread running Process() Pointer to connections Move CwtchPeerChannel under peer/ Write tests for Peer Channel */ type CwtchPeerInstance struct { rai *application.ApplicationInstance ra *application.RicochetApplication } func (cpi *CwtchPeerInstance) Init(rai *application.ApplicationInstance, ra *application.RicochetApplication) { cpi.rai = rai cpi.ra = ra } type CwtchPeer struct { connection.AutoConnectionHandler Profile *model.Profile PendingContacts []string PendingInvites map[string][]string mutex sync.Mutex Log chan string `json:"-"` peerconnections map[string]*connections.PeerPeerConnection serverconnections map[string]*connections.PeerServerConnection } func NewCwtchPeer(name string) *CwtchPeer { cp := new(CwtchPeer) cp.Profile = model.GenerateNewProfile(name) cp.PendingInvites = make(map[string][]string) cp.Log = make(chan string) cp.peerconnections = make(map[string]*connections.PeerPeerConnection) cp.serverconnections = make(map[string]*connections.PeerServerConnection) cp.Init() return cp } func (cp *CwtchPeer) Save(profilefile string) error { cp.mutex.Lock() bytes, _ := json.Marshal(cp) err := ioutil.WriteFile(profilefile, bytes, 0600) cp.mutex.Unlock() return err } func LoadCwtchPeer(profilefile string) (*CwtchPeer, error) { bytes, _ := ioutil.ReadFile(profilefile) cp := new(CwtchPeer) err := json.Unmarshal(bytes, &cp) return cp, err } // AddContactRequest is the entry point for CwtchPeer relationships func (cp *CwtchPeer) AddContactRequest(onion string) { cp.mutex.Lock() cp.PendingContacts = append(cp.PendingContacts, onion) go cp.EstablishContact(onion) cp.mutex.Unlock() } // InviteOnionToGroup kicks off the invite process func (cp *CwtchPeer) InviteOnionToGroup(onion string, groupid string) { cp.mutex.Lock() cp.PendingInvites[onion] = append(cp.PendingInvites[onion], groupid) cp.mutex.Unlock() } func (cp *CwtchPeer) JoinServer(onion string) { } func (cp *CwtchPeer) SendMessageToGroup(groupid string, message string) { // Lookup Group // Lookup Sever Connection // If no server connection, spin off server connection // Else group.EncryptMessage(message) and send result to server } func (cp *CwtchPeer) Listen() error { cwtchpeer := new(application.RicochetApplication) l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", cp.Profile.OnionPrivateKey, 9878) if err != nil { return err } af := application.ApplicationInstanceFactory{} af.Init() af.AddHandler("im.cwtch.peer", func(rai *application.ApplicationInstance) func() channels.Handler { cpi := new(CwtchPeerInstance) cpi.Init(rai, cwtchpeer) return func() channels.Handler { cpc := new(peer.CwtchPeerChannel) cpc.Handler = &CwtchPeerHandler{Onion: rai.RemoteHostname, Peer: cp} return cpc } }) cwtchpeer.Init(cp.Profile.OnionPrivateKey, af, new(application.AcceptAllContactManager)) cp.Log <- "Running cwtch peer on " + l.Addr().String() cwtchpeer.Run(l) return nil } func (cp *CwtchPeer) EstablishContact(onion string) { } type CwtchPeerHandler struct { Onion string Peer *CwtchPeer } func (cph *CwtchPeerHandler) ClientIdentity(ci *protocol.CwtchIdentity) { cph.Peer.Log <- "Received Client Identity from " + cph.Onion + " " + ci.String() cph.Peer.Profile.AddCwtchIdentity(cph.Onion, ci) } func (cph *CwtchPeerHandler) HandleGroupInvite(gci *protocol.GroupChatInvite) { cph.Peer.Profile.ProcessInvite(gci) } func (cph *CwtchPeerHandler) HandleGroupMessage(gm *protocol.GroupMessage) { }