Adding peer channels, renaming client->peer
This commit is contained in:
parent
fbf42b3a79
commit
335a8d76c3
|
@ -1,4 +1,4 @@
|
|||
package client
|
||||
package peer
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
|
@ -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"
|
|
@ -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()
|
|
@ -1,4 +1,4 @@
|
|||
package client
|
||||
package peer
|
||||
|
||||
import (
|
||||
"testing"
|
|
@ -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())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue