dfi.rs 10 KB

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