Discovery Neo Oclib
This commit is contained in:
@@ -39,6 +39,8 @@ type PeerRecordPayload struct {
|
||||
PubKey []byte `json:"public_key"`
|
||||
ExpiryDate time.Time `json:"expiry_date"`
|
||||
IsNano bool `json:"is_nano"`
|
||||
// MasterID is the libp2p PeerID of this peer's MASTER, self-attested and signed.
|
||||
MasterID string `json:"master_id,omitempty"`
|
||||
// TTLSeconds is the publisher's declared lifetime for this record in seconds.
|
||||
// 0 means "use the default (120 s)". Included in the signed payload so it
|
||||
// cannot be altered by an intermediary.
|
||||
@@ -105,6 +107,7 @@ func (pr *PeerRecord) ExtractPeer(ourkey string, key string, pubKey crypto.PubKe
|
||||
NATSAddress: pr.NATSAddress,
|
||||
WalletAddress: pr.WalletAddress,
|
||||
Location: pr.Location,
|
||||
MasterID: pr.MasterID,
|
||||
}
|
||||
if time.Now().UTC().After(pr.ExpiryDate) {
|
||||
return pp.SELF == p.Relation, nil, errors.New("peer " + key + " is offline")
|
||||
@@ -285,6 +288,20 @@ func (ix *IndexerService) initNodeHandler() {
|
||||
}
|
||||
cancel2()
|
||||
}
|
||||
// PendingContact: update inverted index — for each target peer in the list,
|
||||
// record that hb.PeerID wants to contact it. Entries expire after 3 heartbeat
|
||||
// intervals so stale callers are cleaned up automatically if they stop advertising.
|
||||
if len(hb.PendingContact) > 0 {
|
||||
expiry := time.Now().Add(3 * 20 * time.Second)
|
||||
ix.pendingContactIndexMu.Lock()
|
||||
for _, targetID := range hb.PendingContact {
|
||||
if ix.pendingContactIndex[targetID] == nil {
|
||||
ix.pendingContactIndex[targetID] = map[string]time.Time{}
|
||||
}
|
||||
ix.pendingContactIndex[targetID][hb.PeerID] = expiry
|
||||
}
|
||||
ix.pendingContactIndexMu.Unlock()
|
||||
}
|
||||
}
|
||||
ix.Host.SetStreamHandler(common.ProtocolHeartbeat, ix.HandleHeartbeat)
|
||||
ix.Host.SetStreamHandler(common.ProtocolPublish, ix.handleNodePublish)
|
||||
@@ -351,7 +368,8 @@ func (ix *IndexerService) handleNodePublish(s network.Stream) {
|
||||
}
|
||||
continue
|
||||
}
|
||||
if _, err := rec.Verify(); err != nil {
|
||||
pubKey, err := rec.Verify()
|
||||
if err != nil {
|
||||
ix.behavior.RecordBadSignature(remotePeer)
|
||||
logger.Warn().Err(err).Str("peer", remotePeer.String()).Msg("bad signature on publish")
|
||||
return
|
||||
@@ -369,6 +387,26 @@ func (ix *IndexerService) handleNodePublish(s network.Stream) {
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// Chain of trust: PubKey → PeerID (libp2p invariant), then transport identity.
|
||||
// This prevents a peer from publishing a record on behalf of someone else.
|
||||
if derivedID, err := lpp.IDFromPublicKey(pubKey); err != nil || derivedID != pid {
|
||||
ix.behavior.RecordBadSignature(remotePeer)
|
||||
logger.Warn().Str("peer", remotePeer.String()).Msg("PubKey/PeerID mismatch on publish")
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
if remotePeer != pid {
|
||||
ix.behavior.RecordBadSignature(remotePeer)
|
||||
logger.Warn().Str("remote", remotePeer.String()).Str("claimed", pid.String()).Msg("transport identity mismatch on publish")
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
if rec.StreamAddress != "" && !strings.HasSuffix(rec.StreamAddress, "/p2p/"+rec.PeerID) {
|
||||
ix.behavior.RecordBadSignature(remotePeer)
|
||||
logger.Warn().Str("peer", remotePeer.String()).Msg("StreamAddress/PeerID mismatch on publish")
|
||||
s.Reset()
|
||||
return
|
||||
}
|
||||
|
||||
ix.StreamMU.Lock()
|
||||
defer ix.StreamMU.Unlock()
|
||||
@@ -566,7 +604,7 @@ func (ix *IndexerService) handleIndirectProbe(s network.Stream) {
|
||||
// Connect to target if not already connected.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 6*time.Second)
|
||||
defer cancel()
|
||||
if ix.Host.Network().Connectedness(req.Target.ID) != network.Connected {
|
||||
if len(ix.Host.Network().ConnsToPeer(req.Target.ID)) == 0 {
|
||||
if err := ix.Host.Connect(ctx, req.Target); err != nil {
|
||||
respond(false, 0)
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user