message.rs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. use futures::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
  2. use log::debug;
  3. use url::Url;
  4. use crate::{
  5. serial::{Decodable, Encodable, SerialDecodable, SerialEncodable, VarInt},
  6. Error, Result,
  7. };
  8. const MAGIC_BYTES: [u8; 4] = [0xd9, 0xef, 0xb6, 0x7d];
  9. /// Generic message template.
  10. pub trait Message: 'static + Encodable + Decodable + Send + Sync {
  11. fn name() -> &'static str;
  12. }
  13. /// Outbound keep-alive message.
  14. #[derive(SerialEncodable, SerialDecodable)]
  15. pub struct PingMessage {
  16. pub nonce: u32,
  17. }
  18. /// Inbound keep-alive message.
  19. #[derive(SerialEncodable, SerialDecodable)]
  20. pub struct PongMessage {
  21. pub nonce: u32,
  22. }
  23. /// Requests address of outbound connection.
  24. #[derive(SerialEncodable, SerialDecodable)]
  25. pub struct GetAddrsMessage {}
  26. /// Sends address information to inbound connection. Response to GetAddrs
  27. /// message.
  28. #[derive(SerialEncodable, SerialDecodable)]
  29. pub struct AddrsMessage {
  30. pub addrs: Vec<Url>,
  31. }
  32. /// Sends external address information to inbound connection.
  33. #[derive(SerialEncodable, SerialDecodable)]
  34. pub struct ExtAddrsMessage {
  35. pub ext_addrs: Vec<Url>,
  36. }
  37. /// Requests version information of outbound connection.
  38. #[derive(SerialEncodable, SerialDecodable)]
  39. pub struct VersionMessage {
  40. pub node_id: String,
  41. }
  42. /// Sends version information to inbound connection. Response to VersionMessage.
  43. #[derive(SerialEncodable, SerialDecodable)]
  44. pub struct VerackMessage {
  45. // app version
  46. pub app: String,
  47. }
  48. impl Message for PingMessage {
  49. fn name() -> &'static str {
  50. "ping"
  51. }
  52. }
  53. impl Message for PongMessage {
  54. fn name() -> &'static str {
  55. "pong"
  56. }
  57. }
  58. impl Message for GetAddrsMessage {
  59. fn name() -> &'static str {
  60. "getaddr"
  61. }
  62. }
  63. impl Message for AddrsMessage {
  64. fn name() -> &'static str {
  65. "addr"
  66. }
  67. }
  68. impl Message for ExtAddrsMessage {
  69. fn name() -> &'static str {
  70. "extaddr"
  71. }
  72. }
  73. impl Message for VersionMessage {
  74. fn name() -> &'static str {
  75. "version"
  76. }
  77. }
  78. impl Message for VerackMessage {
  79. fn name() -> &'static str {
  80. "verack"
  81. }
  82. }
  83. /// Packets are the base type read from the network. Converted to messages and
  84. /// passed to event loop.
  85. pub struct Packet {
  86. pub command: String,
  87. pub payload: Vec<u8>,
  88. }
  89. /// Reads and decodes an inbound payload.
  90. pub async fn read_packet<R: AsyncRead + Unpin + Sized>(stream: &mut R) -> Result<Packet> {
  91. // Packets have a 4 byte header of magic digits
  92. // This is used for network debugging
  93. let mut magic = [0u8; 4];
  94. debug!(target: "net", "reading magic...");
  95. stream.read_exact(&mut magic).await?;
  96. debug!(target: "net", "read magic {:?}", magic);
  97. if magic != MAGIC_BYTES {
  98. return Err(Error::MalformedPacket)
  99. }
  100. // The type of the message
  101. let command_len = VarInt::decode_async(stream).await?.0 as usize;
  102. let mut cmd = vec![0u8; command_len];
  103. if command_len > 0 {
  104. stream.read_exact(&mut cmd).await?;
  105. }
  106. let cmd = String::from_utf8(cmd)?;
  107. debug!(target: "net", "read command: {}", cmd);
  108. let payload_len = VarInt::decode_async(stream).await?.0 as usize;
  109. // The message-dependent data (see message types)
  110. let mut payload = vec![0u8; payload_len];
  111. if payload_len > 0 {
  112. stream.read_exact(&mut payload).await?;
  113. }
  114. debug!(target: "net", "read payload {} bytes", payload_len);
  115. Ok(Packet { command: cmd, payload })
  116. }
  117. /// Sends an outbound packet by writing data to TCP stream.
  118. pub async fn send_packet<W: AsyncWrite + Unpin + Sized>(
  119. stream: &mut W,
  120. packet: Packet,
  121. ) -> Result<()> {
  122. debug!(target: "net", "sending magic...");
  123. stream.write_all(&MAGIC_BYTES).await?;
  124. debug!(target: "net", "sent magic...");
  125. VarInt(packet.command.len() as u64).encode_async(stream).await?;
  126. assert!(!packet.command.is_empty());
  127. stream.write_all(packet.command.as_bytes()).await?;
  128. debug!(target: "net", "sent command: {}", packet.command);
  129. assert_eq!(std::mem::size_of::<usize>(), std::mem::size_of::<u64>());
  130. VarInt(packet.payload.len() as u64).encode_async(stream).await?;
  131. if !packet.payload.is_empty() {
  132. stream.write_all(&packet.payload).await?;
  133. }
  134. debug!(target: "net", "sent payload {} bytes", packet.payload.len() as u64);
  135. Ok(())
  136. }