inbound_session.rs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. use async_std::sync::{Arc, Mutex, Weak};
  2. use async_executor::Executor;
  3. use async_trait::async_trait;
  4. use fxhash::FxHashMap;
  5. use log::{error, info};
  6. use serde_json::json;
  7. use url::Url;
  8. use crate::{
  9. system::{StoppableTask, StoppableTaskPtr},
  10. Error, Result,
  11. };
  12. use super::{
  13. super::{Acceptor, AcceptorPtr, ChannelPtr, P2p},
  14. Session, SessionBitflag, SESSION_INBOUND,
  15. };
  16. struct InboundInfo {
  17. channel: ChannelPtr,
  18. }
  19. impl InboundInfo {
  20. async fn get_info(&self) -> serde_json::Value {
  21. self.channel.get_info().await
  22. }
  23. }
  24. /// Defines inbound connections session.
  25. pub struct InboundSession {
  26. p2p: Weak<P2p>,
  27. acceptor: AcceptorPtr,
  28. accept_task: StoppableTaskPtr,
  29. connect_infos: Mutex<FxHashMap<Url, InboundInfo>>,
  30. }
  31. impl InboundSession {
  32. /// Create a new inbound session.
  33. pub fn new(p2p: Weak<P2p>) -> Arc<Self> {
  34. let acceptor = Acceptor::new();
  35. Arc::new(Self {
  36. p2p,
  37. acceptor,
  38. accept_task: StoppableTask::new(),
  39. connect_infos: Mutex::new(FxHashMap::default()),
  40. })
  41. }
  42. /// Starts the inbound session. Begins by accepting connections and fails if
  43. /// the address is not configured. Then runs the channel subscription
  44. /// loop.
  45. pub async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  46. match self.p2p().settings().inbound.as_ref() {
  47. Some(accept_addr) => {
  48. self.clone().start_accept_session(accept_addr.clone(), executor.clone()).await?;
  49. }
  50. None => {
  51. info!(target: "net", "Not configured for accepting incoming connections.");
  52. return Ok(())
  53. }
  54. }
  55. self.accept_task.clone().start(
  56. self.clone().channel_sub_loop(executor.clone()),
  57. // Ignore stop handler
  58. |_| async {},
  59. Error::NetworkServiceStopped,
  60. executor,
  61. );
  62. Ok(())
  63. }
  64. /// Stops the inbound session.
  65. pub async fn stop(&self) {
  66. self.acceptor.stop().await;
  67. self.accept_task.stop().await;
  68. }
  69. /// Start accepting connections for inbound session.
  70. async fn start_accept_session(
  71. self: Arc<Self>,
  72. accept_addr: Url,
  73. executor: Arc<Executor<'_>>,
  74. ) -> Result<()> {
  75. info!(target: "net", "Starting inbound session on {}", accept_addr);
  76. let result = self.acceptor.clone().start(accept_addr, executor).await;
  77. if let Err(err) = result.clone() {
  78. error!(target: "net", "Error starting listener: {}", err);
  79. }
  80. result
  81. }
  82. /// Wait for all new channels created by the acceptor and call
  83. /// setup_channel() on them.
  84. async fn channel_sub_loop(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  85. let channel_sub = self.acceptor.clone().subscribe().await;
  86. loop {
  87. let channel = channel_sub.receive().await?;
  88. // Spawn a detached task to process the channel
  89. // This will just perform the channel setup then exit.
  90. executor.spawn(self.clone().setup_channel(channel, executor.clone())).detach();
  91. }
  92. }
  93. /// Registers the channel. First performs a network handshake and starts the
  94. /// channel. Then starts sending keep-alive and address messages across the
  95. /// channel.
  96. async fn setup_channel(
  97. self: Arc<Self>,
  98. channel: ChannelPtr,
  99. executor: Arc<Executor<'_>>,
  100. ) -> Result<()> {
  101. info!(target: "net", "Connected inbound [{}]", channel.address());
  102. self.clone().register_channel(channel.clone(), executor.clone()).await?;
  103. self.manage_channel_for_get_info(channel).await;
  104. Ok(())
  105. }
  106. async fn manage_channel_for_get_info(&self, channel: ChannelPtr) {
  107. let key = channel.address();
  108. self.connect_infos
  109. .lock()
  110. .await
  111. .insert(key.clone(), InboundInfo { channel: channel.clone() });
  112. let stop_sub = channel.subscribe_stop().await;
  113. if stop_sub.is_ok() {
  114. stop_sub.unwrap().receive().await;
  115. }
  116. self.connect_infos.lock().await.remove(&key);
  117. }
  118. }
  119. #[async_trait]
  120. impl Session for InboundSession {
  121. async fn get_info(&self) -> serde_json::Value {
  122. let mut infos = FxHashMap::default();
  123. match self.p2p().settings().inbound.as_ref() {
  124. Some(accept_addr) => {
  125. for (addr, info) in self.connect_infos.lock().await.iter() {
  126. let json_addr = json!({ "accept_addr": accept_addr });
  127. let info = vec![json_addr, info.get_info().await];
  128. infos.insert(addr.to_string(), info);
  129. }
  130. }
  131. None => {}
  132. }
  133. json!({
  134. "connected": infos,
  135. })
  136. }
  137. fn p2p(&self) -> Arc<P2p> {
  138. self.p2p.upgrade().unwrap()
  139. }
  140. fn selector_id(&self) -> SessionBitflag {
  141. SESSION_INBOUND
  142. }
  143. }