dfi.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. #[macro_use]
  2. extern crate clap;
  3. use async_executor::Executor;
  4. use async_std::sync::Mutex;
  5. use easy_parallel::Parallel;
  6. use log::*;
  7. use serde_json::json;
  8. use std::collections::HashMap;
  9. use std::net::SocketAddr;
  10. use std::sync::Arc;
  11. use sapvi::net;
  12. use sapvi::{Channel, Result, SeedProtocol, ServerProtocol};
  13. use std::net::TcpListener;
  14. use async_native_tls::TlsAcceptor;
  15. use http_types::{Request, Response, StatusCode};
  16. use smol::Async;
  17. /// Listens for incoming connections and serves them.
  18. async fn listen(
  19. executor: Arc<Executor<'_>>,
  20. rpc: Arc<RpcInterface>,
  21. listener: Async<TcpListener>,
  22. tls: Option<TlsAcceptor>,
  23. ) -> Result<()> {
  24. // Format the full host address.
  25. let host = match &tls {
  26. None => format!("http://{}", listener.get_ref().local_addr()?),
  27. Some(_) => format!("https://{}", listener.get_ref().local_addr()?),
  28. };
  29. println!("Listening on {}", host);
  30. loop {
  31. // Accept the next connection.
  32. let (stream, _) = listener.accept().await?;
  33. // Spawn a background task serving this connection.
  34. let task = match &tls {
  35. None => {
  36. let stream = async_dup::Arc::new(stream);
  37. let rpc = rpc.clone();
  38. executor.spawn(async move {
  39. if let Err(err) = async_h1::accept(stream, move |req| {
  40. let rpc = rpc.clone();
  41. rpc.serve(req)
  42. })
  43. .await
  44. {
  45. println!("Connection error: {:#?}", err);
  46. }
  47. })
  48. }
  49. Some(tls) => {
  50. // In case of HTTPS, establish a secure TLS connection first.
  51. match tls.accept(stream).await {
  52. Ok(stream) => {
  53. let _stream = async_dup::Arc::new(async_dup::Mutex::new(stream));
  54. executor.spawn(async move {
  55. /*if let Err(err) = async_h1::accept(stream, serve).await {
  56. println!("Connection error: {:#?}", err);
  57. }*/
  58. unimplemented!();
  59. })
  60. }
  61. Err(err) => {
  62. println!("Failed to establish secure TLS connection: {:#?}", err);
  63. continue;
  64. }
  65. }
  66. }
  67. };
  68. // Detach the task to let it run in the background.
  69. task.detach();
  70. }
  71. }
  72. struct RpcInterface {
  73. p2p: Arc<net::P2p>,
  74. started: Mutex<bool>,
  75. quit_send: async_channel::Sender<()>,
  76. quit_recv: async_channel::Receiver<()>,
  77. }
  78. impl RpcInterface {
  79. fn new(p2p: Arc<net::P2p>) -> Arc<Self> {
  80. let (quit_send, quit_recv) = async_channel::unbounded::<()>();
  81. Arc::new(Self {
  82. p2p,
  83. started: Mutex::new(false),
  84. quit_send,
  85. quit_recv,
  86. })
  87. }
  88. async fn serve(self: Arc<Self>, mut req: Request) -> http_types::Result<Response> {
  89. println!("Serving {}", req.url());
  90. let request = req.body_string().await?;
  91. let mut io = jsonrpc_core::IoHandler::new();
  92. io.add_sync_method("say_hello", |_| {
  93. Ok(jsonrpc_core::Value::String("Hello World!".into()))
  94. });
  95. let self2 = self.clone();
  96. io.add_method("get_info", move |_| {
  97. let self2 = self2.clone();
  98. async move { Ok(json!({"started": *self2.started.lock().await})) }
  99. });
  100. let quit_send = self.quit_send.clone();
  101. io.add_method("quit", move |_| {
  102. let quit_send = quit_send.clone();
  103. async move {
  104. let _ = quit_send.send(()).await;
  105. Ok(jsonrpc_core::Value::Null)
  106. }
  107. });
  108. let response = io
  109. .handle_request_sync(&request)
  110. .ok_or(sapvi::Error::BadOperationType)?;
  111. let mut res = Response::new(StatusCode::Ok);
  112. res.insert_header("Content-Type", "text/plain");
  113. res.set_body(response);
  114. Ok(res)
  115. }
  116. async fn wait_for_quit(self: Arc<Self>) -> Result<()> {
  117. Ok(self.quit_recv.recv().await?)
  118. }
  119. }
  120. async fn start(executor: Arc<Executor<'_>>, options: ProgramOptions) -> Result<()> {
  121. let p2p = net::P2p::new(options.network_settings);
  122. let rpc = RpcInterface::new(p2p.clone());
  123. let http = listen(
  124. executor.clone(),
  125. rpc.clone(),
  126. Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?,
  127. None,
  128. );
  129. let http_task = executor.spawn(http);
  130. *rpc.started.lock().await = true;
  131. p2p.start(executor.clone()).await?;
  132. rpc.wait_for_quit().await?;
  133. http_task.cancel().await;
  134. Ok(())
  135. }
  136. async fn start2(executor: Arc<Executor<'_>>, options: ProgramOptions) -> Result<()> {
  137. let connections = Arc::new(Mutex::new(HashMap::new()));
  138. let stored_addrs = Arc::new(Mutex::new(Vec::new()));
  139. let executor2 = executor.clone();
  140. let stored_addrs2 = stored_addrs.clone();
  141. let mut server_task = None;
  142. if let Some(accept_addr) = options.accept_addr {
  143. let accept_addr = accept_addr.clone();
  144. let protocol = ServerProtocol::new(connections.clone(), accept_addr, stored_addrs2);
  145. server_task = Some(executor.spawn(async move {
  146. protocol.start(executor2).await?;
  147. Ok::<(), sapvi::Error>(())
  148. }));
  149. }
  150. let mut seed_protocols = Vec::with_capacity(options.seed_addrs.len());
  151. // Normally we query this from a server
  152. let accept_addr = options.accept_addr.clone();
  153. for seed_addr in options.seed_addrs.iter() {
  154. let protocol = SeedProtocol::new(seed_addr.clone(), accept_addr, stored_addrs.clone());
  155. protocol.clone().start(executor.clone()).await;
  156. seed_protocols.push(protocol);
  157. }
  158. debug!("Waiting for seed node queries to finish...");
  159. for seed_protocol in seed_protocols {
  160. seed_protocol.await_finish().await;
  161. }
  162. debug!("Seed nodes queried.");
  163. let mut client_slots = vec![];
  164. for i in 0..options.connection_slots {
  165. debug!("Starting connection slot {}", i);
  166. let client = Channel::new(
  167. connections.clone(),
  168. accept_addr.clone(),
  169. stored_addrs.clone(),
  170. );
  171. client.clone().start(executor.clone()).await;
  172. client_slots.push(client);
  173. }
  174. for remote_addr in options.manual_connects {
  175. debug!("Starting connection (manual) to {}", remote_addr);
  176. let client = Channel::new(
  177. connections.clone(),
  178. accept_addr.clone(),
  179. stored_addrs.clone(),
  180. );
  181. client
  182. .clone()
  183. .start_manual(remote_addr, executor.clone())
  184. .await;
  185. client_slots.push(client);
  186. }
  187. /*
  188. let rpc = RpcInterface::new();
  189. let http = listen(
  190. executor.clone(),
  191. rpc.clone(),
  192. Async::<TcpListener>::bind(([127, 0, 0, 1], 8000))?,
  193. None,
  194. );
  195. let http_task = executor.spawn(http);
  196. rpc.quit_recv.recv().await?;
  197. http_task.cancel().await;
  198. */
  199. match server_task {
  200. None => {}
  201. Some(server_task) => {
  202. server_task.cancel().await;
  203. }
  204. }
  205. Ok(())
  206. }
  207. struct ProgramOptions {
  208. network_settings: net::Settings,
  209. accept_addr: Option<SocketAddr>,
  210. seed_addrs: Vec<SocketAddr>,
  211. manual_connects: Vec<SocketAddr>,
  212. connection_slots: u32,
  213. log_path: Box<std::path::PathBuf>,
  214. }
  215. impl ProgramOptions {
  216. fn load() -> Result<ProgramOptions> {
  217. let app = clap_app!(dfi =>
  218. (version: "0.1.0")
  219. (author: "Amir Taaki <amir@dyne.org>")
  220. (about: "Dark node")
  221. (@arg ACCEPT: -a --accept +takes_value "Accept address")
  222. (@arg SEED_NODES: -s --seeds ... "Seed nodes")
  223. (@arg CONNECTS: -c --connect ... "Manual connections")
  224. (@arg CONNECT_SLOTS: --slots +takes_value "Connection slots")
  225. (@arg LOG_PATH: --log +takes_value "Logfile path")
  226. )
  227. .get_matches();
  228. let accept_addr = if let Some(accept_addr) = app.value_of("ACCEPT") {
  229. Some(accept_addr.parse()?)
  230. } else {
  231. None
  232. };
  233. let mut seed_addrs: Vec<SocketAddr> = vec![];
  234. if let Some(seeds) = app.values_of("SEED_NODES") {
  235. for seed in seeds {
  236. seed_addrs.push(seed.parse()?);
  237. }
  238. }
  239. let mut manual_connects: Vec<SocketAddr> = vec![];
  240. if let Some(connections) = app.values_of("CONNECTS") {
  241. for connect in connections {
  242. manual_connects.push(connect.parse()?);
  243. }
  244. }
  245. let connection_slots = if let Some(connection_slots) = app.value_of("CONNECT_SLOTS") {
  246. connection_slots.parse()?
  247. } else {
  248. 0
  249. };
  250. let log_path = Box::new(
  251. if let Some(log_path) = app.value_of("LOG_PATH") {
  252. std::path::Path::new(log_path)
  253. } else {
  254. std::path::Path::new("/tmp/darkfid.log")
  255. }
  256. .to_path_buf(),
  257. );
  258. Ok(ProgramOptions {
  259. network_settings: net::Settings {
  260. inbound: accept_addr.clone(),
  261. outbound_connections: connection_slots,
  262. connect_timeout_seconds: 10,
  263. channel_handshake_seconds: 2,
  264. channel_heartbeat_seconds: 10,
  265. external_addr: accept_addr.clone(),
  266. peers: manual_connects.clone(),
  267. seeds: seed_addrs.clone(),
  268. },
  269. accept_addr,
  270. seed_addrs,
  271. manual_connects,
  272. connection_slots,
  273. log_path,
  274. })
  275. }
  276. }
  277. fn main() -> Result<()> {
  278. use simplelog::*;
  279. let options = ProgramOptions::load()?;
  280. CombinedLogger::init(vec![
  281. TermLogger::new(LevelFilter::Debug, Config::default(), TerminalMode::Mixed).unwrap(),
  282. WriteLogger::new(
  283. LevelFilter::Debug,
  284. Config::default(),
  285. std::fs::File::create(options.log_path.as_path()).unwrap(),
  286. ),
  287. ])
  288. .unwrap();
  289. let ex = Arc::new(Executor::new());
  290. let (signal, shutdown) = async_channel::unbounded::<()>();
  291. let ex2 = ex.clone();
  292. let (_, result) = Parallel::new()
  293. // Run four executor threads.
  294. .each(0..3, |_| smol::future::block_on(ex.run(shutdown.recv())))
  295. // Run the main future on the current thread.
  296. .finish(|| {
  297. smol::future::block_on(async move {
  298. start(ex2, options).await?;
  299. drop(signal);
  300. Ok::<(), sapvi::Error>(())
  301. })
  302. });
  303. result
  304. }