162 lines
3.3 KiB
Go
162 lines
3.3 KiB
Go
package protocol
|
|
|
|
import (
|
|
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/net"
|
|
"git.lumeweb.com/LumeWeb/libs5-go/types"
|
|
"github.com/vmihailenco/msgpack/v5"
|
|
"net/url"
|
|
)
|
|
|
|
var (
|
|
_ IncomingMessageSigned = (*AnnouncePeers)(nil)
|
|
)
|
|
|
|
type AnnouncePeers struct {
|
|
peer net.Peer
|
|
connectionUris []*url.URL
|
|
peersToSend []net.Peer
|
|
HandshakeRequirement
|
|
}
|
|
|
|
func (a *AnnouncePeers) PeersToSend() []net.Peer {
|
|
return a.peersToSend
|
|
}
|
|
|
|
func (a *AnnouncePeers) SetPeersToSend(peersToSend []net.Peer) {
|
|
a.peersToSend = peersToSend
|
|
}
|
|
|
|
func NewAnnounceRequest(peer net.Peer, peersToSend []net.Peer) *AnnouncePeers {
|
|
return &AnnouncePeers{peer: peer, connectionUris: nil, peersToSend: peersToSend}
|
|
}
|
|
|
|
func NewAnnouncePeers() *AnnouncePeers {
|
|
ap := &AnnouncePeers{peer: nil, connectionUris: nil}
|
|
|
|
ap.SetRequiresHandshake(false)
|
|
|
|
return ap
|
|
}
|
|
|
|
func (a *AnnouncePeers) DecodeMessage(dec *msgpack.Decoder, message IncomingMessageDataSigned) error {
|
|
// CIDFromString the number of peers.
|
|
numPeers, err := dec.DecodeInt()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Initialize the slice for storing connection URIs.
|
|
var connectionURIs []*url.URL
|
|
|
|
// Loop through each peer.
|
|
for i := 0; i < numPeers; i++ {
|
|
// CIDFromString peer ID.
|
|
peerIdBytes, err := dec.DecodeBytes()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
peerId := encoding.NewNodeId(peerIdBytes)
|
|
|
|
// Skip decoding connection status as it is not used.
|
|
_, err = dec.DecodeBool() // Connection status, not used.
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// CIDFromString the number of connection URIs for this peer.
|
|
numUris, err := dec.DecodeInt()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// CIDFromString each connection URI for this peer.
|
|
for j := 0; j < numUris; j++ {
|
|
uriStr, err := dec.DecodeString()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
uri, err := url.Parse(uriStr)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
pid, err := peerId.ToString()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
passwd, empty := uri.User.Password()
|
|
if empty {
|
|
passwd = ""
|
|
}
|
|
|
|
// Incorporate the peer ID into the URI.
|
|
uri.User = url.UserPassword(pid, passwd)
|
|
|
|
connectionURIs = append(connectionURIs, uri)
|
|
}
|
|
}
|
|
|
|
a.connectionUris = connectionURIs
|
|
|
|
return nil
|
|
}
|
|
|
|
func (a AnnouncePeers) HandleMessage(message IncomingMessageDataSigned) error {
|
|
mediator := message.Mediator
|
|
peer := message.Peer
|
|
if len(a.connectionUris) > 0 {
|
|
err := mediator.ConnectToNode([]*url.URL{a.connectionUris[0]}, false, peer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (a AnnouncePeers) EncodeMsgpack(enc *msgpack.Encoder) error {
|
|
err := enc.EncodeUint(uint64(types.ProtocolMethodAnnouncePeers))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Encode the number of peers.
|
|
err = enc.EncodeInt(int64(len(a.peersToSend)))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Loop through each peer.
|
|
for _, peer := range a.peersToSend {
|
|
err = enc.EncodeBytes(peer.Id().Raw())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Encode connection status.
|
|
err = enc.EncodeBool(peer.IsConnected())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Encode the number of connection URIs for this peer.
|
|
err = enc.EncodeInt(int64(len(peer.ConnectionURIs())))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// Encode each connection URI for this peer.
|
|
for _, uri := range peer.ConnectionURIs() {
|
|
err = enc.EncodeString(uri.String())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|