@@ -54,48 +54,67 @@ use libp2p::{
5454} ;
5555use libp2p_community_tor:: { AddressConversion , TorTransport } ;
5656use std:: error:: Error ;
57+ use tor_hsservice:: config:: OnionServiceConfigBuilder ;
5758
59+ /// Create a transport
60+ /// Returns a tuple of the transport and the onion address we can instruct it to listen on
5861async fn onion_transport (
5962 keypair : identity:: Keypair ,
6063) -> Result <
61- libp2p:: core:: transport:: Boxed < ( PeerId , libp2p:: core:: muxing:: StreamMuxerBox ) > ,
64+ (
65+ libp2p:: core:: transport:: Boxed < ( PeerId , libp2p:: core:: muxing:: StreamMuxerBox ) > ,
66+ Multiaddr ,
67+ ) ,
6268 Box < dyn Error > ,
6369> {
64- let transport = TorTransport :: bootstrapped ( )
70+ let mut transport = TorTransport :: bootstrapped ( )
6571 . await ?
66- . with_address_conversion ( AddressConversion :: IpAndDns )
67- . boxed ( ) ;
72+ . with_address_conversion ( AddressConversion :: IpAndDns ) ;
73+
74+ // We derive the nickname for the onion address from the peer id
75+ let svg_cfg = OnionServiceConfigBuilder :: default ( )
76+ . nickname (
77+ keypair
78+ . public ( )
79+ . to_peer_id ( )
80+ . to_base58 ( )
81+ . to_ascii_lowercase ( )
82+ . parse ( )
83+ . unwrap ( ) ,
84+ )
85+ . num_intro_points ( 3 )
86+ . build ( )
87+ . unwrap ( ) ;
88+
89+ let onion_listen_address = transport. add_onion_service ( svg_cfg, 999 ) . unwrap ( ) ;
6890
6991 let auth_upgrade = noise:: Config :: new ( & keypair) ?;
7092 let multiplex_upgrade = yamux:: Config :: default ( ) ;
7193
7294 let transport = transport
95+ . boxed ( )
7396 . upgrade ( Version :: V1 )
7497 . authenticate ( auth_upgrade)
7598 . multiplex ( multiplex_upgrade)
7699 . map ( |( peer, muxer) , _| ( peer, StreamMuxerBox :: new ( muxer) ) )
77100 . boxed ( ) ;
78101
79- Ok ( transport)
102+ Ok ( ( transport, onion_listen_address ) )
80103}
81104
82105#[ tokio:: main]
83106async fn main ( ) -> Result < ( ) , Box < dyn Error > > {
107+ tracing_subscriber:: fmt:: init ( ) ;
108+
84109 let local_key = identity:: Keypair :: generate_ed25519 ( ) ;
85110 let local_peer_id = PeerId :: from ( local_key. public ( ) ) ;
86111
87112 println ! ( "Local peer id: {local_peer_id}" ) ;
88113
89- let transport = onion_transport ( local_key) . await ?;
114+ let ( transport, onion_listen_address ) = onion_transport ( local_key) . await ?;
90115
91116 let mut swarm = SwarmBuilder :: with_new_identity ( )
92117 . with_tokio ( )
93- . with_tcp (
94- Default :: default ( ) ,
95- ( libp2p:: tls:: Config :: new, libp2p:: noise:: Config :: new) ,
96- libp2p:: yamux:: Config :: default,
97- )
98- . unwrap ( )
99118 . with_other_transport ( |_| transport)
100119 . unwrap ( )
101120 . with_behaviour ( |_| Behaviour {
@@ -104,18 +123,20 @@ async fn main() -> Result<(), Box<dyn Error>> {
104123 . unwrap ( )
105124 . build ( ) ;
106125
107- // Tell the swarm to listen on all interfaces and a random, OS-assigned
108- // port.
109- swarm
110- . listen_on ( "/ip4/0.0.0.0/tcp/0" . parse ( ) . unwrap ( ) )
111- . unwrap ( ) ;
112-
113126 // Dial the peer identified by the multi-address given as the second
114127 // command-line argument, if any.
115128 if let Some ( addr) = std:: env:: args ( ) . nth ( 1 ) {
116129 let remote: Multiaddr = addr. parse ( ) ?;
117130 swarm. dial ( remote) ?;
118131 println ! ( "Dialed {addr}" )
132+ } else {
133+ // TODO: We need to do this because otherwise the status of the onion service is gonna be [`Shutdown`]
134+ // when we first poll it and then the swarm will not pull it again (?). I don't know why this is the case.
135+ tokio:: time:: sleep ( std:: time:: Duration :: from_secs ( 20 ) ) . await ;
136+
137+ // If we are not dialing, we need to listen
138+ // Tell the swarm to listen on a specific onion address
139+ swarm. listen_on ( onion_listen_address) . unwrap ( ) ;
119140 }
120141
121142 loop {
0 commit comments