18
18
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
19
// DEALINGS IN THE SOFTWARE.
20
20
21
- pub use crate :: protocol:: DialResponse ;
22
- use crate :: protocol:: { AutoNatCodec , AutoNatProtocol } ;
21
+ use crate :: protocol:: { AutoNatCodec , AutoNatProtocol , DialRequest , DialResponse , ResponseError } ;
23
22
use libp2p_core:: {
24
23
connection:: { ConnectionId , ListenerId } ,
25
24
ConnectedPoint , Multiaddr , PeerId ,
26
25
} ;
27
26
use libp2p_request_response:: {
28
27
handler:: RequestResponseHandlerEvent , ProtocolSupport , RequestResponse , RequestResponseConfig ,
29
- RequestResponseEvent , RequestResponseMessage ,
28
+ RequestResponseEvent , RequestResponseMessage , ResponseChannel ,
30
29
} ;
31
30
use libp2p_swarm:: {
32
- IntoProtocolsHandler , NetworkBehaviour , NetworkBehaviourAction , PollParameters ,
31
+ AddressScore , DialPeerCondition , IntoProtocolsHandler , NetworkBehaviour ,
32
+ NetworkBehaviourAction , PollParameters ,
33
33
} ;
34
34
use std:: {
35
+ collections:: { HashMap , HashSet , VecDeque } ,
35
36
iter,
36
37
task:: { Context , Poll } ,
37
38
} ;
38
39
39
- #[ derive( Clone , Debug , Eq , PartialEq ) ]
40
- pub enum AutoNatEvent {
41
- DialResponse ( DialResponse ) ,
42
- }
40
+ type FiniteAddrScore = u32 ;
43
41
44
42
pub struct AutoNat {
45
43
inner : RequestResponse < AutoNatCodec > ,
44
+ local_addresses : HashMap < Multiaddr , FiniteAddrScore > ,
45
+ pending_inbound : HashMap < PeerId , ResponseChannel < DialResponse > > ,
46
+ pending_outbound : HashSet < PeerId > ,
47
+ send_request : VecDeque < PeerId > ,
46
48
}
47
49
48
- impl AutoNat {
49
- pub fn new ( ) -> Self {
50
+ impl Default for AutoNat {
51
+ fn default ( ) -> Self {
50
52
let protocols = iter:: once ( ( AutoNatProtocol , ProtocolSupport :: Full ) ) ;
51
53
let cfg = RequestResponseConfig :: default ( ) ;
52
54
let inner = RequestResponse :: new ( AutoNatCodec , protocols, cfg) ;
53
- Self { inner }
55
+ Self {
56
+ inner,
57
+ local_addresses : HashMap :: default ( ) ,
58
+ pending_inbound : HashMap :: default ( ) ,
59
+ pending_outbound : HashSet :: default ( ) ,
60
+ send_request : VecDeque :: default ( ) ,
61
+ }
54
62
}
63
+ }
55
64
56
- pub fn add_address ( & mut self , peer_id : & PeerId , addr : Multiaddr ) {
57
- self . inner . add_address ( peer_id, addr)
65
+ impl AutoNat {
66
+ pub fn add_local_address ( & mut self , address : Multiaddr ) {
67
+ if self . local_addresses . get ( & address) . is_none ( ) {
68
+ self . local_addresses . insert ( address, 1 ) ;
69
+ }
58
70
}
59
71
}
60
72
61
73
impl NetworkBehaviour for AutoNat {
62
74
type ProtocolsHandler = <RequestResponse < AutoNatCodec > as NetworkBehaviour >:: ProtocolsHandler ;
63
- type OutEvent = AutoNatEvent ;
75
+ type OutEvent = ( ) ;
64
76
65
77
fn new_handler ( & mut self ) -> Self :: ProtocolsHandler {
66
78
self . inner . new_handler ( )
@@ -85,7 +97,17 @@ impl NetworkBehaviour for AutoNat {
85
97
endpoint : & ConnectedPoint ,
86
98
) {
87
99
self . inner
88
- . inject_connection_established ( peer, conn, endpoint)
100
+ . inject_connection_established ( peer, conn, endpoint) ;
101
+ if !self . pending_outbound . contains ( peer) {
102
+ self . send_request . push_back ( * peer) ;
103
+ }
104
+ if let ConnectedPoint :: Dialer { address } = endpoint {
105
+ if let Some ( channel) = self . pending_inbound . remove ( peer) {
106
+ let _ = self
107
+ . inner
108
+ . send_response ( channel, DialResponse :: Ok ( address. clone ( ) ) ) ;
109
+ }
110
+ }
89
111
}
90
112
91
113
fn inject_connection_closed (
@@ -96,7 +118,10 @@ impl NetworkBehaviour for AutoNat {
96
118
handler : <Self :: ProtocolsHandler as IntoProtocolsHandler >:: Handler ,
97
119
) {
98
120
self . inner
99
- . inject_connection_closed ( peer, conn, endpoint, handler)
121
+ . inject_connection_closed ( peer, conn, endpoint, handler) ;
122
+ // Channel can be dropped, as the underlying substream already closed.
123
+ self . pending_inbound . remove ( peer) ;
124
+ self . send_request . retain ( |p| p != peer) ;
100
125
}
101
126
102
127
fn inject_address_change (
@@ -106,16 +131,34 @@ impl NetworkBehaviour for AutoNat {
106
131
old : & ConnectedPoint ,
107
132
new : & ConnectedPoint ,
108
133
) {
109
- self . inner . inject_address_change ( peer, conn, old, new)
134
+ self . inner . inject_address_change ( peer, conn, old, new) ;
135
+ if let ConnectedPoint :: Listener {
136
+ local_addr : old_addr,
137
+ ..
138
+ } = old
139
+ {
140
+ match new {
141
+ ConnectedPoint :: Listener {
142
+ local_addr : new_addr,
143
+ ..
144
+ } if old_addr != new_addr => {
145
+ self . local_addresses . remove ( old_addr) ;
146
+ if !self . local_addresses . contains_key ( new_addr) {
147
+ self . local_addresses . insert ( new_addr. clone ( ) , 1 ) ;
148
+ }
149
+ }
150
+ _ => { }
151
+ }
152
+ }
110
153
}
111
154
112
155
fn inject_event (
113
156
& mut self ,
114
- peer : PeerId ,
157
+ peer_id : PeerId ,
115
158
conn : ConnectionId ,
116
159
event : RequestResponseHandlerEvent < AutoNatCodec > ,
117
160
) {
118
- self . inner . inject_event ( peer , conn, event)
161
+ self . inner . inject_event ( peer_id , conn, event)
119
162
}
120
163
121
164
fn inject_addr_reach_failure (
@@ -133,7 +176,12 @@ impl NetworkBehaviour for AutoNat {
133
176
handler : Self :: ProtocolsHandler ,
134
177
error : libp2p_swarm:: DialError ,
135
178
) {
136
- self . inner . inject_dial_failure ( peer_id, handler, error)
179
+ self . inner . inject_dial_failure ( peer_id, handler, error) ;
180
+ if let Some ( channel) = self . pending_inbound . remove ( peer_id) {
181
+ let _ = self
182
+ . inner
183
+ . send_response ( channel, DialResponse :: Err ( ResponseError :: DialError ) ) ;
184
+ }
137
185
}
138
186
139
187
fn inject_listen_failure (
@@ -151,11 +199,15 @@ impl NetworkBehaviour for AutoNat {
151
199
}
152
200
153
201
fn inject_new_listen_addr ( & mut self , id : ListenerId , addr : & Multiaddr ) {
154
- self . inner . inject_new_listen_addr ( id, addr)
202
+ self . inner . inject_new_listen_addr ( id, addr) ;
203
+ if !self . local_addresses . contains_key ( addr) {
204
+ self . local_addresses . insert ( addr. clone ( ) , 0 ) ;
205
+ }
155
206
}
156
207
157
208
fn inject_expired_listen_addr ( & mut self , id : ListenerId , addr : & Multiaddr ) {
158
- self . inner . inject_expired_listen_addr ( id, addr)
209
+ self . inner . inject_expired_listen_addr ( id, addr) ;
210
+ self . local_addresses . remove ( addr) ;
159
211
}
160
212
161
213
fn inject_listener_error ( & mut self , id : ListenerId , err : & ( dyn std:: error:: Error + ' static ) ) {
@@ -167,11 +219,19 @@ impl NetworkBehaviour for AutoNat {
167
219
}
168
220
169
221
fn inject_new_external_addr ( & mut self , addr : & Multiaddr ) {
170
- self . inner . inject_new_external_addr ( addr)
222
+ self . inner . inject_new_external_addr ( addr) ;
223
+ match self . local_addresses . get_mut ( addr) {
224
+ Some ( score) if * score == 0 => * score = 1 ,
225
+ Some ( _) => { } ,
226
+ None => {
227
+ self . local_addresses . insert ( addr. clone ( ) , 1 ) ;
228
+ }
229
+ }
171
230
}
172
231
173
232
fn inject_expired_external_addr ( & mut self , addr : & Multiaddr ) {
174
- self . inner . inject_expired_external_addr ( addr)
233
+ self . inner . inject_expired_external_addr ( addr) ;
234
+ self . local_addresses . remove ( addr) ;
175
235
}
176
236
177
237
fn poll (
@@ -180,46 +240,62 @@ impl NetworkBehaviour for AutoNat {
180
240
params : & mut impl PollParameters ,
181
241
) -> Poll < NetworkBehaviourAction < Self :: OutEvent , Self :: ProtocolsHandler > > {
182
242
loop {
243
+ if let Some ( peer_id) = self . send_request . pop_front ( ) {
244
+ let mut scores: Vec < ( Multiaddr , FiniteAddrScore ) > =
245
+ self . local_addresses . clone ( ) . into_iter ( ) . collect ( ) ;
246
+ // Sort so that the address with the highest score will be dialed first by the remote.
247
+ scores. sort_by ( |( _, score_a) , ( _, score_b) | score_b. cmp ( score_a) ) ;
248
+ let addrs = scores. into_iter ( ) . map ( |( a, _) | a) . collect ( ) ;
249
+ self . inner
250
+ . send_request ( & peer_id, DialRequest { peer_id, addrs } ) ;
251
+ }
183
252
match self . inner . poll ( cx, params) {
184
253
Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent (
185
254
RequestResponseEvent :: Message { peer, message } ,
186
255
) ) => match message {
187
256
RequestResponseMessage :: Request {
188
- request_id,
189
- request,
257
+ request_id : _ ,
258
+ request : DialRequest { peer_id , addrs } ,
190
259
channel,
191
260
} => {
192
- println ! ( "{} {:?} {:?} {:?}" , peer, request_id, request, channel) ;
261
+ for addr in addrs {
262
+ self . inner . add_address ( & peer, addr)
263
+ }
264
+ // TODO: Handle if there is already a pending request.
265
+ self . pending_inbound . insert ( peer_id, channel) ;
266
+ return Poll :: Ready ( NetworkBehaviourAction :: DialPeer {
267
+ peer_id : peer,
268
+ handler : self . inner . new_handler ( ) ,
269
+ condition : DialPeerCondition :: Always ,
270
+ } ) ;
193
271
}
194
272
RequestResponseMessage :: Response {
195
- request_id,
273
+ request_id : _ ,
196
274
response,
197
275
} => {
198
- println ! ( "{} {:?} {:?}" , peer, request_id, response) ;
276
+ self . pending_outbound . remove ( & peer) ;
277
+ if let DialResponse :: Ok ( address) = response {
278
+ let score = self . local_addresses . entry ( address. clone ( ) ) . or_insert ( 1 ) ;
279
+ * score += 1 ;
280
+ return Poll :: Ready ( NetworkBehaviourAction :: ReportObservedAddr {
281
+ address,
282
+ score : AddressScore :: Finite ( * score) ,
283
+ } ) ;
284
+ }
199
285
}
200
286
} ,
201
287
Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent (
202
- RequestResponseEvent :: ResponseSent { peer, request_id } ,
203
- ) ) => {
204
- println ! ( "response sent {} {:?}" , peer, request_id) ;
205
- }
288
+ RequestResponseEvent :: ResponseSent { .. } ,
289
+ ) ) => { }
206
290
Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent (
207
- RequestResponseEvent :: OutboundFailure {
208
- peer,
209
- request_id,
210
- error,
211
- } ,
291
+ RequestResponseEvent :: OutboundFailure { peer, .. } ,
212
292
) ) => {
213
- println ! ( "outbound failure {} {:?} {:?}" , peer, request_id , error ) ;
293
+ self . pending_outbound . remove ( & peer) ;
214
294
}
215
295
Poll :: Ready ( NetworkBehaviourAction :: GenerateEvent (
216
- RequestResponseEvent :: InboundFailure {
217
- peer,
218
- error,
219
- request_id,
220
- } ,
296
+ RequestResponseEvent :: InboundFailure { peer, .. } ,
221
297
) ) => {
222
- println ! ( "inbound failure {} {:?} {:?}" , peer, request_id , error ) ;
298
+ self . pending_inbound . remove ( & peer) ;
223
299
}
224
300
Poll :: Ready ( NetworkBehaviourAction :: DialAddress { address, handler } ) => {
225
301
return Poll :: Ready ( NetworkBehaviourAction :: DialAddress { address, handler } )
0 commit comments