protocol_version.rs 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2024 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use std::{
  19. sync::Arc,
  20. time::{Duration, UNIX_EPOCH},
  21. };
  22. use futures::future::join_all;
  23. use log::{debug, error};
  24. use smol::Executor;
  25. use super::super::{
  26. channel::ChannelPtr,
  27. message::{VerackMessage, VersionMessage},
  28. message_subscriber::MessageSubscription,
  29. settings::SettingsPtr,
  30. };
  31. use crate::{system::timeout::timeout, Error, Result};
  32. /// Implements the protocol version handshake sent out by nodes at
  33. /// the beginning of a connection.
  34. pub struct ProtocolVersion {
  35. channel: ChannelPtr,
  36. version_sub: MessageSubscription<VersionMessage>,
  37. verack_sub: MessageSubscription<VerackMessage>,
  38. settings: SettingsPtr,
  39. }
  40. impl ProtocolVersion {
  41. /// Create a new version protocol. Makes a version and version ack
  42. /// subscription, then adds them to a version protocol instance.
  43. pub async fn new(channel: ChannelPtr, settings: SettingsPtr) -> Arc<Self> {
  44. // Creates a version subscription
  45. let version_sub =
  46. channel.subscribe_msg::<VersionMessage>().await.expect("Missing version dispatcher!");
  47. // Creates a version acknowledgement subscription
  48. let verack_sub =
  49. channel.subscribe_msg::<VerackMessage>().await.expect("Missing verack dispatcher!");
  50. Arc::new(Self { channel, version_sub, verack_sub, settings })
  51. }
  52. /// Start version information exchange. Start the timer. Send version
  53. /// info and wait for version ack. Wait for version info and send
  54. /// version ack.
  55. pub async fn run(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  56. debug!(target: "net::protocol_version::run()", "START => address={}", self.channel.address());
  57. // Start timer
  58. // Send version, wait for verack
  59. // Wait for version, send verack
  60. // Fin.
  61. let result = timeout(
  62. Duration::from_secs(self.settings.channel_handshake_timeout),
  63. self.clone().exchange_versions(executor),
  64. )
  65. .await;
  66. if let Err(e) = result {
  67. error!(
  68. target: "net::protocol_version::run()",
  69. "[P2P] Version Exchange failed [{}]: {}",
  70. self.channel.address(), e,
  71. );
  72. self.channel.stop().await;
  73. return Err(Error::ChannelTimeout)
  74. }
  75. debug!(target: "net::protocol_version::run()", "END => address={}", self.channel.address());
  76. Ok(())
  77. }
  78. /// Send and receive version information
  79. async fn exchange_versions(self: Arc<Self>, executor: Arc<Executor<'_>>) -> Result<()> {
  80. debug!(
  81. target: "net::protocol_version::exchange_versions()",
  82. "START => address={}", self.channel.address(),
  83. );
  84. let send = executor.spawn(self.clone().send_version());
  85. let recv = executor.spawn(self.clone().recv_version());
  86. let rets = join_all(vec![send, recv]).await;
  87. if let Err(e) = &rets[0] {
  88. error!(
  89. target: "net::protocol_version::exchange_versions()",
  90. "send_version() failed: {}", e,
  91. );
  92. return Err(e.clone())
  93. }
  94. if let Err(e) = &rets[1] {
  95. error!(
  96. target: "net::protocol_version::exchange_versions()",
  97. "recv_version() failed: {}", e,
  98. );
  99. return Err(e.clone())
  100. }
  101. debug!(
  102. target: "net::protocol_version::exchange_versions()",
  103. "END => address={}", self.channel.address(),
  104. );
  105. Ok(())
  106. }
  107. /// Send version info and wait for version acknowledgement.
  108. /// Ensures that the app version is the same.
  109. async fn send_version(self: Arc<Self>) -> Result<()> {
  110. debug!(
  111. target: "net::protocol_version::send_version()",
  112. "START => address={}", self.channel.address(),
  113. );
  114. let version = VersionMessage {
  115. node_id: self.settings.node_id.clone(),
  116. version: self.settings.app_version.clone(),
  117. timestamp: UNIX_EPOCH.elapsed().unwrap().as_secs(),
  118. connect_recv_addr: self.channel.connect_addr().clone(),
  119. resolve_recv_addr: self.channel.resolve_addr().clone(),
  120. ext_send_addr: self.settings.external_addrs.clone(),
  121. /* TODO: `features` is a list of enabled features in the
  122. format Vec<(service, version)>. Protocols will add their
  123. own data to this field when they are attached.*/
  124. features: vec![],
  125. };
  126. self.channel.send(&version).await?;
  127. // Wait for verack
  128. let verack_msg = self.verack_sub.receive().await?;
  129. // Validate peer received version against our version.
  130. debug!(
  131. target: "net::protocol_version::send_version()",
  132. "App version: {}, Recv version: {}",
  133. self.settings.app_version, verack_msg.app_version,
  134. );
  135. // MAJOR and MINOR should be the same.
  136. if self.settings.app_version.major != verack_msg.app_version.major &&
  137. self.settings.app_version.minor != verack_msg.app_version.minor
  138. {
  139. error!(
  140. target: "net::protocol_version::send_version()",
  141. "[P2P] Version mismatch from {}. Disconnecting...",
  142. self.channel.address(),
  143. );
  144. self.channel.stop().await;
  145. return Err(Error::ChannelStopped)
  146. }
  147. // Versions are compatible
  148. debug!(
  149. target: "net::protocol_version::send_version()",
  150. "END => address={}", self.channel.address(),
  151. );
  152. Ok(())
  153. }
  154. /// Receive version info, check the message is okay and send verack
  155. /// with app version attached.
  156. async fn recv_version(self: Arc<Self>) -> Result<()> {
  157. debug!(
  158. target: "net::protocol_version::recv_version()",
  159. "START => address={}", self.channel.address(),
  160. );
  161. // Receive version message
  162. let version = self.version_sub.receive().await?;
  163. self.channel.set_version(version).await;
  164. // Send verack
  165. let verack = VerackMessage { app_version: self.settings.app_version.clone() };
  166. self.channel.send(&verack).await?;
  167. debug!(
  168. target: "net::protocol_version::recv_version()",
  169. "END => address={}", self.channel.address(),
  170. );
  171. Ok(())
  172. }
  173. }