forked from cwtch.im/cwtch
104 lines
3.2 KiB
Go
104 lines
3.2 KiB
Go
package fetch
|
|
|
|
import (
|
|
"cwtch.im/cwtch/protocol"
|
|
"errors"
|
|
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
|
|
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
|
"git.openprivacy.ca/openprivacy/libricochet-go/wire/control"
|
|
"github.com/golang/protobuf/proto"
|
|
)
|
|
|
|
// CwtchPeerFetchChannel is the peer implementation of the im.cwtch.server.fetch
|
|
// channel.
|
|
type CwtchPeerFetchChannel struct {
|
|
channel *channels.Channel
|
|
Handler CwtchPeerFetchChannelHandler
|
|
}
|
|
|
|
// CwtchPeerFetchChannelHandler should be implemented by peers to receive new messages.
|
|
type CwtchPeerFetchChannelHandler interface {
|
|
HandleGroupMessage(*protocol.GroupMessage)
|
|
}
|
|
|
|
// Type returns the type string for this channel, e.g. "im.ricochet.server.fetch)
|
|
func (cpfc *CwtchPeerFetchChannel) Type() string {
|
|
return "im.cwtch.server.fetch"
|
|
}
|
|
|
|
// Closed is called when the channel is closed for any reason.
|
|
func (cpfc *CwtchPeerFetchChannel) Closed(err error) {
|
|
|
|
}
|
|
|
|
// OnlyClientCanOpen - for Cwtch server channels only client can open
|
|
func (cpfc *CwtchPeerFetchChannel) OnlyClientCanOpen() bool {
|
|
return true
|
|
}
|
|
|
|
// Singleton - for Cwtch channels there can only be one instance per direction
|
|
func (cpfc *CwtchPeerFetchChannel) Singleton() bool {
|
|
return true
|
|
}
|
|
|
|
// Bidirectional - for Cwtch channels are not bidrectional
|
|
func (cpfc *CwtchPeerFetchChannel) Bidirectional() bool {
|
|
return false
|
|
}
|
|
|
|
// RequiresAuthentication - Cwtch server channels require no auth.
|
|
func (cpfc *CwtchPeerFetchChannel) RequiresAuthentication() string {
|
|
return "none"
|
|
}
|
|
|
|
// OpenInbound - cwtch server peer implementations shouldnever respond to inbound requests
|
|
func (cpfc *CwtchPeerFetchChannel) OpenInbound(channel *channels.Channel, raw *Protocol_Data_Control.OpenChannel) ([]byte, error) {
|
|
return nil, errors.New("client does not receive inbound listen channels")
|
|
}
|
|
|
|
// OpenOutbound sets up a new cwtch fetch channel
|
|
func (cpfc *CwtchPeerFetchChannel) OpenOutbound(channel *channels.Channel) ([]byte, error) {
|
|
cpfc.channel = channel
|
|
messageBuilder := new(utils.MessageBuilder)
|
|
return messageBuilder.OpenChannel(channel.ID, cpfc.Type()), nil
|
|
}
|
|
|
|
// OpenOutboundResult confirms a previous open channel request
|
|
func (cpfc *CwtchPeerFetchChannel) OpenOutboundResult(err error, crm *Protocol_Data_Control.ChannelResult) {
|
|
if err == nil {
|
|
if crm.GetOpened() {
|
|
cpfc.channel.Pending = false
|
|
cpfc.FetchRequest()
|
|
}
|
|
}
|
|
}
|
|
|
|
// FetchRequest sends a FetchMessage to the Server.
|
|
func (cpfc *CwtchPeerFetchChannel) FetchRequest() error {
|
|
if cpfc.channel.Pending == false {
|
|
fm := &protocol.FetchMessage{}
|
|
csp := &protocol.CwtchServerPacket{
|
|
FetchMessage: fm,
|
|
}
|
|
packet, _ := proto.Marshal(csp)
|
|
cpfc.channel.SendMessage(packet)
|
|
} else {
|
|
return errors.New("channel isn't set up yet")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Packet is called for each raw packet received on this channel.
|
|
func (cpfc *CwtchPeerFetchChannel) Packet(data []byte) {
|
|
csp := &protocol.CwtchServerPacket{}
|
|
err := proto.Unmarshal(data, csp)
|
|
if err == nil {
|
|
if csp.GetGroupMessage() != nil {
|
|
gm := csp.GetGroupMessage()
|
|
// We create a new go routine here to avoid leaking any information about processing time
|
|
// TODO Server can probably try to use this to DoS a peer
|
|
go cpfc.Handler.HandleGroupMessage(gm)
|
|
}
|
|
}
|
|
}
|