2626// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
2727// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2828// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29-
30- use crate :: { crypt:: types:: SharedSecret , proxy:: Command } ;
29+ use crate :: {
30+ crypt:: { self , Crypt , types:: SharedSecret } ,
31+ proxy:: Command ,
32+ } ;
3133
3234// Authors: Adolfo Gómez, dkmaster at dkmon dot com
3335use super :: * ;
@@ -41,6 +43,8 @@ struct TestContext {
4143 ctrl_rx : flume:: Receiver < Command > ,
4244 payload_tx : flume:: Sender < PayloadWithChannel > ,
4345 payload_rx : flume:: Receiver < PayloadWithChannel > ,
46+ crypt_inbound : Crypt ,
47+ crypt_outbound : Crypt ,
4448 stop : Trigger ,
4549}
4650
@@ -58,21 +62,26 @@ fn create_client() -> TestContext {
5862
5963 let stop = Trigger :: new ( ) ;
6064
65+ let crypt_inbound = Crypt :: new ( & secret_in, 0 ) ;
66+ let crypt_outbound = Crypt :: new ( & secret_out, 16 ) ;
67+
6168 // Crate a tunnel client with async-everything to ease testing
6269 TestContext {
6370 client : TunnelClient {
6471 reader : client_reader,
6572 writer : client_writer,
6673 tx : client_tx,
6774 rx : client_rx,
68- crypt_inbound : Crypt :: new ( & secret_in , 0 ) ,
69- crypt_outbound : Crypt :: new ( & secret_out , 16 ) ,
75+ crypt_inbound : crypt_inbound . clone ( ) ,
76+ crypt_outbound : crypt_outbound . clone ( ) ,
7077 stop : stop. clone ( ) ,
7178 proxy : Handler :: new ( ctrl_tx. clone ( ) ) ,
7279 } ,
7380 local,
7481 ctrl_tx,
7582 ctrl_rx,
83+ crypt_inbound,
84+ crypt_outbound,
7685 payload_tx,
7786 payload_rx,
7887 stop,
@@ -118,7 +127,7 @@ async fn check_stop() {
118127}
119128
120129#[ tokio:: test]
121- async fn check_connection_closed ( ) {
130+ async fn check_remote_connection_closed ( ) {
122131 let TestContext {
123132 client,
124133 local,
@@ -162,7 +171,7 @@ async fn check_connection_closed() {
162171}
163172
164173#[ tokio:: test]
165- async fn inbound_channel_closed_works_finely ( ) {
174+ async fn inbound_chan_closed_works_finely ( ) {
166175 let TestContext {
167176 client,
168177 ctrl_tx : _ctrl_tx,
@@ -190,6 +199,7 @@ async fn inbound_channel_closed_works_finely() {
190199 } ) ;
191200
192201 drop ( payload_tx) ;
202+ // Send something using locak, to ensure data is got
193203
194204 // If not stopped in time, it's a failure, as it means the client did not detect the channel closure
195205 stopped
@@ -203,3 +213,102 @@ async fn inbound_channel_closed_works_finely() {
203213 "Expected no commands to be sent to proxy after channel closure"
204214 ) ;
205215}
216+
217+ #[ tokio:: test]
218+ async fn outbound_chan_closed_works_finely ( ) {
219+ let TestContext {
220+ client,
221+ mut local, // We need to keep the cannels alive, event if not used
222+ ctrl_tx : _ctrl_tx,
223+ ctrl_rx,
224+ payload_tx : _payload_tx,
225+ payload_rx,
226+ mut crypt_outbound,
227+ stop,
228+ ..
229+ } = create_client ( ) ;
230+ let stopped = Trigger :: new ( ) ; // used to signal test completion
231+ tokio:: spawn ( {
232+ let stopped = stopped. clone ( ) ;
233+ async move {
234+ // Run the client, it should stop when we receive connection closed from server
235+ if client. run ( None ) . await . is_err ( ) {
236+ // Must return err, because chanel is closed
237+ log:: info!( "Client run failed as expected:" ) ;
238+ stopped. trigger ( ) ; // Signal that the client has stopped
239+ } else {
240+ log:: error!(
241+ "Client run completed successfully, expected failure due to channel closure"
242+ ) ;
243+ }
244+ log:: info!( "Client run completed" ) ;
245+ }
246+ } ) ;
247+
248+ drop ( payload_rx) ;
249+
250+ // Sends a valid packet, but as the channel is closed, it should cause the client to stop with an error
251+ crypt_outbound
252+ . write ( & stop, & mut local, 1 , b"test" )
253+ . await
254+ . unwrap ( ) ;
255+
256+ // If not stopped in time, it's a failure, as it means the client did not detect the channel closure
257+ stopped
258+ . wait_timeout_async ( std:: time:: Duration :: from_secs ( 1 ) )
259+ . await
260+ . unwrap ( ) ;
261+
262+ // No message on ctrl_rx, ensure
263+ assert ! (
264+ ctrl_rx. try_recv( ) . is_err( ) ,
265+ "Expected no commands to be sent to proxy after channel closure"
266+ ) ;
267+ }
268+
269+ #[ tokio:: test]
270+ async fn sends_data ( ) {
271+ let TestContext {
272+ client,
273+ mut local,
274+ // We need to keep the channels alive, event if not used
275+ ctrl_tx : _ctrl_tx,
276+ ctrl_rx : _ctrl_rx,
277+ payload_tx,
278+ payload_rx : _payload_rx,
279+ mut crypt_outbound,
280+ stop,
281+ ..
282+ } = create_client ( ) ;
283+ tokio:: spawn ( {
284+ let stop = stop. clone ( ) ;
285+ async move {
286+ // Run the client, it should stop when we receive connection closed from server
287+ if let Err ( e) = client. run ( None ) . await {
288+ log:: error!( "Client run failed: {:?}" , e) ;
289+ } else {
290+ log:: info!( "Client run completed successfully" ) ;
291+ }
292+ log:: info!( "Client run completed" ) ;
293+ stop. trigger ( ) ; // Signal that the client has stopped
294+ }
295+ } ) ;
296+
297+ // Send something using payload_tx
298+ payload_tx
299+ . send_async ( PayloadWithChannel :: new ( 1 , b"test" ) )
300+ . await
301+ . unwrap ( ) ;
302+
303+ // Read from local and decrypt
304+ let mut buffer = PacketBuffer :: new ( ) ;
305+ let ( data, channel_id) = crypt_outbound
306+ . read ( & stop, & mut local, & mut buffer)
307+ . await
308+ . unwrap ( ) ;
309+
310+ assert_eq ! ( channel_id, 1 ) ;
311+ assert_eq ! ( data, b"test" ) ;
312+
313+ stop. trigger ( ) ; // Stop the client
314+ }
0 commit comments