libs5-go/protocol/handshake_open.go

127 lines
2.4 KiB
Go

package protocol
import (
"errors"
"fmt"
"git.lumeweb.com/LumeWeb/libs5-go/interfaces"
"git.lumeweb.com/LumeWeb/libs5-go/net"
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
"git.lumeweb.com/LumeWeb/libs5-go/protocol/signed"
"git.lumeweb.com/LumeWeb/libs5-go/types"
"github.com/vmihailenco/msgpack/v5"
)
var _ base.IncomingMessageTyped = (*HandshakeOpen)(nil)
type HandshakeOpen struct {
challenge []byte
networkId string
handshake []byte
base.IncomingMessageTypedImpl
base.IncomingMessageHandler
}
func (h *HandshakeOpen) SetHandshake(handshake []byte) {
h.handshake = handshake
}
func (h HandshakeOpen) Challenge() []byte {
return h.challenge
}
func (h HandshakeOpen) NetworkId() string {
return h.networkId
}
var _ base.EncodeableMessage = (*HandshakeOpen)(nil)
var (
errInvalidChallenge = errors.New("Invalid challenge")
)
func NewHandshakeOpen(challenge []byte, networkId string) *HandshakeOpen {
ho := &HandshakeOpen{
challenge: challenge,
networkId: networkId,
}
ho.SetRequiresHandshake(false)
return ho
}
func (h HandshakeOpen) EncodeMsgpack(enc *msgpack.Encoder) error {
err := enc.EncodeUint(uint64(types.ProtocolMethodHandshakeOpen))
if err != nil {
return err
}
err = enc.EncodeBytes(h.challenge)
if err != nil {
return err
}
if h.networkId != "" {
err = enc.EncodeString(h.networkId)
if err != nil {
return err
}
}
return nil
}
func (h *HandshakeOpen) DecodeMessage(dec *msgpack.Decoder) error {
handshake, err := dec.DecodeBytes()
if err != nil {
return err
}
h.handshake = handshake
_, err = dec.PeekCode()
networkId := ""
if err != nil {
if err.Error() != "EOF" {
return err
}
h.networkId = networkId
return nil
}
networkId, err = dec.DecodeString()
if err != nil {
return err
}
h.networkId = networkId
return nil
}
func (h *HandshakeOpen) HandleMessage(node interfaces.Node, peer net.Peer, verifyId bool) error {
if h.networkId != node.NetworkId() {
return fmt.Errorf("Peer is in different network: %s", h.networkId)
}
handshake := signed.NewHandshakeDoneRequest(h.handshake, types.SupportedFeatures, node.Services().P2P().SelfConnectionUris())
message, err := msgpack.Marshal(handshake)
if err != nil {
return err
}
secureMessage, err := node.Services().P2P().SignMessageSimple(message)
if err != nil {
return err
}
err = peer.SendMessage(secureMessage)
if err != nil {
return err
}
return nil
}