@@ -40,7 +40,9 @@ use std::{
40
40
41
41
type FiniteAddrScore = u32 ;
42
42
43
+ /// Config for the [`Behaviour`].
43
44
pub struct Config {
45
+ // Timeout for requests.
44
46
timeout : Duration ,
45
47
}
46
48
@@ -53,18 +55,26 @@ impl Default for Config {
53
55
}
54
56
55
57
impl Config {
58
+ /// Set the timeout for dial-requests.
56
59
pub fn with_timeout ( mut self , timeout : Duration ) -> Self {
57
60
self . timeout = timeout;
58
61
self
59
62
}
60
63
}
61
64
65
+ /// Network Behaviour for AutoNAT.
62
66
pub struct Behaviour {
67
+ // Inner protocol for sending requests and receiving the response.
63
68
inner : RequestResponse < AutoNatCodec > ,
64
- local_addresses : HashMap < Multiaddr , FiniteAddrScore > ,
65
- pending_inbound : HashMap < PeerId , ResponseChannel < DialResponse > > ,
66
- pending_outbound : HashSet < PeerId > ,
67
- send_request : VecDeque < PeerId > ,
69
+ // Local listening addresses with a score indicating their reachability.
70
+ // The score increases each time a remote peer successfully dials this address.
71
+ addresses : HashMap < Multiaddr , FiniteAddrScore > ,
72
+ // Ongoing inbound requests, where no response has been sent back to the remote yet.
73
+ ongoing_inbound : HashMap < PeerId , ResponseChannel < DialResponse > > ,
74
+ // Ongoing outbound dial-requests, where no response has been received from the remote yet.
75
+ ongoing_outbound : HashSet < PeerId > ,
76
+ // Recently connected peers to which we want to send a dial-request.
77
+ pending_requests : VecDeque < PeerId > ,
68
78
}
69
79
70
80
impl Default for Behaviour {
@@ -81,18 +91,27 @@ impl Behaviour {
81
91
let inner = RequestResponse :: new ( AutoNatCodec , protocols, cfg) ;
82
92
Self {
83
93
inner,
84
- local_addresses : HashMap :: default ( ) ,
85
- pending_inbound : HashMap :: default ( ) ,
86
- pending_outbound : HashSet :: default ( ) ,
87
- send_request : VecDeque :: default ( ) ,
94
+ addresses : HashMap :: default ( ) ,
95
+ ongoing_inbound : HashMap :: default ( ) ,
96
+ ongoing_outbound : HashSet :: default ( ) ,
97
+ pending_requests : VecDeque :: default ( ) ,
88
98
}
89
99
}
90
100
101
+ /// Add a new address to the address list that is send to remote peers in a dial-request.
91
102
pub fn add_local_address ( & mut self , address : Multiaddr ) {
92
- if self . local_addresses . get ( & address) . is_none ( ) {
93
- self . local_addresses . insert ( address, 1 ) ;
103
+ if self . addresses . get ( & address) . is_none ( ) {
104
+ self . addresses . insert ( address, 1 ) ;
94
105
}
95
106
}
107
+
108
+ /// Get the list of local addresses with their current score.
109
+ ///
110
+ /// The score of an address increases each time a remote peer successfully dialed us via this address.
111
+ /// Therefore higher scores indicate a higher reachability.
112
+ pub fn address_list ( & self ) -> impl Iterator < Item = ( & Multiaddr , & FiniteAddrScore ) > {
113
+ self . addresses . iter ( )
114
+ }
96
115
}
97
116
98
117
impl NetworkBehaviour for Behaviour {
@@ -112,7 +131,8 @@ impl NetworkBehaviour for Behaviour {
112
131
}
113
132
114
133
fn inject_disconnected ( & mut self , peer : & PeerId ) {
115
- self . inner . inject_disconnected ( peer)
134
+ self . inner . inject_disconnected ( peer) ;
135
+ self . ongoing_inbound . remove ( peer) ;
116
136
}
117
137
118
138
fn inject_connection_established (
@@ -123,11 +143,16 @@ impl NetworkBehaviour for Behaviour {
123
143
) {
124
144
self . inner
125
145
. inject_connection_established ( peer, conn, endpoint) ;
126
- if !self . pending_outbound . contains ( peer) {
127
- self . send_request . push_back ( * peer) ;
146
+
147
+ // Initiate a new dial request if there is none pending.
148
+ if !self . ongoing_outbound . contains ( peer) {
149
+ self . pending_requests . push_back ( * peer) ;
128
150
}
151
+
129
152
if let ConnectedPoint :: Dialer { address } = endpoint {
130
- if let Some ( channel) = self . pending_inbound . remove ( peer) {
153
+ if let Some ( channel) = self . ongoing_inbound . remove ( peer) {
154
+ // Successfully dialed one of the addresses from the remote peer.
155
+ // TODO: Check if the address was part of the list received in the dial-request.
131
156
let _ = self
132
157
. inner
133
158
. send_response ( channel, DialResponse :: Ok ( address. clone ( ) ) ) ;
@@ -144,9 +169,6 @@ impl NetworkBehaviour for Behaviour {
144
169
) {
145
170
self . inner
146
171
. inject_connection_closed ( peer, conn, endpoint, handler) ;
147
- // Channel can be dropped, as the underlying substream already closed.
148
- self . pending_inbound . remove ( peer) ;
149
- self . send_request . retain ( |p| p != peer) ;
150
172
}
151
173
152
174
fn inject_address_change (
@@ -157,24 +179,6 @@ impl NetworkBehaviour for Behaviour {
157
179
new : & ConnectedPoint ,
158
180
) {
159
181
self . inner . inject_address_change ( peer, conn, old, new) ;
160
- if let ConnectedPoint :: Listener {
161
- local_addr : old_addr,
162
- ..
163
- } = old
164
- {
165
- match new {
166
- ConnectedPoint :: Listener {
167
- local_addr : new_addr,
168
- ..
169
- } if old_addr != new_addr => {
170
- self . local_addresses . remove ( old_addr) ;
171
- if !self . local_addresses . contains_key ( new_addr) {
172
- self . local_addresses . insert ( new_addr. clone ( ) , 1 ) ;
173
- }
174
- }
175
- _ => { }
176
- }
177
- }
178
182
}
179
183
180
184
fn inject_event (
@@ -202,7 +206,8 @@ impl NetworkBehaviour for Behaviour {
202
206
error : libp2p_swarm:: DialError ,
203
207
) {
204
208
self . inner . inject_dial_failure ( peer_id, handler, error) ;
205
- if let Some ( channel) = self . pending_inbound . remove ( peer_id) {
209
+ if let Some ( channel) = self . ongoing_inbound . remove ( peer_id) {
210
+ // Failed to dial any of the addresses sent by the remote peer in their dial-request.
206
211
let _ = self
207
212
. inner
208
213
. send_response ( channel, DialResponse :: Err ( ResponseError :: DialError ) ) ;
@@ -225,14 +230,14 @@ impl NetworkBehaviour for Behaviour {
225
230
226
231
fn inject_new_listen_addr ( & mut self , id : ListenerId , addr : & Multiaddr ) {
227
232
self . inner . inject_new_listen_addr ( id, addr) ;
228
- if !self . local_addresses . contains_key ( addr) {
229
- self . local_addresses . insert ( addr. clone ( ) , 0 ) ;
233
+ if !self . addresses . contains_key ( addr) {
234
+ self . addresses . insert ( addr. clone ( ) , 0 ) ;
230
235
}
231
236
}
232
237
233
238
fn inject_expired_listen_addr ( & mut self , id : ListenerId , addr : & Multiaddr ) {
234
239
self . inner . inject_expired_listen_addr ( id, addr) ;
235
- self . local_addresses . remove ( addr) ;
240
+ self . addresses . remove ( addr) ;
236
241
}
237
242
238
243
fn inject_listener_error ( & mut self , id : ListenerId , err : & ( dyn std:: error:: Error + ' static ) ) {
@@ -245,18 +250,19 @@ impl NetworkBehaviour for Behaviour {
245
250
246
251
fn inject_new_external_addr ( & mut self , addr : & Multiaddr ) {
247
252
self . inner . inject_new_external_addr ( addr) ;
248
- match self . local_addresses . get_mut ( addr) {
253
+ // Add the address to the local address list.
254
+ match self . addresses . get_mut ( addr) {
249
255
Some ( score) if * score == 0 => * score = 1 ,
250
256
Some ( _) => { }
251
257
None => {
252
- self . local_addresses . insert ( addr. clone ( ) , 1 ) ;
258
+ self . addresses . insert ( addr. clone ( ) , 1 ) ;
253
259
}
254
260
}
255
261
}
256
262
257
263
fn inject_expired_external_addr ( & mut self , addr : & Multiaddr ) {
258
264
self . inner . inject_expired_external_addr ( addr) ;
259
- self . local_addresses . remove ( addr) ;
265
+ self . addresses . remove ( addr) ;
260
266
}
261
267
262
268
fn poll (
@@ -265,9 +271,8 @@ impl NetworkBehaviour for Behaviour {
265
271
params : & mut impl PollParameters ,
266
272
) -> Poll < NetworkBehaviourAction < Self :: OutEvent , Self :: ProtocolsHandler > > {
267
273
loop {
268
- if let Some ( peer_id) = self . send_request . pop_front ( ) {
269
- let mut scores: Vec < ( Multiaddr , FiniteAddrScore ) > =
270
- self . local_addresses . clone ( ) . into_iter ( ) . collect ( ) ;
274
+ if let Some ( peer_id) = self . pending_requests . pop_front ( ) {
275
+ let mut scores: Vec < _ > = self . addresses . clone ( ) . into_iter ( ) . collect ( ) ;
271
276
// Sort so that the address with the highest score will be dialed first by the remote.
272
277
scores. sort_by ( |( _, score_a) , ( _, score_b) | score_b. cmp ( score_a) ) ;
273
278
let addrs = scores. into_iter ( ) . map ( |( a, _) | a) . collect ( ) ;
@@ -283,11 +288,12 @@ impl NetworkBehaviour for Behaviour {
283
288
request : DialRequest { peer_id, addrs } ,
284
289
channel,
285
290
} => {
291
+ // Add all addresses to the address book.
286
292
for addr in addrs {
287
293
self . inner . add_address ( & peer, addr)
288
294
}
289
- // TODO: Handle if there is already a pending request.
290
- self . pending_inbound . insert ( peer_id, channel) ;
295
+ // TODO: Handle if there is already a ongoing request.
296
+ self . ongoing_inbound . insert ( peer_id, channel) ;
291
297
return Poll :: Ready ( NetworkBehaviourAction :: DialPeer {
292
298
peer_id : peer,
293
299
handler : self . inner . new_handler ( ) ,
@@ -298,9 +304,10 @@ impl NetworkBehaviour for Behaviour {
298
304
request_id : _,
299
305
response,
300
306
} => {
301
- self . pending_outbound . remove ( & peer) ;
307
+ self . ongoing_outbound . remove ( & peer) ;
302
308
if let DialResponse :: Ok ( address) = response {
303
- let score = self . local_addresses . entry ( address. clone ( ) ) . or_insert ( 1 ) ;
309
+ // Increase score of the successfully dialed address.
310
+ let score = self . addresses . entry ( address. clone ( ) ) . or_insert ( 1 ) ;
304
311
* score += 1 ;
305
312
return Poll :: Ready ( NetworkBehaviourAction :: ReportObservedAddr {
306
313
address,
@@ -315,12 +322,12 @@ impl NetworkBehaviour for Behaviour {
315
322
Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent (
316
323
RequestResponseEvent :: OutboundFailure { peer, .. } ,
317
324
) ) => {
318
- self . pending_outbound . remove ( & peer) ;
325
+ self . ongoing_outbound . remove ( & peer) ;
319
326
}
320
327
Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent (
321
328
RequestResponseEvent :: InboundFailure { peer, .. } ,
322
329
) ) => {
323
- self . pending_inbound . remove ( & peer) ;
330
+ self . ongoing_inbound . remove ( & peer) ;
324
331
}
325
332
Poll :: Ready ( NetworkBehaviourAction :: DialAddress { address, handler } ) => {
326
333
return Poll :: Ready ( NetworkBehaviourAction :: DialAddress { address, handler } )
0 commit comments