Debug
This commit is contained in:
@@ -1,16 +1,6 @@
|
||||
package node
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"time"
|
||||
|
||||
"oc-discovery/daemons/node/common"
|
||||
"oc-discovery/daemons/node/indexer"
|
||||
|
||||
oclib "cloud.o-forge.io/core/oc-lib"
|
||||
"cloud.o-forge.io/core/oc-lib/dbs"
|
||||
"cloud.o-forge.io/core/oc-lib/models/peer"
|
||||
"github.com/libp2p/go-libp2p/core/control"
|
||||
"github.com/libp2p/go-libp2p/core/host"
|
||||
"github.com/libp2p/go-libp2p/core/network"
|
||||
@@ -18,13 +8,10 @@ import (
|
||||
ma "github.com/multiformats/go-multiaddr"
|
||||
)
|
||||
|
||||
// OCConnectionGater enforces two rules on every inbound connection:
|
||||
// 1. If the peer is known locally and blacklisted → reject.
|
||||
// 2. If the peer is unknown locally → ask indexers one by one whether it
|
||||
// exists in the DHT. Accept as soon as one confirms it; reject if none do
|
||||
// (or if no indexers are reachable yet, allow optimistically).
|
||||
//
|
||||
// Outbound connections are always allowed — we chose to dial them.
|
||||
// OCConnectionGater allows all connections unconditionally.
|
||||
// Peer validation (local DB + DHT by peer_id) is enforced at the stream level
|
||||
// in each handler, so ProtocolHeartbeat and ProtocolPublish — through which a
|
||||
// node first registers itself — are never blocked.
|
||||
type OCConnectionGater struct {
|
||||
host host.Host
|
||||
}
|
||||
@@ -33,105 +20,12 @@ func newOCConnectionGater(h host.Host) *OCConnectionGater {
|
||||
return &OCConnectionGater{host: h}
|
||||
}
|
||||
|
||||
// InterceptPeerDial — allow all outbound dials.
|
||||
func (g *OCConnectionGater) InterceptPeerDial(_ pp.ID) bool { return true }
|
||||
|
||||
// InterceptAddrDial — allow all outbound dials.
|
||||
func (g *OCConnectionGater) InterceptAddrDial(_ pp.ID, _ ma.Multiaddr) bool { return true }
|
||||
|
||||
// InterceptAccept — allow at transport level (PeerID not yet known).
|
||||
func (g *OCConnectionGater) InterceptAccept(_ network.ConnMultiaddrs) bool { return true }
|
||||
|
||||
// InterceptUpgraded — final gate; always allow (decisions already made in InterceptSecured).
|
||||
func (g *OCConnectionGater) InterceptPeerDial(_ pp.ID) bool { return true }
|
||||
func (g *OCConnectionGater) InterceptAddrDial(_ pp.ID, _ ma.Multiaddr) bool { return true }
|
||||
func (g *OCConnectionGater) InterceptAccept(_ network.ConnMultiaddrs) bool { return true }
|
||||
func (g *OCConnectionGater) InterceptSecured(_ network.Direction, _ pp.ID, _ network.ConnMultiaddrs) bool {
|
||||
return true
|
||||
}
|
||||
func (g *OCConnectionGater) InterceptUpgraded(_ network.Conn) (bool, control.DisconnectReason) {
|
||||
return true, 0
|
||||
}
|
||||
|
||||
// InterceptSecured is called after the cryptographic handshake — PeerID is now known.
|
||||
// Only inbound connections are verified; outbound are trusted.
|
||||
func (g *OCConnectionGater) InterceptSecured(dir network.Direction, pid pp.ID, _ network.ConnMultiaddrs) bool {
|
||||
if dir == network.DirOutbound {
|
||||
return true
|
||||
}
|
||||
logger := oclib.GetLogger()
|
||||
|
||||
// 1. Local DB lookup by PeerID.
|
||||
access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
|
||||
results := access.Search(&dbs.Filters{
|
||||
And: map[string][]dbs.Filter{ // search by name if no filters are provided
|
||||
"peer_id": {{Operator: dbs.EQUAL.String(), Value: pid.String()}},
|
||||
},
|
||||
}, pid.String(), false)
|
||||
for _, item := range results.Data {
|
||||
p, ok := item.(*peer.Peer)
|
||||
if !ok || p.PeerID != pid.String() {
|
||||
continue
|
||||
}
|
||||
if p.Relation == peer.BLACKLIST {
|
||||
logger.Warn().Str("peer", pid.String()).Msg("[gater] rejected blacklisted peer")
|
||||
return false
|
||||
}
|
||||
// Known, not blacklisted.
|
||||
return true
|
||||
}
|
||||
|
||||
// 2. Unknown locally — verify via indexers.
|
||||
indexers := common.Indexers.GetAddrs()
|
||||
|
||||
if len(indexers) == 0 {
|
||||
// No indexers reachable yet — allow optimistically (bootstrap phase).
|
||||
logger.Warn().Str("peer", pid.String()).Msg("[gater] no indexers available, allowing unverified inbound")
|
||||
return true
|
||||
}
|
||||
|
||||
req := indexer.GetValue{PeerID: pid.String()}
|
||||
// A single DHT GetValue already traverses the entire DHT network, so asking
|
||||
// a second indexer would yield the same result. We only fall through to the
|
||||
// next indexer if the current one is unreachable (transport error), not if
|
||||
// it returns found=false (that answer is already DHT-wide authoritative).
|
||||
for _, ai := range indexers {
|
||||
found, reachable := queryIndexerPeerExists(g.host, *ai.Info, req)
|
||||
if !reachable {
|
||||
continue // indexer down — try next
|
||||
}
|
||||
if !found {
|
||||
logger.Warn().Str("peer", pid.String()).Msg("[gater] peer not found in DHT, rejecting inbound")
|
||||
}
|
||||
return found // definitive DHT answer
|
||||
}
|
||||
|
||||
// All indexers unreachable — allow optimistically rather than blocking indefinitely.
|
||||
logger.Warn().Str("peer", pid.String()).Msg("[gater] all indexers unreachable, allowing unverified inbound")
|
||||
return true
|
||||
}
|
||||
|
||||
// queryIndexerPeerExists opens a fresh one-shot stream to ai, sends a GetValue
|
||||
// request, and returns (found, reachable).
|
||||
// reachable=false means the indexer could not be reached (transport error);
|
||||
// the caller should then try another indexer.
|
||||
// reachable=true means the indexer answered — found is the DHT-wide authoritative result.
|
||||
func queryIndexerPeerExists(h host.Host, ai pp.AddrInfo, req indexer.GetValue) (found, reachable bool) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if h.Network().Connectedness(ai.ID) != network.Connected {
|
||||
if err := h.Connect(ctx, ai); err != nil {
|
||||
return false, false
|
||||
}
|
||||
}
|
||||
s, err := h.NewStream(ctx, ai.ID, common.ProtocolGet)
|
||||
if err != nil {
|
||||
return false, false
|
||||
}
|
||||
defer s.Close()
|
||||
s.SetDeadline(time.Now().Add(3 * time.Second))
|
||||
|
||||
if err := json.NewEncoder(s).Encode(req); err != nil {
|
||||
return false, false
|
||||
}
|
||||
var resp indexer.GetResponse
|
||||
if err := json.NewDecoder(s).Decode(&resp); err != nil {
|
||||
return false, false
|
||||
}
|
||||
return resp.Found, true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user