@startuml connection_gater title ConnectionGater — Vérification à l'admission (InterceptSecured) participant "Remote Peer\n(inbound)" as Remote participant "libp2p\nhost A" as Host participant "OCConnectionGater" as Gater participant "DB (oc-lib)" as DB participant "Indexer X\n(joignable)" as IX participant "Indexer Y\n(injoignable)" as IY Remote -> Host: inbound connection (post-PSK, post-TLS) Host -> Gater: InterceptSecured(dir=Inbound, id=RemotePeerID, conn) alt dir == Outbound Gater --> Host: true (outbound toujours autorisé) end == Étape 1 : Vérification base de données == Gater -> DB: NewRequestAdmin(PEER).Search(\n Filter: peer_id = RemotePeerID\n) DB --> Gater: []peer.Peer alt trouvé AND relation == BLACKLIST Gater --> Host: false (refusé — blacklisté) Host ->x Remote: connexion fermée end alt trouvé AND relation != BLACKLIST Gater --> Host: true (connu et non blacklisté) end == Étape 2 : Vérification DHT (peer inconnu en DB) == note over Gater: Peer inconnu → vérifier qu'il existe\ndans le réseau DHT Gater -> Gater: getReq = GetValue{PeerID: RemotePeerID} loop Pour chaque indexeur (ordre aléatoire — Shuffle) alt Indexer IY injoignable (transport error) Gater -> IY: h.Connect(ctxTTL, IY_AddrInfo) IY -->x Gater: connexion échouée note over Gater: reachable=false\n→ essaie le suivant end alt Indexer IX joignable Gater -> IX: h.Connect(ctxTTL, IX_AddrInfo) IX --> Gater: OK Gater -> IX: TempStream /opencloud/record/get/1.0 Gater -> IX: stream.Encode(GetValue{PeerID: RemotePeerID}) IX -> IX: Recherche locale + DHT si absent IX --> Gater: GetResponse{Found: true/false, Records} note over Gater: reachable=true → réponse autoritaire\n(DHT distribué : un seul indexeur suffit) alt Found == true Gater --> Host: true (pair connu du réseau) else Found == false Gater --> Host: false (refusé — inconnu du réseau) Host ->x Remote: connexion fermée end end end alt Aucun indexeur joignable note over Gater: Réseau naissant ou tous isolés.\nAutorisation par défaut. Gater --> Host: true end @enduml