protocol_address.rs 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. use std::sync::Arc;
  2. use async_trait::async_trait;
  3. use log::debug;
  4. use smol::Executor;
  5. use crate::{
  6. error::Result,
  7. net::{
  8. message,
  9. message_subscriber::MessageSubscription,
  10. protocol::{ProtocolBase, ProtocolBasePtr, ProtocolJobsManager, ProtocolJobsManagerPtr},
  11. ChannelPtr, HostsPtr, P2pPtr,
  12. },
  13. };
  14. /// Defines address and get-address messages.
  15. pub struct ProtocolAddress {
  16. channel: ChannelPtr,
  17. addrs_sub: MessageSubscription<message::AddrsMessage>,
  18. get_addrs_sub: MessageSubscription<message::GetAddrsMessage>,
  19. hosts: HostsPtr,
  20. jobsman: ProtocolJobsManagerPtr,
  21. }
  22. impl ProtocolAddress {
  23. /// Create a new address protocol. Makes an address and get-address
  24. /// subscription and adds them to the address protocol instance.
  25. pub async fn new(channel: ChannelPtr, p2p: P2pPtr) -> ProtocolBasePtr {
  26. let hosts = p2p.hosts();
  27. // Creates a subscription to address message.
  28. let addrs_sub = channel
  29. .clone()
  30. .subscribe_msg::<message::AddrsMessage>()
  31. .await
  32. .expect("Missing addrs dispatcher!");
  33. // Creates a subscription to get-address message.
  34. let get_addrs_sub = channel
  35. .clone()
  36. .subscribe_msg::<message::GetAddrsMessage>()
  37. .await
  38. .expect("Missing getaddrs dispatcher!");
  39. Arc::new(Self {
  40. channel: channel.clone(),
  41. addrs_sub,
  42. get_addrs_sub,
  43. hosts,
  44. jobsman: ProtocolJobsManager::new("ProtocolAddress", channel),
  45. })
  46. }
  47. /// Handles receiving the address message. Loops to continually recieve
  48. /// address messages on the address subsciption. Adds the recieved
  49. /// addresses to the list of hosts.
  50. async fn handle_receive_addrs(self: Arc<Self>) -> Result<()> {
  51. debug!(target: "net", "ProtocolAddress::handle_receive_addrs() [START]");
  52. loop {
  53. let addrs_msg = self.addrs_sub.receive().await?;
  54. debug!(
  55. target: "net",
  56. "ProtocolAddress::handle_receive_addrs() received {} addrs",
  57. addrs_msg.addrs.len()
  58. );
  59. for (i, addr) in addrs_msg.addrs.iter().enumerate() {
  60. debug!(" addr[{}]: {}", i, addr);
  61. }
  62. self.hosts.store(addrs_msg.addrs.clone()).await;
  63. }
  64. }
  65. /// Handles receiving the get-address message. Continually recieves
  66. /// get-address messages on the get-address subsciption. Then replies
  67. /// with an address message.
  68. async fn handle_receive_get_addrs(self: Arc<Self>) -> Result<()> {
  69. debug!(target: "net", "ProtocolAddress::handle_receive_get_addrs() [START]");
  70. loop {
  71. let _get_addrs = self.get_addrs_sub.receive().await?;
  72. debug!(target: "net", "ProtocolAddress::handle_receive_get_addrs() received GetAddrs message");
  73. // Loads the list of hosts.
  74. let addrs = self.hosts.load_all().await;
  75. debug!(
  76. target: "net",
  77. "ProtocolAddress::handle_receive_get_addrs() sending {} addrs",
  78. addrs.len()
  79. );
  80. // Creates an address messages containing host address.
  81. let addrs_msg = message::AddrsMessage { addrs };
  82. // Sends the address message across the channel.
  83. self.channel.clone().send(addrs_msg).await?;
  84. }
  85. }
  86. }
  87. #[async_trait]
  88. impl ProtocolBase for ProtocolAddress {
  89. /// Starts the address protocol. Runs receive address and get address
  90. /// protocols on the protocol task manager. Then sends get-address
  91. /// message.
  92. async fn start(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  93. debug!(target: "net", "ProtocolAddress::start() [START]");
  94. self.jobsman.clone().start(executor.clone());
  95. self.jobsman.clone().spawn(self.clone().handle_receive_addrs(), executor.clone()).await;
  96. self.jobsman.clone().spawn(self.clone().handle_receive_get_addrs(), executor).await;
  97. // Send get_address message.
  98. let get_addrs = message::GetAddrsMessage {};
  99. let _ = self.channel.clone().send(get_addrs).await;
  100. debug!(target: "net", "ProtocolAddress::start() [END]");
  101. Ok(())
  102. }
  103. fn name(&self) -> &'static str {
  104. "ProtocolAddress"
  105. }
  106. }