mirror of
https://github.com/yggdrasil-network/yggdrasil-go.git
synced 2025-08-24 16:05:07 +03:00
Add NodeInfo field to PeerEntry and PeerInfo structures, and update related handlers to include NodeInfo in peer data retrieval and handshake processes.
This commit is contained in:
parent
c0a9bc802a
commit
1f8f36860f
4 changed files with 63 additions and 3 deletions
|
@ -33,6 +33,7 @@ type PeerEntry struct {
|
||||||
Latency time.Duration `json:"latency,omitempty"`
|
Latency time.Duration `json:"latency,omitempty"`
|
||||||
LastErrorTime time.Duration `json:"last_error_time,omitempty"`
|
LastErrorTime time.Duration `json:"last_error_time,omitempty"`
|
||||||
LastError string `json:"last_error,omitempty"`
|
LastError string `json:"last_error,omitempty"`
|
||||||
|
NodeInfo string `json:"nodeinfo,omitempty"` // NodeInfo from peer handshake
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) error {
|
func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse) error {
|
||||||
|
@ -64,6 +65,11 @@ func (a *AdminSocket) getPeersHandler(_ *GetPeersRequest, res *GetPeersResponse)
|
||||||
peer.LastErrorTime = time.Since(p.LastErrorTime)
|
peer.LastErrorTime = time.Since(p.LastErrorTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Add NodeInfo if available
|
||||||
|
if len(p.NodeInfo) > 0 {
|
||||||
|
peer.NodeInfo = string(p.NodeInfo)
|
||||||
|
}
|
||||||
|
|
||||||
res.Peers = append(res.Peers, peer)
|
res.Peers = append(res.Peers, peer)
|
||||||
}
|
}
|
||||||
slices.SortStableFunc(res.Peers, func(a, b PeerEntry) int {
|
slices.SortStableFunc(res.Peers, func(a, b PeerEntry) int {
|
||||||
|
|
|
@ -37,6 +37,7 @@ type PeerInfo struct {
|
||||||
TXRate uint64
|
TXRate uint64
|
||||||
Uptime time.Duration
|
Uptime time.Duration
|
||||||
Latency time.Duration
|
Latency time.Duration
|
||||||
|
NodeInfo []byte // NodeInfo received during handshake
|
||||||
}
|
}
|
||||||
|
|
||||||
type TreeEntryInfo struct {
|
type TreeEntryInfo struct {
|
||||||
|
@ -92,6 +93,11 @@ func (c *Core) GetPeers() []PeerInfo {
|
||||||
peerinfo.RXRate = atomic.LoadUint64(&c.rxrate)
|
peerinfo.RXRate = atomic.LoadUint64(&c.rxrate)
|
||||||
peerinfo.TXRate = atomic.LoadUint64(&c.txrate)
|
peerinfo.TXRate = atomic.LoadUint64(&c.txrate)
|
||||||
peerinfo.Uptime = time.Since(c.up)
|
peerinfo.Uptime = time.Since(c.up)
|
||||||
|
// Add NodeInfo from handshake
|
||||||
|
if len(state._nodeInfo) > 0 {
|
||||||
|
peerinfo.NodeInfo = make([]byte, len(state._nodeInfo))
|
||||||
|
copy(peerinfo.NodeInfo, state._nodeInfo)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if p, ok := conns[conn]; ok {
|
if p, ok := conns[conn]; ok {
|
||||||
peerinfo.Key = p.Key
|
peerinfo.Key = p.Key
|
||||||
|
|
|
@ -64,9 +64,10 @@ type link struct {
|
||||||
linkType linkType // Type of link, i.e. outbound/inbound, persistent/ephemeral
|
linkType linkType // Type of link, i.e. outbound/inbound, persistent/ephemeral
|
||||||
linkProto string // Protocol carrier of link, e.g. TCP, AWDL
|
linkProto string // Protocol carrier of link, e.g. TCP, AWDL
|
||||||
// The remaining fields can only be modified safely from within the links actor
|
// The remaining fields can only be modified safely from within the links actor
|
||||||
_conn *linkConn // Connected link, if any, nil if not connected
|
_conn *linkConn // Connected link, if any, nil if not connected
|
||||||
_err error // Last error on the connection, if any
|
_err error // Last error on the connection, if any
|
||||||
_errtime time.Time // Last time an error occurred
|
_errtime time.Time // Last time an error occurred
|
||||||
|
_nodeInfo []byte // NodeInfo received from peer during handshake
|
||||||
}
|
}
|
||||||
|
|
||||||
type linkOptions struct {
|
type linkOptions struct {
|
||||||
|
@ -246,6 +247,7 @@ func (l *links) add(u *url.URL, sintf string, linkType linkType) error {
|
||||||
linkType: linkType,
|
linkType: linkType,
|
||||||
linkProto: strings.ToUpper(u.Scheme),
|
linkProto: strings.ToUpper(u.Scheme),
|
||||||
kick: make(chan struct{}),
|
kick: make(chan struct{}),
|
||||||
|
_nodeInfo: nil, // Initialize NodeInfo field
|
||||||
}
|
}
|
||||||
state.ctx, state.cancel = context.WithCancel(l.core.ctx)
|
state.ctx, state.cancel = context.WithCancel(l.core.ctx)
|
||||||
|
|
||||||
|
@ -524,6 +526,7 @@ func (l *links) listen(u *url.URL, sintf string, local bool) (*Listener, error)
|
||||||
linkType: linkTypeIncoming,
|
linkType: linkTypeIncoming,
|
||||||
linkProto: strings.ToUpper(u.Scheme),
|
linkProto: strings.ToUpper(u.Scheme),
|
||||||
kick: make(chan struct{}),
|
kick: make(chan struct{}),
|
||||||
|
_nodeInfo: nil, // Initialize NodeInfo field
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if state._conn != nil {
|
if state._conn != nil {
|
||||||
|
@ -605,6 +608,16 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, s
|
||||||
meta := version_getBaseMetadata()
|
meta := version_getBaseMetadata()
|
||||||
meta.publicKey = l.core.public
|
meta.publicKey = l.core.public
|
||||||
meta.priority = options.priority
|
meta.priority = options.priority
|
||||||
|
|
||||||
|
// Add our NodeInfo to handshake if available
|
||||||
|
phony.Block(&l.core.proto.nodeinfo, func() {
|
||||||
|
nodeInfo := l.core.proto.nodeinfo._getNodeInfo()
|
||||||
|
if len(nodeInfo) > 0 {
|
||||||
|
meta.nodeInfo = make([]byte, len(nodeInfo))
|
||||||
|
copy(meta.nodeInfo, nodeInfo)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
metaBytes, err := meta.encode(l.core.secret, options.password)
|
metaBytes, err := meta.encode(l.core.secret, options.password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to generate handshake: %w", err)
|
return fmt.Errorf("failed to generate handshake: %w", err)
|
||||||
|
@ -661,6 +674,20 @@ func (l *links) handler(linkType linkType, options linkOptions, conn net.Conn, s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store the received NodeInfo in the link state
|
||||||
|
if len(meta.nodeInfo) > 0 {
|
||||||
|
phony.Block(l, func() {
|
||||||
|
// Find the link state for this connection
|
||||||
|
for _, state := range l._links {
|
||||||
|
if state._conn != nil && state._conn.Conn == conn {
|
||||||
|
state._nodeInfo = make([]byte, len(meta.nodeInfo))
|
||||||
|
copy(state._nodeInfo, meta.nodeInfo)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
dir := "outbound"
|
dir := "outbound"
|
||||||
if linkType == linkTypeIncoming {
|
if linkType == linkTypeIncoming {
|
||||||
dir = "inbound"
|
dir = "inbound"
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/ed25519"
|
"crypto/ed25519"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"golang.org/x/crypto/blake2b"
|
"golang.org/x/crypto/blake2b"
|
||||||
|
@ -21,6 +22,7 @@ type version_metadata struct {
|
||||||
minorVer uint16
|
minorVer uint16
|
||||||
publicKey ed25519.PublicKey
|
publicKey ed25519.PublicKey
|
||||||
priority uint8
|
priority uint8
|
||||||
|
nodeInfo []byte // NodeInfo data from configuration
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -35,6 +37,7 @@ const (
|
||||||
metaVersionMinor // uint16
|
metaVersionMinor // uint16
|
||||||
metaPublicKey // [32]byte
|
metaPublicKey // [32]byte
|
||||||
metaPriority // uint8
|
metaPriority // uint8
|
||||||
|
metaNodeInfo // []byte
|
||||||
)
|
)
|
||||||
|
|
||||||
type handshakeError string
|
type handshakeError string
|
||||||
|
@ -52,6 +55,7 @@ func version_getBaseMetadata() version_metadata {
|
||||||
return version_metadata{
|
return version_metadata{
|
||||||
majorVer: ProtocolVersionMajor,
|
majorVer: ProtocolVersionMajor,
|
||||||
minorVer: ProtocolVersionMinor,
|
minorVer: ProtocolVersionMinor,
|
||||||
|
nodeInfo: nil, // Will be set during handshake
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +81,16 @@ func (m *version_metadata) encode(privateKey ed25519.PrivateKey, password []byte
|
||||||
bs = binary.BigEndian.AppendUint16(bs, 1)
|
bs = binary.BigEndian.AppendUint16(bs, 1)
|
||||||
bs = append(bs, m.priority)
|
bs = append(bs, m.priority)
|
||||||
|
|
||||||
|
// Add NodeInfo if available (with size validation)
|
||||||
|
if len(m.nodeInfo) > 0 {
|
||||||
|
if len(m.nodeInfo) > 16384 {
|
||||||
|
return nil, fmt.Errorf("NodeInfo exceeds max length of 16384 bytes")
|
||||||
|
}
|
||||||
|
bs = binary.BigEndian.AppendUint16(bs, metaNodeInfo)
|
||||||
|
bs = binary.BigEndian.AppendUint16(bs, uint16(len(m.nodeInfo)))
|
||||||
|
bs = append(bs, m.nodeInfo...)
|
||||||
|
}
|
||||||
|
|
||||||
hasher, err := blake2b.New512(password)
|
hasher, err := blake2b.New512(password)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -135,6 +149,13 @@ func (m *version_metadata) decode(r io.Reader, password []byte) error {
|
||||||
|
|
||||||
case metaPriority:
|
case metaPriority:
|
||||||
m.priority = bs[0]
|
m.priority = bs[0]
|
||||||
|
|
||||||
|
case metaNodeInfo:
|
||||||
|
if oplen > 16384 {
|
||||||
|
return fmt.Errorf("received NodeInfo exceeds max length of 16384 bytes")
|
||||||
|
}
|
||||||
|
m.nodeInfo = make([]byte, oplen)
|
||||||
|
copy(m.nodeInfo, bs[:oplen])
|
||||||
}
|
}
|
||||||
bs = bs[oplen:]
|
bs = bs[oplen:]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue