Official cwtch.im peer and server implementations. https://cwtch.im
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
3.6KB

  1. package peer
  2. import (
  3. "cwtch.im/cwtch/protocol"
  4. "git.openprivacy.ca/openprivacy/libricochet-go/channels"
  5. "git.openprivacy.ca/openprivacy/libricochet-go/utils"
  6. "git.openprivacy.ca/openprivacy/libricochet-go/wire/control"
  7. "github.com/golang/protobuf/proto"
  8. "log"
  9. )
  10. // CwtchPeerChannel implements the ChannelHandler interface for a channel of
  11. // type "im.ricochet.Cwtch". The channel may be inbound or outbound.
  12. //
  13. // CwtchPeerChannel implements protocol-level sanity and state validation, but
  14. // does not handle or acknowledge Cwtch messages. The application must provide
  15. // a CwtchPeerChannelHandler implementation to handle Cwtch events.
  16. type CwtchPeerChannel struct {
  17. // Methods of Handler are called for Cwtch events on this channel
  18. Handler CwtchPeerChannelHandler
  19. channel *channels.Channel
  20. }
  21. // CwtchPeerChannelHandler is implemented by an application type to receive
  22. // events from a CwtchPeerChannel.
  23. type CwtchPeerChannelHandler interface {
  24. HandleGroupInvite(*protocol.GroupChatInvite)
  25. }
  26. // SendMessage sends a raw message on this channel
  27. func (cpc *CwtchPeerChannel) SendMessage(data []byte) {
  28. cpc.channel.SendMessage(data)
  29. }
  30. // Type returns the type string for this channel, e.g. "im.ricochet.Cwtch".
  31. func (cpc *CwtchPeerChannel) Type() string {
  32. return "im.cwtch.peer"
  33. }
  34. // Closed is called when the channel is closed for any reason.
  35. func (cpc *CwtchPeerChannel) Closed(err error) {
  36. }
  37. // OnlyClientCanOpen - for Cwtch channels any side can open
  38. func (cpc *CwtchPeerChannel) OnlyClientCanOpen() bool {
  39. return false
  40. }
  41. // Singleton - for Cwtch channels there can only be one instance per direction
  42. func (cpc *CwtchPeerChannel) Singleton() bool {
  43. return true
  44. }
  45. // Bidirectional - for Cwtch channels are not bidrectional
  46. func (cpc *CwtchPeerChannel) Bidirectional() bool {
  47. return false
  48. }
  49. // RequiresAuthentication - Cwtch channels require hidden service auth
  50. func (cpc *CwtchPeerChannel) RequiresAuthentication() string {
  51. return "im.ricochet.auth.3dh"
  52. }
  53. // OpenInbound is the first method called for an inbound channel request.
  54. // If an error is returned, the channel is rejected. If a RawMessage is
  55. // returned, it will be sent as the ChannelResult message.
  56. func (cpc *CwtchPeerChannel) OpenInbound(channel *channels.Channel, raw *Protocol_Data_Control.OpenChannel) ([]byte, error) {
  57. cpc.channel = channel
  58. messageBuilder := new(utils.MessageBuilder)
  59. return messageBuilder.AckOpenChannel(channel.ID), nil
  60. }
  61. // OpenOutbound is the first method called for an outbound channel request.
  62. // If an error is returned, the channel is not opened. If a RawMessage is
  63. // returned, it will be sent as the OpenChannel message.
  64. func (cpc *CwtchPeerChannel) OpenOutbound(channel *channels.Channel) ([]byte, error) {
  65. cpc.channel = channel
  66. messageBuilder := new(utils.MessageBuilder)
  67. return messageBuilder.OpenChannel(channel.ID, cpc.Type()), nil
  68. }
  69. // OpenOutboundResult is called when a response is received for an
  70. // outbound OpenChannel request. If `err` is non-nil, the channel was
  71. // rejected and Closed will be called immediately afterwards. `raw`
  72. // contains the raw protocol message including any extension data.
  73. func (cpc *CwtchPeerChannel) OpenOutboundResult(err error, crm *Protocol_Data_Control.ChannelResult) {
  74. if err == nil {
  75. if crm.GetOpened() {
  76. cpc.channel.Pending = false
  77. }
  78. }
  79. }
  80. // Packet is called for each raw packet received on this channel.
  81. func (cpc *CwtchPeerChannel) Packet(data []byte) {
  82. cpp := &protocol.CwtchPeerPacket{}
  83. err := proto.Unmarshal(data, cpp)
  84. if err == nil {
  85. if cpp.GetGroupChatInvite() != nil {
  86. cpc.Handler.HandleGroupInvite(cpp.GetGroupChatInvite())
  87. }
  88. } else {
  89. log.Printf("Error Receivng Packet %v\n", err)
  90. }
  91. }