160 lines
3.1 KiB
Go
160 lines
3.1 KiB
Go
package signed
|
|
|
|
import (
|
|
"bytes"
|
|
"errors"
|
|
"fmt"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/protocol/base"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/utils"
|
|
"github.com/vmihailenco/msgpack/v5"
|
|
"net/url"
|
|
)
|
|
|
|
var _ IncomingMessageSigned = (*HandshakeDone)(nil)
|
|
var _ base.EncodeableMessage = (*HandshakeDone)(nil)
|
|
|
|
type HandshakeDone struct {
|
|
challenge []byte
|
|
networkId string
|
|
supportedFeatures int
|
|
connectionUris []*url.URL
|
|
handshake []byte
|
|
base.HandshakeRequirement
|
|
}
|
|
|
|
func NewHandshakeDoneRequest(handshake []byte, supportedFeatures int, connectionUris []*url.URL) *HandshakeDone {
|
|
ho := &HandshakeDone{
|
|
handshake: handshake,
|
|
supportedFeatures: supportedFeatures,
|
|
connectionUris: connectionUris,
|
|
}
|
|
|
|
ho.SetRequiresHandshake(false)
|
|
|
|
return ho
|
|
}
|
|
|
|
func (m HandshakeDone) EncodeMsgpack(enc *msgpack.Encoder) error {
|
|
err := enc.EncodeUint(uint64(types.ProtocolMethodHandshakeDone))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = enc.EncodeBytes(m.handshake)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = enc.EncodeInt(int64(m.supportedFeatures))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = utils.EncodeMsgpackArray(enc, m.connectionUris)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *HandshakeDone) SetChallenge(challenge []byte) {
|
|
m.challenge = challenge
|
|
}
|
|
|
|
func (m *HandshakeDone) SetNetworkId(networkId string) {
|
|
m.networkId = networkId
|
|
}
|
|
|
|
func NewHandshakeDone() *HandshakeDone {
|
|
hn := &HandshakeDone{challenge: nil, networkId: "", supportedFeatures: -1}
|
|
|
|
hn.SetRequiresHandshake(false)
|
|
|
|
return hn
|
|
}
|
|
|
|
func (h HandshakeDone) HandleMessage(message IncomingMessageDataSigned) error {
|
|
services := message.Services
|
|
peer := message.Peer
|
|
verifyId := message.VerifyId
|
|
nodeId := message.NodeId
|
|
logger := message.Logger
|
|
|
|
if !services.IsStarted() {
|
|
err := peer.End()
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
return nil
|
|
}
|
|
|
|
if !bytes.Equal(peer.Challenge(), h.challenge) {
|
|
return errors.New("Invalid challenge")
|
|
}
|
|
|
|
if !verifyId {
|
|
peer.SetId(nodeId)
|
|
} else {
|
|
if !peer.Id().Equals(nodeId) {
|
|
return fmt.Errorf("Invalid transports id on initial list")
|
|
}
|
|
}
|
|
|
|
peer.SetConnected(true)
|
|
peer.SetHandshakeDone(true)
|
|
|
|
if h.supportedFeatures != types.SupportedFeatures {
|
|
return fmt.Errorf("Remote node does not support required features")
|
|
}
|
|
err := services.P2P().AddPeer(peer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
peer.SetConnectionURIs(h.connectionUris)
|
|
|
|
peerId, err := peer.Id().ToString()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
logger.Info(fmt.Sprintf("[+] %s (%s)", peerId, peer.RenderLocationURI()))
|
|
|
|
err = services.P2P().SendPublicPeersToPeer(peer, []net.Peer{peer})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (h *HandshakeDone) DecodeMessage(dec *msgpack.Decoder, message IncomingMessageDataSigned) error {
|
|
challenge, err := dec.DecodeBytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
h.challenge = challenge
|
|
|
|
supportedFeatures, err := dec.DecodeInt()
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
h.supportedFeatures = supportedFeatures
|
|
|
|
connectionUris, err := utils.DecodeMsgpackURLArray(dec)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
h.connectionUris = connectionUris
|
|
return nil
|
|
}
|