Adding peer channels, renaming client->peer

This commit is contained in:
Sarah Jamie Lewis 2018-03-11 11:49:10 -07:00
parent fbf42b3a79
commit 335a8d76c3
17 changed files with 301 additions and 9 deletions

View File

@ -1,4 +1,4 @@
package client
package peer
import (
"crypto/rand"

View File

@ -0,0 +1,42 @@
package connections
import (
//"git.mascherari.press/cwtch/peer/peer"
//"git.mascherari.press/cwtch/protocol"
"github.com/s-rah/go-ricochet"
//"github.com/s-rah/go-ricochet/channels"
"github.com/s-rah/go-ricochet/connection"
//"github.com/s-rah/go-ricochet/identity"
//"github.com/s-rah/go-ricochet/utils"
//"time"
)
type PeerPeerConnection struct {
connection.AutoConnectionHandler
PeerHostname string
state ConnectionState
connection connection.Connection
}
func NewPeerPeerConnection(peerhostname string) *PeerPeerConnection {
ppc := new(PeerPeerConnection)
ppc.PeerHostname = peerhostname
ppc.Init()
return ppc
}
// GetState returns the current connection state
func (ppc *PeerPeerConnection) GetState() ConnectionState {
return ppc.state
}
// Run manages the setup and teardown of a peer->peer connection
func (ppc *PeerPeerConnection) Run() error {
rc, err := goricochet.Open(ppc.PeerHostname)
if err == nil {
rc.TraceLog(true)
ppc.connection = *rc
ppc.state = CONNECTED
}
return err
}

View File

@ -0,0 +1,51 @@
package connections
import (
"crypto/rsa"
"github.com/s-rah/go-ricochet"
"github.com/s-rah/go-ricochet/connection"
"github.com/s-rah/go-ricochet/identity"
"github.com/s-rah/go-ricochet/utils"
"net"
"testing"
"time"
)
func PeerAuthValid(hostname string, publicKey rsa.PublicKey) (allowed, known bool) {
return true, true
}
func runtestserver(t *testing.T) {
ln, _ := net.Listen("tcp", "127.0.0.1:5452")
conn, _ := ln.Accept()
defer conn.Close()
privateKey, err := utils.LoadPrivateKeyFromFile("../../testing/private_key")
if err != nil {
t.Errorf("Private Key Error %v", err)
}
rc, err := goricochet.NegotiateVersionInbound(conn)
if err != nil {
t.Errorf("Negotiate Version Error: %v", err)
}
rc.TraceLog(true)
err = connection.HandleInboundConnection(rc).ProcessAuthAsServer(identity.Initialize("", privateKey), PeerAuthValid)
if err != nil {
t.Errorf("ServerAuth Error: %v", err)
}
}
func TestPeerPeerConnection(t *testing.T) {
ppc := NewPeerPeerConnection("127.0.0.1:5452|kwke2hntvyfqm7dr")
//numcalls := 0
go runtestserver(t)
state := ppc.GetState()
if state != DISCONNECTED {
t.Errorf("new connections should start in disconnected state")
}
go ppc.Run()
time.Sleep(time.Second * 1)
state = ppc.GetState()
if state != CONNECTED {
t.Errorf("connection state should be connected, was instead %v", state)
}
}

View File

@ -1,8 +1,8 @@
package connections
import (
"git.mascherari.press/cwtch/client/fetch"
"git.mascherari.press/cwtch/client/send"
"git.mascherari.press/cwtch/peer/fetch"
"git.mascherari.press/cwtch/peer/send"
"git.mascherari.press/cwtch/protocol"
"github.com/s-rah/go-ricochet"
"github.com/s-rah/go-ricochet/channels"

View File

@ -1,4 +1,4 @@
package client
package peer
import (
"encoding/json"
@ -14,10 +14,6 @@ import (
)
/**
ServerConnectionPool
background thread running Process()
pointer to connection
Probably worthwhile defining a type called PeerServerConnection to manage background() and other commmands!
PeerConnectionPool
Background thread running Process()

View File

@ -1,4 +1,4 @@
package client
package peer
import (
"testing"

104
peer/peer/peer_channel.go Normal file
View File

@ -0,0 +1,104 @@
package peer
import (
"git.mascherari.press/cwtch/protocol"
"github.com/golang/protobuf/proto"
"github.com/s-rah/go-ricochet/channels"
"github.com/s-rah/go-ricochet/utils"
"github.com/s-rah/go-ricochet/wire/control"
)
// CwtchPeerChannel implements the ChannelHandler interface for a channel of
// type "im.ricochet.Cwtch". The channel may be inbound or outbound.
//
// CwtchPeerChannel implements protocol-level sanity and state validation, but
// does not handle or acknowledge Cwtch messages. The application must provide
// a CwtchPeerChannelHandler implementation to handle Cwtch events.
type CwtchPeerChannel struct {
// Methods of Handler are called for Cwtch events on this channel
Handler CwtchPeerChannelHandler
channel *channels.Channel
}
// CwtchPeerChannelHandler is implemented by an application type to receive
// events from a CwtchPeerChannel.
type CwtchPeerChannelHandler interface {
ClientIdentity(*protocol.CwtchIdentity)
HandleGroupInvite()
}
// Type returns the type string for this channel, e.g. "im.ricochet.Cwtch".
func (cpc *CwtchPeerChannel) SendMessage(data []byte) {
cpc.channel.SendMessage(data)
}
// Type returns the type string for this channel, e.g. "im.ricochet.Cwtch".
func (cpc *CwtchPeerChannel) Type() string {
return "im.cwtch.peer"
}
// Closed is called when the channel is closed for any reason.
func (cpc *CwtchPeerChannel) Closed(err error) {
}
// OnlyClientCanOpen - for Cwtch channels any side can open
func (cpc *CwtchPeerChannel) OnlyClientCanOpen() bool {
return false
}
// Singleton - for Cwtch channels there can only be one instance per direction
func (cpc *CwtchPeerChannel) Singleton() bool {
return true
}
// Bidirectional - for Cwtch channels are not bidrectional
func (cpc *CwtchPeerChannel) Bidirectional() bool {
return false
}
// RequiresAuthentication - Cwtch channels require hidden service auth
func (cpc *CwtchPeerChannel) RequiresAuthentication() string {
return "im.ricochet.auth.hidden-service"
}
// OpenInbound is the first method called for an inbound channel request.
// If an error is returned, the channel is rejected. If a RawMessage is
// returned, it will be sent as the ChannelResult message.
func (cpc *CwtchPeerChannel) OpenInbound(channel *channels.Channel, raw *Protocol_Data_Control.OpenChannel) ([]byte, error) {
cpc.channel = channel
messageBuilder := new(utils.MessageBuilder)
return messageBuilder.AckOpenChannel(channel.ID), nil
}
// OpenOutbound is the first method called for an outbound channel request.
// If an error is returned, the channel is not opened. If a RawMessage is
// returned, it will be sent as the OpenChannel message.
func (cpc *CwtchPeerChannel) OpenOutbound(channel *channels.Channel) ([]byte, error) {
cpc.channel = channel
messageBuilder := new(utils.MessageBuilder)
return messageBuilder.OpenChannel(channel.ID, cpc.Type()), nil
}
// OpenOutboundResult is called when a response is received for an
// outbound OpenChannel request. If `err` is non-nil, the channel was
// rejected and Closed will be called immediately afterwards. `raw`
// contains the raw protocol message including any extension data.
func (cpc *CwtchPeerChannel) OpenOutboundResult(err error, crm *Protocol_Data_Control.ChannelResult) {
if err == nil {
if crm.GetOpened() {
cpc.channel.Pending = false
}
}
}
// Packet is called for each raw packet received on this channel.
func (cpc *CwtchPeerChannel) Packet(data []byte) {
cpp := &protocol.CwtchPeerPacket{}
err := proto.Unmarshal(data, cpp)
if err == nil {
if cpp.GetCwtchIdentify() != nil {
cpc.Handler.ClientIdentity(cpp.GetCwtchIdentify())
}
}
}

View File

@ -0,0 +1,99 @@
package peer
import (
"git.mascherari.press/cwtch/protocol"
"github.com/golang/protobuf/proto"
"github.com/s-rah/go-ricochet/channels"
"github.com/s-rah/go-ricochet/wire/control"
"testing"
)
func TestPeerChannelAttributes(t *testing.T) {
cssc := new(CwtchPeerChannel)
if cssc.Type() != "im.cwtch.peer" {
t.Errorf("cwtch channel type is incorrect %v", cssc.Type())
}
if cssc.OnlyClientCanOpen() {
t.Errorf("either side should be able to open im.cwtch.peer channel")
}
if cssc.Bidirectional() {
t.Errorf("im.cwtch.peer should not be bidirectional")
}
if !cssc.Singleton() {
t.Errorf("im.cwtch.server.listen should be a Singleton")
}
if cssc.RequiresAuthentication() != "im.ricochet.auth.hidden-service" {
t.Errorf("cwtch channel required auth is incorrect %v", cssc.RequiresAuthentication())
}
}
type TestHandler struct {
Received bool
}
func (th *TestHandler) ClientIdentity(ci *protocol.CwtchIdentity) {
if ci.GetName() == "hello" {
th.Received = true
}
}
func (th *TestHandler) HandleGroupInvite() {
}
func TestPeerChannel(t *testing.T) {
th := new(TestHandler)
cpc := new(CwtchPeerChannel)
cpc.Handler = th
channel := new(channels.Channel)
channel.ID = 3
result, err := cpc.OpenOutbound(channel)
if err != nil {
t.Errorf("should have send open channel request instead %v, %v", result, err)
}
cpc2 := new(CwtchPeerChannel)
channel2 := new(channels.Channel)
channel2.ID = 3
sent := false
channel2.SendMessage = func(message []byte) {
sent = true
}
control := new(Protocol_Data_Control.Packet)
proto.Unmarshal(result[:], control)
ack, err := cpc2.OpenInbound(channel2, control.GetOpenChannel())
if err != nil {
t.Errorf("should have ack open channel request instead %v, %v", ack, err)
}
ackpacket := new(Protocol_Data_Control.Packet)
proto.Unmarshal(ack[:], ackpacket)
cpc.OpenOutboundResult(nil, ackpacket.GetChannelResult())
if channel.Pending != false {
t.Errorf("Channel should no longer be pending")
}
gm := &protocol.CwtchIdentity{
Name: "hello",
Ed25519PublicKey: []byte{},
}
cpp := &protocol.CwtchPeerPacket{
CwtchIdentify: gm,
}
packet, _ := proto.Marshal(cpp)
cpc.Packet(packet)
if th.Received == false {
t.Errorf("Should have sent packet to handler")
}
cpc2.SendMessage(packet)
if sent == false {
t.Errorf("Should have sent packet to channel")
}
}