@@ -92,14 +92,19 @@ pub enum PProxyCommandResponse {
92
92
ExpirePeerAccess { } ,
93
93
}
94
94
95
+ pub struct TunnelContext {
96
+ tx : mpsc:: Sender < ChannelPackage > ,
97
+ outbound_sent_notifier : Option < CommandNotifier > ,
98
+ }
99
+
95
100
pub struct PProxy {
96
101
command_tx : mpsc:: Sender < ( PProxyCommand , CommandNotifier ) > ,
97
102
command_rx : mpsc:: Receiver < ( PProxyCommand , CommandNotifier ) > ,
98
103
swarm : Swarm < PProxyNetworkBehaviour > ,
99
104
proxy_addr : Option < SocketAddr > ,
100
105
outbound_ready_notifiers : HashMap < request_response:: OutboundRequestId , CommandNotifier > ,
101
106
inbound_tunnels : HashMap < ( PeerId , TunnelId ) , Tunnel > ,
102
- tunnel_txs : HashMap < ( PeerId , TunnelId ) , mpsc :: Sender < ChannelPackage > > ,
107
+ tunnel_ctx : HashMap < ( PeerId , TunnelId ) , TunnelContext > ,
103
108
access_client : Option < AccessClient > ,
104
109
}
105
110
@@ -129,7 +134,7 @@ impl PProxy {
129
134
proxy_addr,
130
135
outbound_ready_notifiers : HashMap :: new ( ) ,
131
136
inbound_tunnels : HashMap :: new ( ) ,
132
- tunnel_txs : HashMap :: new ( ) ,
137
+ tunnel_ctx : HashMap :: new ( ) ,
133
138
access_client,
134
139
} ,
135
140
PProxyHandle {
@@ -175,7 +180,10 @@ impl PProxy {
175
180
tunnel. listen ( stream, tunnel_rx) . await ?;
176
181
177
182
self . inbound_tunnels . insert ( ( peer_id, tunnel_id) , tunnel) ;
178
- self . tunnel_txs . insert ( ( peer_id, tunnel_id) , tunnel_tx) ;
183
+ self . tunnel_ctx . insert ( ( peer_id, tunnel_id) , TunnelContext {
184
+ tx : tunnel_tx,
185
+ outbound_sent_notifier : None ,
186
+ } ) ;
179
187
180
188
Ok ( ( ) )
181
189
}
@@ -191,7 +199,7 @@ impl PProxy {
191
199
& mut self ,
192
200
peer_id : PeerId ,
193
201
request : proto:: Tunnel ,
194
- ) -> Result < Option < proto:: Tunnel > > {
202
+ ) -> Result < proto:: Tunnel > {
195
203
let tunnel_id = request
196
204
. tunnel_id
197
205
. parse ( )
@@ -216,11 +224,11 @@ impl PProxy {
216
224
}
217
225
} ;
218
226
219
- Ok ( Some ( proto:: Tunnel {
227
+ Ok ( proto:: Tunnel {
220
228
tunnel_id : tunnel_id. to_string ( ) ,
221
229
command : proto:: TunnelCommand :: ConnectResp . into ( ) ,
222
230
data,
223
- } ) )
231
+ } )
224
232
}
225
233
226
234
proto:: TunnelCommand :: Package => {
@@ -231,16 +239,20 @@ impl PProxy {
231
239
return Err ( Error :: AccessDenied ( peer_id. to_string ( ) ) ) ;
232
240
}
233
241
234
- let Some ( tx ) = self . tunnel_txs . get ( & ( peer_id, tunnel_id) ) else {
242
+ let Some ( ctx ) = self . tunnel_ctx . get ( & ( peer_id, tunnel_id) ) else {
235
243
return Err ( Error :: ProtocolNotSupport (
236
244
"No tunnel for Package" . to_string ( ) ,
237
245
) ) ;
238
246
} ;
239
247
240
- tx. send ( Ok ( request. data . unwrap_or_default ( ) ) ) . await ?;
248
+ ctx . tx . send ( Ok ( request. data . unwrap_or_default ( ) ) ) . await ?;
241
249
242
250
// Have to do this to close the response waiter in remote.
243
- Ok ( None )
251
+ Ok ( proto:: Tunnel {
252
+ tunnel_id : tunnel_id. to_string ( ) ,
253
+ command : proto:: TunnelCommand :: PackageResp . into ( ) ,
254
+ data : None ,
255
+ } )
244
256
}
245
257
246
258
_ => Err ( Error :: ProtocolNotSupport (
@@ -263,7 +275,7 @@ impl PProxy {
263
275
264
276
SwarmEvent :: ConnectionClosed { peer_id, .. } => {
265
277
self . inbound_tunnels . retain ( |( p, _) , _| p != & peer_id) ;
266
- self . tunnel_txs . retain ( |( p, _) , _| p != & peer_id) ;
278
+ self . tunnel_ctx . retain ( |( p, _) , _| p != & peer_id) ;
267
279
}
268
280
269
281
SwarmEvent :: Behaviour ( PProxyNetworkBehaviourEvent :: RequestResponse (
@@ -278,13 +290,13 @@ impl PProxy {
278
290
Err ( e) => {
279
291
if let Ok ( tunnel_id) = tunnel_id. parse ( ) {
280
292
self . inbound_tunnels . remove ( & ( peer, tunnel_id) ) ;
281
- self . tunnel_txs . remove ( & ( peer, tunnel_id) ) ;
293
+ self . tunnel_ctx . remove ( & ( peer, tunnel_id) ) ;
282
294
}
283
- Some ( proto:: Tunnel {
295
+ proto:: Tunnel {
284
296
tunnel_id,
285
297
command : proto:: TunnelCommand :: Break . into ( ) ,
286
298
data : Some ( e. to_string ( ) . as_bytes ( ) . to_vec ( ) ) ,
287
- } )
299
+ }
288
300
}
289
301
} ;
290
302
@@ -299,11 +311,6 @@ impl PProxy {
299
311
request_id,
300
312
response,
301
313
} => {
302
- // This is response of TunnelCommand::Package
303
- let Some ( response) = response else {
304
- return Ok ( ( ) ) ;
305
- } ;
306
-
307
314
match response. command ( ) {
308
315
proto:: TunnelCommand :: ConnectResp => {
309
316
let tx = self
@@ -326,6 +333,28 @@ impl PProxy {
326
333
. map_err ( |_| Error :: EssentialTaskClosed ) ?;
327
334
}
328
335
336
+ proto:: TunnelCommand :: PackageResp => {
337
+ let tunnel_id = response. tunnel_id . parse ( ) . map_err ( |_| {
338
+ Error :: TunnelIdParseError ( response. tunnel_id . clone ( ) )
339
+ } ) ?;
340
+
341
+ let Some ( ctx) = self . tunnel_ctx . get_mut ( & ( peer, tunnel_id) ) else {
342
+ return Err ( Error :: ProtocolNotSupport (
343
+ "No ctx for Package" . to_string ( ) ,
344
+ ) ) ;
345
+ } ;
346
+
347
+ let Some ( notifier) = ctx. outbound_sent_notifier . take ( ) else {
348
+ return Err ( Error :: ProtocolNotSupport (
349
+ "No notifier for Package" . to_string ( ) ,
350
+ ) ) ;
351
+ } ;
352
+
353
+ notifier
354
+ . send ( Ok ( PProxyCommandResponse :: SendOutboundPackageCommand { } ) )
355
+ . map_err ( |_| Error :: EssentialTaskClosed ) ?;
356
+ }
357
+
329
358
proto:: TunnelCommand :: Break => {
330
359
let tunnel_id = response. tunnel_id . parse ( ) . map_err ( |_| {
331
360
Error :: TunnelIdParseError ( response. tunnel_id . clone ( ) )
@@ -338,8 +367,8 @@ impl PProxy {
338
367
}
339
368
340
369
// Terminat connected tunnel
341
- if let Some ( tx ) = self . tunnel_txs . remove ( & ( peer, tunnel_id) ) {
342
- tx. send ( Err ( TunnelError :: ConnectionAborted ) ) . await ?
370
+ if let Some ( ctx ) = self . tunnel_ctx . remove ( & ( peer, tunnel_id) ) {
371
+ ctx . tx . send ( Err ( TunnelError :: ConnectionAborted ) ) . await ?
343
372
} ;
344
373
}
345
374
@@ -432,7 +461,10 @@ impl PProxy {
432
461
tunnel_tx : mpsc:: Sender < ChannelPackage > ,
433
462
tx : CommandNotifier ,
434
463
) -> Result < ( ) > {
435
- self . tunnel_txs . insert ( ( peer_id, tunnel_id) , tunnel_tx) ;
464
+ self . tunnel_ctx . insert ( ( peer_id, tunnel_id) , TunnelContext {
465
+ tx : tunnel_tx,
466
+ outbound_sent_notifier : None ,
467
+ } ) ;
436
468
437
469
let request = proto:: Tunnel {
438
470
tunnel_id : tunnel_id. to_string ( ) ,
@@ -465,13 +497,23 @@ impl PProxy {
465
497
data : Some ( data) ,
466
498
} ;
467
499
500
+ let Some ( ctx) = self . tunnel_ctx . get_mut ( & ( peer_id, tunnel_id) ) else {
501
+ let err_msg = "No ctx for outbound package" ;
502
+
503
+ tx. send ( Err ( Error :: TunnelContextNotFound ( err_msg. to_string ( ) ) ) )
504
+ . map_err ( |_| Error :: EssentialTaskClosed ) ?;
505
+
506
+ return Err ( Error :: TunnelContextNotFound ( err_msg. to_string ( ) ) ) ;
507
+ } ;
508
+
509
+ ctx. outbound_sent_notifier = Some ( tx) ;
510
+
468
511
self . swarm
469
512
. behaviour_mut ( )
470
513
. request_response
471
514
. send_request ( & peer_id, request) ;
472
515
473
- tx. send ( Ok ( PProxyCommandResponse :: SendOutboundPackageCommand { } ) )
474
- . map_err ( |_| Error :: EssentialTaskClosed )
516
+ Ok ( ( ) )
475
517
}
476
518
477
519
async fn on_expire_peer_access ( & mut self , peer_id : PeerId , tx : CommandNotifier ) -> Result < ( ) > {
0 commit comments