@@ -2,7 +2,10 @@ use std::{thread, time::Duration};
22
33use base64:: prelude:: * ;
44use color_eyre:: Result ;
5- use iroh:: { Endpoint , SecretKey } ;
5+ use iroh:: {
6+ Endpoint , SecretKey ,
7+ protocol:: { ProtocolHandler , Router } ,
8+ } ;
69use iroh_ssh:: IrohSsh ;
710use pid1:: Pid1Settings ;
811use rust_supervisor:: { ChildType , Supervisor , SupervisorConfig } ;
@@ -29,11 +32,55 @@ async fn run_ssh() -> Result<()> {
2932 }
3033 let server = builder. build ( ) . await . expect ( "couldn't create iroh server" ) ;
3134 println ! ( "{}@{}" , whoami:: username( ) , server. node_id( ) ) ;
32- loop {
33- tokio:: time:: sleep ( Duration :: from_secs ( 60 ) ) . await ;
34- }
35+ tokio:: signal:: ctrl_c ( ) . await ?;
36+ Ok ( ( ) )
37+ }
38+
39+ #[ derive( Debug ) ]
40+ struct PortForwardHandler {
41+ port : u16 ,
3542}
3643
44+ impl ProtocolHandler for PortForwardHandler {
45+ async fn accept ( & self , connection : iroh:: endpoint:: Connection ) -> Result < ( ) , iroh:: protocol:: AcceptError > {
46+ let endpoint_id = connection. remote_id ( ) ;
47+ let port = self . port ;
48+
49+ match connection. accept_bi ( ) . await {
50+ Ok ( ( mut iroh_send, mut iroh_recv) ) => {
51+ println ! ( "Accepted bidirectional stream from {endpoint_id}" ) ;
52+
53+ match TcpStream :: connect ( format ! ( "127.0.0.1:{}" , port) ) . await {
54+ Ok ( mut output_stream) => {
55+ println ! ( "Connected to local server on port {}" , port) ;
56+
57+ let ( mut local_read, mut local_write) = output_stream. split ( ) ;
58+
59+ let a_to_b = async move { tokio:: io:: copy ( & mut local_read, & mut iroh_send) . await } ;
60+ let b_to_a = async move { tokio:: io:: copy ( & mut iroh_recv, & mut local_write) . await } ;
61+
62+ tokio:: select! {
63+ result = a_to_b => {
64+ println!( "{port}->Iroh stream ended: {result:?}" ) ;
65+ } ,
66+ result = b_to_a => {
67+ println!( "Iroh->{port} stream ended: {result:?}" ) ;
68+ } ,
69+ } ;
70+ }
71+ Err ( e) => {
72+ println ! ( "Failed to connect to local server {port}: {e}" ) ;
73+ }
74+ }
75+ }
76+ Err ( e) => {
77+ println ! ( "Failed to accept bidirectional stream {port}: {e}" ) ;
78+ }
79+ }
80+
81+ Ok ( ( ) )
82+ }
83+ }
3784#[ tokio:: main]
3885async fn port_forward ( ) -> Result < ( ) > {
3986 let Some ( secret_key) = get_secret_key ( ) else {
@@ -42,45 +89,22 @@ async fn port_forward() -> Result<()> {
4289 let secret_key: & [ u8 ; 32 ] = secret_key[ 0 ..32 ] . try_into ( ) . unwrap ( ) ;
4390 let secret_key = SecretKey :: from_bytes ( secret_key) ;
4491 if let Ok ( forwarded_ports) = std:: env:: var ( PORT_FORWARD_ENV ) {
92+ println ! ( "setting up port forwarding..." ) ;
4593 let mut join_set = JoinSet :: new ( ) ;
4694 for port in forwarded_ports. split ( ',' ) {
4795 let alpn: Vec < u8 > = format ! ( "/coman/{port}" ) . into_bytes ( ) ;
4896 let endpoint = Endpoint :: builder ( )
4997 . secret_key ( secret_key. clone ( ) )
50- . alpns ( vec ! [ alpn] )
98+ . alpns ( vec ! [ alpn. clone ( ) ] )
5199 . bind ( )
52100 . await ?;
101+
53102 let port = port. to_owned ( ) ;
54103 join_set. spawn ( async move {
55- while let Some ( incoming) = endpoint. accept ( ) . await {
56- let connection = incoming. await . unwrap ( ) ;
57- match connection. accept_bi ( ) . await {
58- Ok ( ( mut iroh_send, mut iroh_recv) ) => {
59- match TcpStream :: connect ( format ! ( "127.0.0.1:{port}" ) ) . await {
60- Ok ( mut stream) => {
61- let ( mut local_read, mut local_write) = stream. split ( ) ;
62- let a_to_b = async move { tokio:: io:: copy ( & mut local_read, & mut iroh_send) . await } ;
63- let b_to_a = async move { tokio:: io:: copy ( & mut iroh_recv, & mut local_write) . await } ;
64-
65- tokio:: select! {
66- result = a_to_b => {
67- println!( "{port}->Iroh stream ended: {result:?}" ) ;
68- } ,
69- result = b_to_a => {
70- println!( "Iroh->{port} stream ended: {result:?}" ) ;
71- } ,
72- } ;
73- }
74- Err ( e) => {
75- println ! ( "Failed to connect to {port}: {e:?}" ) ;
76- }
77- }
78- }
79- Err ( e) => {
80- println ! ( "Failed to accept stream to {port}: {e:?}" ) ;
81- }
82- }
83- }
104+ let handler = PortForwardHandler {
105+ port : port. parse :: < u16 > ( ) . expect ( "couldn't parse port" ) ,
106+ } ;
107+ Router :: builder ( endpoint. clone ( ) ) . accept ( & alpn, handler) . spawn ( ) ;
84108 } ) ;
85109 }
86110 while let Some ( res) = join_set. join_next ( ) . await {
0 commit comments