77 "strings"
88 "sync"
99
10+ "github.com/urfave/cli/v2"
11+
1012 "github.com/dennis-tra/pcp/internal/format"
1113 "github.com/dennis-tra/pcp/internal/log"
1214 "github.com/dennis-tra/pcp/pkg/dht"
@@ -17,11 +19,21 @@ import (
1719 "github.com/pkg/errors"
1820)
1921
22+ type PeerState uint8
23+
24+ const (
25+ NotConnected PeerState = iota
26+ Connecting
27+ Connected
28+ FailedConnecting
29+ FailedAuthentication
30+ )
31+
2032type Node struct {
2133 * pcpnode.Node
2234
23- discoverers []Discoverer
24- discoveredPeers * sync.Map
35+ discoverers []Discoverer
36+ peerStates * sync.Map // TODO: Use PeerStore?
2537}
2638
2739type Discoverer interface {
@@ -36,9 +48,9 @@ func InitNode(ctx context.Context, words []string) (*Node, error) {
3648 }
3749
3850 n := & Node {
39- Node : h ,
40- discoveredPeers : & sync.Map {},
41- discoverers : []Discoverer {},
51+ Node : h ,
52+ peerStates : & sync.Map {},
53+ discoverers : []Discoverer {},
4254 }
4355
4456 n .RegisterPushRequestHandler (n )
@@ -118,24 +130,35 @@ func (n *Node) HandlePeer(pi peer.AddrInfo) {
118130 }
119131
120132 // Check if we have already seen the peer and exit early to not connect again.
121- // TODO: Check if the multi addresses have changed
122- _ , loaded := n .discoveredPeers .LoadOrStore (pi .ID , pi )
123- if loaded {
124- log .Debugln ("Skipping peer as we tried to connect previously:" , pi .ID )
133+ peerState , _ := n .peerStates .LoadOrStore (pi .ID , NotConnected )
134+ switch peerState .(PeerState ) {
135+ case NotConnected :
136+ case Connecting :
137+ log .Debugln ("Skipping node as we're already trying to connect" , pi .ID )
138+ return
139+ case FailedConnecting :
140+ // TODO: Check if multiaddrs have changed and only connect if that's the case
141+ log .Debugln ("We tried to connect previously but couldn't establish a connection, try again" , pi .ID )
142+ case FailedAuthentication :
143+ log .Debugln ("We tried to connect previously but the node didn't pass authentication -> skipping" , pi .ID )
125144 return
126145 }
127146
128147 log .Debugln ("Connecting to peer:" , pi .ID )
148+ n .peerStates .Store (pi .ID , Connecting )
129149 if err := n .Connect (n .ServiceContext (), pi ); err != nil {
130150 log .Debugln ("Error connecting to peer:" , pi .ID , err )
151+ n .peerStates .Store (pi .ID , FailedConnecting )
131152 return
132153 }
133154
134155 // Negotiate PAKE
135156 if _ , err := n .StartKeyExchange (n .ServiceContext (), pi .ID ); err != nil {
136- log .Errorln (err )
157+ log .Errorln ("Peer didn't pass authentication:" , err )
158+ n .peerStates .Store (pi .ID , FailedAuthentication )
137159 return
138160 }
161+ n .peerStates .Store (pi .ID , Connected )
139162
140163 // We're authenticated so can initiate a transfer
141164 if n .GetState () == pcpnode .Connected {
0 commit comments