libs5-go/protocol/signed/announce_peers.go

162 lines
3.4 KiB
Go

package signed
import (
"git.lumeweb.com/LumeWeb/libs5-go/encoding"
"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/types"
"github.com/vmihailenco/msgpack/v5"
"net/url"
)
var (
_ base.IncomingMessageTyped = (*AnnouncePeers)(nil)
)
type AnnouncePeers struct {
peer net.Peer
connectionUris []*url.URL
peersToSend []net.Peer
base.IncomingMessageTypedImpl
}
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) 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(node interfaces.Node, peer net.Peer, verifyId bool) error {
if len(a.connectionUris) > 0 {
err := node.Services().P2P().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
}