From 801d91363a7570efef75d4aede39b961564963d1 Mon Sep 17 00:00:00 2001 From: Jose Celano Date: Tue, 7 May 2024 10:05:48 +0100 Subject: [PATCH] chore(deps): bump aquatic_udp_protocol from 0.8.0 to 0.9.0 --- Cargo.lock | 65 +++++++- Cargo.toml | 3 +- cSpell.json | 3 +- src/console/clients/checker/checks/udp.rs | 4 +- src/console/clients/udp/app.rs | 6 +- src/console/clients/udp/checker.rs | 19 +-- src/console/clients/udp/responses.rs | 38 ++--- src/servers/udp/connection_cookie.rs | 8 +- src/servers/udp/handlers.rs | 152 ++++++++++--------- src/servers/udp/peer_builder.rs | 17 ++- src/servers/udp/request.rs | 2 +- src/servers/udp/server.rs | 2 +- src/shared/bit_torrent/tracker/udp/client.rs | 7 +- tests/servers/udp/contract.rs | 35 ++--- 14 files changed, 225 insertions(+), 136 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 143ba1aa..b7f59266 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,14 +146,30 @@ version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" +[[package]] +name = "aquatic_peer_id" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0732a73df221dcb25713849c6ebaf57b85355f669716652a7466f688cc06f25" +dependencies = [ + "compact_str", + "hex", + "quickcheck", + "regex", + "serde", + "zerocopy", +] + [[package]] name = "aquatic_udp_protocol" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2919b480121f7d20d247524da62bad1b6b7928bc3f50898f624b5c592727341" +checksum = "0af90e5162f5fcbde33524128f08dc52a779f32512d5f8692eadd4b55c89389e" dependencies = [ + "aquatic_peer_id", "byteorder", "either", + "zerocopy", ] [[package]] @@ -698,6 +714,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" +[[package]] +name = "castaway" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a17ed5635fc8536268e5d4de1e22e81ac34419e5f052d4d51f4e01dcc263fcc" +dependencies = [ + "rustversion", +] + [[package]] name = "cc" version = "1.0.96" @@ -836,6 +861,19 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422" +[[package]] +name = "compact_str" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f86b9c4c00838774a6d902ef931eff7470720c51d90c2e32cfe15dc304737b3f" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "ryu", + "static_assertions", +] + [[package]] name = "concurrent-queue" version = "2.5.0" @@ -1176,6 +1214,16 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "env_logger" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a19187fea3ac7e84da7dacf48de0c45d63c6a76f9490dae389aead16c243fce3" +dependencies = [ + "log", + "regex", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -2826,6 +2874,17 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "quickcheck" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "588f6378e4dd99458b60ec275b4477add41ce4fa9f64dcba6f15adccb19b50d6" +dependencies = [ + "env_logger", + "log", + "rand", +] + [[package]] name = "quote" version = "1.0.36" @@ -3961,6 +4020,7 @@ dependencies = [ "tracing", "url", "uuid", + "zerocopy", ] [[package]] @@ -4579,6 +4639,7 @@ version = "0.7.33" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "087eca3c1eaf8c47b94d02790dd086cd594b912d2043d4de4bfdd466b3befb7c" dependencies = [ + "byteorder", "zerocopy-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 486c4123..63735450 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,7 @@ version = "3.0.0-alpha.12-develop" [dependencies] anyhow = "1" -aquatic_udp_protocol = "0.8" +aquatic_udp_protocol = "0" async-trait = "0" axum = { version = "0", features = ["macros"] } axum-client-ip = "0" @@ -76,6 +76,7 @@ trace = "0" tracing = "0" url = "2" uuid = { version = "1", features = ["v4"] } +zerocopy = "0.7.33" [package.metadata.cargo-machete] ignored = ["serde_bytes", "crossbeam-skiplist", "dashmap", "parking_lot"] diff --git a/cSpell.json b/cSpell.json index 24ef6b0a..2473e9c3 100644 --- a/cSpell.json +++ b/cSpell.json @@ -170,7 +170,8 @@ "Xtorrent", "Xunlei", "xxxxxxxxxxxxxxxxxxxxd", - "yyyyyyyyyyyyyyyyyyyyd" + "yyyyyyyyyyyyyyyyyyyyd", + "zerocopy" ], "enableFiletypes": [ "dockerfile", diff --git a/src/console/clients/checker/checks/udp.rs b/src/console/clients/checker/checks/udp.rs index 48f72edf..6458190d 100644 --- a/src/console/clients/checker/checks/udp.rs +++ b/src/console/clients/checker/checks/udp.rs @@ -27,7 +27,7 @@ pub async fn run(udp_trackers: &Vec, check_results: &mut Vec, check_results: &mut Vec anyhow::Result { - let transaction_id = TransactionId(RANDOM_TRANSACTION_ID); + let transaction_id = TransactionId::new(RANDOM_TRANSACTION_ID); let mut client = checker::Client::default(); @@ -151,12 +151,12 @@ async fn handle_announce(tracker_socket_addr: &SocketAddr, info_hash: &TorrustIn let connection_id = client.send_connection_request(transaction_id).await?; client - .send_announce_request(connection_id, transaction_id, *info_hash, Port(bound_to.port())) + .send_announce_request(connection_id, transaction_id, *info_hash, Port(bound_to.port().into())) .await } async fn handle_scrape(tracker_socket_addr: &SocketAddr, info_hashes: &[TorrustInfoHash]) -> anyhow::Result { - let transaction_id = TransactionId(RANDOM_TRANSACTION_ID); + let transaction_id = TransactionId::new(RANDOM_TRANSACTION_ID); let mut client = checker::Client::default(); diff --git a/src/console/clients/udp/checker.rs b/src/console/clients/udp/checker.rs index 9b2a9011..d5149204 100644 --- a/src/console/clients/udp/checker.rs +++ b/src/console/clients/udp/checker.rs @@ -3,8 +3,8 @@ use std::net::{Ipv4Addr, SocketAddr}; use anyhow::Context; use aquatic_udp_protocol::common::InfoHash; use aquatic_udp_protocol::{ - AnnounceEvent, AnnounceRequest, ConnectRequest, ConnectionId, NumberOfBytes, NumberOfPeers, PeerId, PeerKey, Port, Response, - ScrapeRequest, TransactionId, + AnnounceActionPlaceholder, AnnounceEvent, AnnounceRequest, ConnectRequest, ConnectionId, NumberOfBytes, NumberOfPeers, + PeerId, PeerKey, Port, Response, ScrapeRequest, TransactionId, }; use log::debug; use thiserror::Error; @@ -148,16 +148,17 @@ impl Client { let announce_request = AnnounceRequest { connection_id, + action_placeholder: AnnounceActionPlaceholder::default(), transaction_id, info_hash: InfoHash(info_hash.bytes()), peer_id: PeerId(*b"-qB00000000000000001"), - bytes_downloaded: NumberOfBytes(0i64), - bytes_uploaded: NumberOfBytes(0i64), - bytes_left: NumberOfBytes(0i64), - event: AnnounceEvent::Started, - ip_address: Some(Ipv4Addr::new(0, 0, 0, 0)), - key: PeerKey(0u32), - peers_wanted: NumberOfPeers(1i32), + bytes_downloaded: NumberOfBytes(0i64.into()), + bytes_uploaded: NumberOfBytes(0i64.into()), + bytes_left: NumberOfBytes(0i64.into()), + event: AnnounceEvent::Started.into(), + ip_address: Ipv4Addr::new(0, 0, 0, 0).into(), + key: PeerKey::new(0i32), + peers_wanted: NumberOfPeers(1i32.into()), port: client_port, }; diff --git a/src/console/clients/udp/responses.rs b/src/console/clients/udp/responses.rs index 2fbc38f5..8ea1a978 100644 --- a/src/console/clients/udp/responses.rs +++ b/src/console/clients/udp/responses.rs @@ -1,7 +1,7 @@ //! Aquatic responses are not serializable. These are the serializable wrappers. use std::net::{Ipv4Addr, Ipv6Addr}; -use aquatic_udp_protocol::{AnnounceResponse, ScrapeResponse}; +use aquatic_udp_protocol::{AnnounceResponse, Ipv4AddrBytes, Ipv6AddrBytes, ScrapeResponse}; use serde::Serialize; #[derive(Serialize)] @@ -13,33 +13,33 @@ pub struct AnnounceResponseDto { peers: Vec, } -impl From> for AnnounceResponseDto { - fn from(announce: AnnounceResponse) -> Self { +impl From> for AnnounceResponseDto { + fn from(announce: AnnounceResponse) -> Self { Self { - transaction_id: announce.transaction_id.0, - announce_interval: announce.announce_interval.0, - leechers: announce.leechers.0, - seeders: announce.seeders.0, + transaction_id: announce.fixed.transaction_id.0.into(), + announce_interval: announce.fixed.announce_interval.0.into(), + leechers: announce.fixed.leechers.0.into(), + seeders: announce.fixed.seeders.0.into(), peers: announce .peers .iter() - .map(|peer| format!("{}:{}", peer.ip_address, peer.port.0)) + .map(|peer| format!("{}:{}", Ipv4Addr::from(peer.ip_address), peer.port.0)) .collect::>(), } } } -impl From> for AnnounceResponseDto { - fn from(announce: AnnounceResponse) -> Self { +impl From> for AnnounceResponseDto { + fn from(announce: AnnounceResponse) -> Self { Self { - transaction_id: announce.transaction_id.0, - announce_interval: announce.announce_interval.0, - leechers: announce.leechers.0, - seeders: announce.seeders.0, + transaction_id: announce.fixed.transaction_id.0.into(), + announce_interval: announce.fixed.announce_interval.0.into(), + leechers: announce.fixed.leechers.0.into(), + seeders: announce.fixed.seeders.0.into(), peers: announce .peers .iter() - .map(|peer| format!("{}:{}", peer.ip_address, peer.port.0)) + .map(|peer| format!("{}:{}", Ipv6Addr::from(peer.ip_address), peer.port.0)) .collect::>(), } } @@ -54,14 +54,14 @@ pub struct ScrapeResponseDto { impl From for ScrapeResponseDto { fn from(scrape: ScrapeResponse) -> Self { Self { - transaction_id: scrape.transaction_id.0, + transaction_id: scrape.transaction_id.0.into(), torrent_stats: scrape .torrent_stats .iter() .map(|torrent_scrape_statistics| TorrentStats { - seeders: torrent_scrape_statistics.seeders.0, - completed: torrent_scrape_statistics.completed.0, - leechers: torrent_scrape_statistics.leechers.0, + seeders: torrent_scrape_statistics.seeders.0.into(), + completed: torrent_scrape_statistics.completed.0.into(), + leechers: torrent_scrape_statistics.leechers.0.into(), }) .collect::>(), } diff --git a/src/servers/udp/connection_cookie.rs b/src/servers/udp/connection_cookie.rs index 49ea6261..af3a2870 100644 --- a/src/servers/udp/connection_cookie.rs +++ b/src/servers/udp/connection_cookie.rs @@ -71,6 +71,8 @@ use std::panic::Location; use aquatic_udp_protocol::ConnectionId; use torrust_tracker_clock::time_extent::{Extent, TimeExtent}; +use zerocopy::network_endian::I64; +use zerocopy::AsBytes; use super::error::Error; @@ -83,13 +85,15 @@ pub const COOKIE_LIFETIME: TimeExtent = TimeExtent::from_sec(2, &60); /// Converts a connection ID into a connection cookie. #[must_use] pub fn from_connection_id(connection_id: &ConnectionId) -> Cookie { - connection_id.0.to_le_bytes() + let mut cookie = [0u8; 8]; + connection_id.write_to(&mut cookie); + cookie } /// Converts a connection cookie into a connection ID. #[must_use] pub fn into_connection_id(connection_cookie: &Cookie) -> ConnectionId { - ConnectionId(i64::from_le_bytes(*connection_cookie)) + ConnectionId(I64::new(i64::from_be_bytes(*connection_cookie))) } /// Generates a new connection cookie. diff --git a/src/servers/udp/handlers.rs b/src/servers/udp/handlers.rs index 122e666a..876f4c9f 100644 --- a/src/servers/udp/handlers.rs +++ b/src/servers/udp/handlers.rs @@ -1,19 +1,21 @@ //! Handlers for the UDP server. use std::fmt; -use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +use std::net::{IpAddr, SocketAddr}; use std::panic::Location; use std::sync::Arc; use std::time::Instant; use aquatic_udp_protocol::{ - AnnounceInterval, AnnounceRequest, AnnounceResponse, ConnectRequest, ConnectResponse, ErrorResponse, NumberOfDownloads, - NumberOfPeers, Port, Request, Response, ResponsePeer, ScrapeRequest, ScrapeResponse, TorrentScrapeStatistics, TransactionId, + AnnounceInterval, AnnounceRequest, AnnounceResponse, AnnounceResponseFixedData, ConnectRequest, ConnectResponse, + ErrorResponse, Ipv4AddrBytes, Ipv6AddrBytes, NumberOfDownloads, NumberOfPeers, Port, Request, Response, ResponsePeer, + ScrapeRequest, ScrapeResponse, TorrentScrapeStatistics, TransactionId, }; use log::debug; use tokio::net::UdpSocket; use torrust_tracker_located_error::DynError; use torrust_tracker_primitives::info_hash::InfoHash; use uuid::Uuid; +use zerocopy::network_endian::I32; use super::connection_cookie::{check, from_connection_id, into_connection_id, make}; use super::UdpRequest; @@ -41,7 +43,7 @@ pub(crate) async fn handle_packet(udp_request: UdpRequest, tracker: &Arc { - ip_address: ip, - port: Port(peer.peer_addr.port()), + Some(ResponsePeer:: { + ip_address: ip.into(), + port: Port(peer.peer_addr.port().into()), }) } else { None @@ -204,18 +208,20 @@ pub async fn handle_announce( Ok(Response::from(announce_response)) } else { let announce_response = AnnounceResponse { - transaction_id: wrapped_announce_request.announce_request.transaction_id, - announce_interval: AnnounceInterval(i64::from(tracker.get_announce_policy().interval) as i32), - leechers: NumberOfPeers(i64::from(response.stats.incomplete) as i32), - seeders: NumberOfPeers(i64::from(response.stats.complete) as i32), + fixed: AnnounceResponseFixedData { + transaction_id: wrapped_announce_request.announce_request.transaction_id, + announce_interval: AnnounceInterval(I32::new(i64::from(tracker.get_announce_policy().interval) as i32)), + leechers: NumberOfPeers(I32::new(i64::from(response.stats.incomplete) as i32)), + seeders: NumberOfPeers(I32::new(i64::from(response.stats.complete) as i32)), + }, peers: response .peers .iter() .filter_map(|peer| { if let IpAddr::V6(ip) = peer.peer_addr.ip() { - Some(ResponsePeer:: { - ip_address: ip, - port: Port(peer.peer_addr.port()), + Some(ResponsePeer:: { + ip_address: ip.into(), + port: Port(peer.peer_addr.port().into()), }) } else { None @@ -259,9 +265,9 @@ pub async fn handle_scrape(remote_addr: SocketAddr, request: &ScrapeRequest, tra #[allow(clippy::cast_possible_truncation)] let scrape_entry = { TorrentScrapeStatistics { - seeders: NumberOfPeers(i64::from(swarm_metadata.complete) as i32), - completed: NumberOfDownloads(i64::from(swarm_metadata.downloaded) as i32), - leechers: NumberOfPeers(i64::from(swarm_metadata.incomplete) as i32), + seeders: NumberOfPeers(I32::new(i64::from(swarm_metadata.complete) as i32)), + completed: NumberOfDownloads(I32::new(i64::from(swarm_metadata.downloaded) as i32)), + leechers: NumberOfPeers(I32::new(i64::from(swarm_metadata.incomplete) as i32)), } }; @@ -445,14 +451,14 @@ mod tests { fn sample_connect_request() -> ConnectRequest { ConnectRequest { - transaction_id: TransactionId(0i32), + transaction_id: TransactionId(0i32.into()), } } #[tokio::test] async fn a_connect_response_should_contain_the_same_transaction_id_as_the_connect_request() { let request = ConnectRequest { - transaction_id: TransactionId(0i32), + transaction_id: TransactionId(0i32.into()), }; let response = handle_connect(sample_ipv4_remote_addr(), &request, &public_tracker()) @@ -471,7 +477,7 @@ mod tests { #[tokio::test] async fn a_connect_response_should_contain_a_new_connection_id() { let request = ConnectRequest { - transaction_id: TransactionId(0i32), + transaction_id: TransactionId(0i32.into()), }; let response = handle_connect(sample_ipv4_remote_addr(), &request, &public_tracker()) @@ -529,10 +535,11 @@ mod tests { mod announce_request { use std::net::Ipv4Addr; + use std::num::NonZeroU16; use aquatic_udp_protocol::{ - AnnounceEvent, AnnounceRequest, ConnectionId, NumberOfBytes, NumberOfPeers, PeerId as AquaticPeerId, PeerKey, Port, - TransactionId, + AnnounceActionPlaceholder, AnnounceEvent, AnnounceRequest, ConnectionId, NumberOfBytes, NumberOfPeers, + PeerId as AquaticPeerId, PeerKey, Port, TransactionId, }; use crate::servers::udp::connection_cookie::{into_connection_id, make}; @@ -550,17 +557,18 @@ mod tests { let default_request = AnnounceRequest { connection_id: into_connection_id(&make(&sample_ipv4_remote_addr())), - transaction_id: TransactionId(0i32), + action_placeholder: AnnounceActionPlaceholder::default(), + transaction_id: TransactionId(0i32.into()), info_hash: info_hash_aquatic, peer_id: AquaticPeerId([255u8; 20]), - bytes_downloaded: NumberOfBytes(0i64), - bytes_uploaded: NumberOfBytes(0i64), - bytes_left: NumberOfBytes(0i64), - event: AnnounceEvent::Started, - ip_address: Some(client_ip), - key: PeerKey(0u32), - peers_wanted: NumberOfPeers(1i32), - port: Port(client_port), + bytes_downloaded: NumberOfBytes(0i64.into()), + bytes_uploaded: NumberOfBytes(0i64.into()), + bytes_left: NumberOfBytes(0i64.into()), + event: AnnounceEvent::Started.into(), + ip_address: client_ip.into(), + key: PeerKey::new(0i32), + peers_wanted: NumberOfPeers::new(1i32), + port: Port::new(NonZeroU16::new(client_port).expect("a non-zero client port")), }; AnnounceRequestBuilder { request: default_request, @@ -583,12 +591,12 @@ mod tests { } pub fn with_ip_address(mut self, ip_address: Ipv4Addr) -> Self { - self.request.ip_address = Some(ip_address); + self.request.ip_address = ip_address.into(); self } pub fn with_port(mut self, port: u16) -> Self { - self.request.port = Port(port); + self.request.port = Port(port.into()); self } @@ -600,23 +608,23 @@ mod tests { mod using_ipv4 { use std::future; - use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::Arc; use aquatic_udp_protocol::{ - AnnounceInterval, AnnounceResponse, InfoHash as AquaticInfoHash, NumberOfPeers, PeerId as AquaticPeerId, - Response, ResponsePeer, + AnnounceInterval, AnnounceResponse, InfoHash as AquaticInfoHash, Ipv4AddrBytes, Ipv6AddrBytes, NumberOfPeers, + PeerId as AquaticPeerId, Response, ResponsePeer, }; use mockall::predicate::eq; use torrust_tracker_primitives::peer; use crate::core::{self, statistics}; use crate::servers::udp::connection_cookie::{into_connection_id, make}; - use crate::servers::udp::handlers::handle_announce; use crate::servers::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::servers::udp::handlers::tests::{ public_tracker, sample_ipv4_socket_address, tracker_configuration, TorrentPeerBuilder, }; + use crate::servers::udp::handlers::{handle_announce, AnnounceResponseFixedData}; #[tokio::test] async fn an_announced_peer_should_be_added_to_the_tracker() { @@ -659,14 +667,16 @@ mod tests { let response = handle_announce(remote_addr, &request, &public_tracker()).await.unwrap(); - let empty_peer_vector: Vec> = vec![]; + let empty_peer_vector: Vec> = vec![]; assert_eq!( response, Response::from(AnnounceResponse { - transaction_id: request.transaction_id, - announce_interval: AnnounceInterval(120i32), - leechers: NumberOfPeers(0i32), - seeders: NumberOfPeers(1i32), + fixed: AnnounceResponseFixedData { + transaction_id: request.transaction_id, + announce_interval: AnnounceInterval(120i32.into()), + leechers: NumberOfPeers(0i32.into()), + seeders: NumberOfPeers(1i32.into()), + }, peers: empty_peer_vector }) ); @@ -739,7 +749,7 @@ mod tests { let response = announce_a_new_peer_using_ipv4(tracker.clone()).await; // The response should not contain the peer using IPV6 - let peers: Option>> = match response { + let peers: Option>> = match response { Response::AnnounceIpv6(announce_response) => Some(announce_response.peers), _ => None, }; @@ -820,23 +830,23 @@ mod tests { mod using_ipv6 { use std::future; - use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::sync::Arc; use aquatic_udp_protocol::{ - AnnounceInterval, AnnounceResponse, InfoHash as AquaticInfoHash, NumberOfPeers, PeerId as AquaticPeerId, - Response, ResponsePeer, + AnnounceInterval, AnnounceResponse, InfoHash as AquaticInfoHash, Ipv4AddrBytes, Ipv6AddrBytes, NumberOfPeers, + PeerId as AquaticPeerId, Response, ResponsePeer, }; use mockall::predicate::eq; use torrust_tracker_primitives::peer; use crate::core::{self, statistics}; use crate::servers::udp::connection_cookie::{into_connection_id, make}; - use crate::servers::udp::handlers::handle_announce; use crate::servers::udp::handlers::tests::announce_request::AnnounceRequestBuilder; use crate::servers::udp::handlers::tests::{ public_tracker, sample_ipv6_remote_addr, tracker_configuration, TorrentPeerBuilder, }; + use crate::servers::udp::handlers::{handle_announce, AnnounceResponseFixedData}; #[tokio::test] async fn an_announced_peer_should_be_added_to_the_tracker() { @@ -883,14 +893,16 @@ mod tests { let response = handle_announce(remote_addr, &request, &public_tracker()).await.unwrap(); - let empty_peer_vector: Vec> = vec![]; + let empty_peer_vector: Vec> = vec![]; assert_eq!( response, Response::from(AnnounceResponse { - transaction_id: request.transaction_id, - announce_interval: AnnounceInterval(120i32), - leechers: NumberOfPeers(0i32), - seeders: NumberOfPeers(1i32), + fixed: AnnounceResponseFixedData { + transaction_id: request.transaction_id, + announce_interval: AnnounceInterval(120i32.into()), + leechers: NumberOfPeers(0i32.into()), + seeders: NumberOfPeers(1i32.into()), + }, peers: empty_peer_vector }) ); @@ -966,7 +978,7 @@ mod tests { let response = announce_a_new_peer_using_ipv6(tracker.clone()).await; // The response should not contain the peer using IPV4 - let peers: Option>> = match response { + let peers: Option>> = match response { Response::AnnounceIpv4(announce_response) => Some(announce_response.peers), _ => None, }; @@ -1074,9 +1086,9 @@ mod tests { fn zeroed_torrent_statistics() -> TorrentScrapeStatistics { TorrentScrapeStatistics { - seeders: NumberOfPeers(0), - completed: NumberOfDownloads(0), - leechers: NumberOfPeers(0), + seeders: NumberOfPeers(0.into()), + completed: NumberOfDownloads(0.into()), + leechers: NumberOfPeers(0.into()), } } @@ -1089,7 +1101,7 @@ mod tests { let request = ScrapeRequest { connection_id: into_connection_id(&make(&remote_addr)), - transaction_id: TransactionId(0i32), + transaction_id: TransactionId(0i32.into()), info_hashes, }; @@ -1123,7 +1135,7 @@ mod tests { ScrapeRequest { connection_id: into_connection_id(&make(remote_addr)), - transaction_id: TransactionId(0i32), + transaction_id: TransactionId::new(0i32), info_hashes, } } @@ -1159,9 +1171,9 @@ mod tests { let torrent_stats = match_scrape_response(add_a_sample_seeder_and_scrape(tracker.clone()).await); let expected_torrent_stats = vec![TorrentScrapeStatistics { - seeders: NumberOfPeers(1), - completed: NumberOfDownloads(0), - leechers: NumberOfPeers(0), + seeders: NumberOfPeers(1.into()), + completed: NumberOfDownloads(0.into()), + leechers: NumberOfPeers(0.into()), }]; assert_eq!(torrent_stats.unwrap().torrent_stats, expected_torrent_stats); @@ -1232,9 +1244,9 @@ mod tests { let torrent_stats = match_scrape_response(handle_scrape(remote_addr, &request, &tracker).await.unwrap()).unwrap(); let expected_torrent_stats = vec![TorrentScrapeStatistics { - seeders: NumberOfPeers(1), - completed: NumberOfDownloads(0), - leechers: NumberOfPeers(0), + seeders: NumberOfPeers(1.into()), + completed: NumberOfDownloads(0.into()), + leechers: NumberOfPeers(0.into()), }]; assert_eq!(torrent_stats.torrent_stats, expected_torrent_stats); @@ -1265,7 +1277,7 @@ mod tests { ScrapeRequest { connection_id: into_connection_id(&make(remote_addr)), - transaction_id: TransactionId(0i32), + transaction_id: TransactionId(0i32.into()), info_hashes, } } diff --git a/src/servers/udp/peer_builder.rs b/src/servers/udp/peer_builder.rs index f7eb935a..104f42a7 100644 --- a/src/servers/udp/peer_builder.rs +++ b/src/servers/udp/peer_builder.rs @@ -18,13 +18,20 @@ use crate::CurrentClock; /// request. #[must_use] pub fn from_request(announce_wrapper: &AnnounceWrapper, peer_ip: &IpAddr) -> peer::Peer { + let announce_event = match aquatic_udp_protocol::AnnounceEvent::from(announce_wrapper.announce_request.event) { + aquatic_udp_protocol::AnnounceEvent::Started => AnnounceEvent::Started, + aquatic_udp_protocol::AnnounceEvent::Stopped => AnnounceEvent::Stopped, + aquatic_udp_protocol::AnnounceEvent::Completed => AnnounceEvent::Completed, + aquatic_udp_protocol::AnnounceEvent::None => AnnounceEvent::None, + }; + peer::Peer { peer_id: peer::Id(announce_wrapper.announce_request.peer_id.0), - peer_addr: SocketAddr::new(*peer_ip, announce_wrapper.announce_request.port.0), + peer_addr: SocketAddr::new(*peer_ip, announce_wrapper.announce_request.port.0.into()), updated: CurrentClock::now(), - uploaded: NumberOfBytes(announce_wrapper.announce_request.bytes_uploaded.0), - downloaded: NumberOfBytes(announce_wrapper.announce_request.bytes_downloaded.0), - left: NumberOfBytes(announce_wrapper.announce_request.bytes_left.0), - event: AnnounceEvent::from_i32(announce_wrapper.announce_request.event.to_i32()), + uploaded: NumberOfBytes(announce_wrapper.announce_request.bytes_uploaded.0.into()), + downloaded: NumberOfBytes(announce_wrapper.announce_request.bytes_downloaded.0.into()), + left: NumberOfBytes(announce_wrapper.announce_request.bytes_left.0.into()), + event: announce_event, } } diff --git a/src/servers/udp/request.rs b/src/servers/udp/request.rs index e172e03b..f95fec07 100644 --- a/src/servers/udp/request.rs +++ b/src/servers/udp/request.rs @@ -21,7 +21,7 @@ impl AnnounceWrapper { #[must_use] pub fn new(announce_request: &AnnounceRequest) -> Self { AnnounceWrapper { - announce_request: announce_request.clone(), + announce_request: *announce_request, info_hash: InfoHash(announce_request.info_hash.0), } } diff --git a/src/servers/udp/server.rs b/src/servers/udp/server.rs index 7086b6ab..dc1bccde 100644 --- a/src/servers/udp/server.rs +++ b/src/servers/udp/server.rs @@ -346,7 +346,7 @@ impl Udp { let buffer = vec![0u8; MAX_PACKET_SIZE]; let mut cursor = Cursor::new(buffer); - match response.write(&mut cursor) { + match response.write_bytes(&mut cursor) { Ok(()) => { #[allow(clippy::cast_possible_truncation)] let position = cursor.position() as usize; diff --git a/src/shared/bit_torrent/tracker/udp/client.rs b/src/shared/bit_torrent/tracker/udp/client.rs index 9af9571b..81209efb 100644 --- a/src/shared/bit_torrent/tracker/udp/client.rs +++ b/src/shared/bit_torrent/tracker/udp/client.rs @@ -9,6 +9,7 @@ use aquatic_udp_protocol::{ConnectRequest, Request, Response, TransactionId}; use log::debug; use tokio::net::UdpSocket; use tokio::time; +use zerocopy::network_endian::I32; use crate::shared::bit_torrent::tracker::udp::{source_address, MAX_PACKET_SIZE}; @@ -160,7 +161,7 @@ impl UdpTrackerClient { let request_buffer = vec![0u8; MAX_PACKET_SIZE]; let mut cursor = Cursor::new(request_buffer); - let request_data_result = match request.write(&mut cursor) { + let request_data_result = match request.write_bytes(&mut cursor) { Ok(()) => { #[allow(clippy::cast_possible_truncation)] let position = cursor.position() as usize; @@ -186,7 +187,7 @@ impl UdpTrackerClient { debug!(target: "UDP tracker client", "received {payload_size} bytes. Response {response_buffer:?}"); - let response = Response::from_bytes(&response_buffer[..payload_size], true)?; + let response = Response::parse_bytes(&response_buffer[..payload_size], true)?; Ok(response) } @@ -218,7 +219,7 @@ pub async fn check(binding: &SocketAddr) -> Result { match new_udp_tracker_client_connected(binding.to_string().as_str()).await { Ok(client) => { let connect_request = ConnectRequest { - transaction_id: TransactionId(123), + transaction_id: TransactionId(I32::new(123)), }; // client.send() return usize, but doesn't use here diff --git a/tests/servers/udp/contract.rs b/tests/servers/udp/contract.rs index 56e400f8..7abd6092 100644 --- a/tests/servers/udp/contract.rs +++ b/tests/servers/udp/contract.rs @@ -60,7 +60,7 @@ async fn should_return_a_bad_request_response_when_the_client_sends_an_empty_req Err(err) => panic!("{err}"), }; - let response = Response::from_bytes(&buffer, true).unwrap(); + let response = Response::parse_bytes(&buffer, true).unwrap(); assert!(is_error_response(&response, "bad request")); @@ -85,7 +85,7 @@ mod receiving_a_connection_request { }; let connect_request = ConnectRequest { - transaction_id: TransactionId(123), + transaction_id: TransactionId::new(123), }; match client.send(connect_request.into()).await { @@ -98,7 +98,7 @@ mod receiving_a_connection_request { Err(err) => panic!("{err}"), }; - assert!(is_connect_response(&response, TransactionId(123))); + assert!(is_connect_response(&response, TransactionId::new(123))); env.stop().await; } @@ -108,8 +108,8 @@ mod receiving_an_announce_request { use std::net::Ipv4Addr; use aquatic_udp_protocol::{ - AnnounceEvent, AnnounceRequest, ConnectionId, InfoHash, NumberOfBytes, NumberOfPeers, PeerId, PeerKey, Port, - TransactionId, + AnnounceActionPlaceholder, AnnounceEvent, AnnounceRequest, ConnectionId, InfoHash, NumberOfBytes, NumberOfPeers, PeerId, + PeerKey, Port, TransactionId, }; use torrust_tracker::shared::bit_torrent::tracker::udp::client::new_udp_tracker_client_connected; use torrust_tracker_test_helpers::configuration; @@ -127,23 +127,24 @@ mod receiving_an_announce_request { Err(err) => panic!("{err}"), }; - let connection_id = send_connection_request(TransactionId(123), &client).await; + let connection_id = send_connection_request(TransactionId::new(123), &client).await; // Send announce request let announce_request = AnnounceRequest { connection_id: ConnectionId(connection_id.0), - transaction_id: TransactionId(123i32), + action_placeholder: AnnounceActionPlaceholder::default(), + transaction_id: TransactionId::new(123i32), info_hash: InfoHash([0u8; 20]), peer_id: PeerId([255u8; 20]), - bytes_downloaded: NumberOfBytes(0i64), - bytes_uploaded: NumberOfBytes(0i64), - bytes_left: NumberOfBytes(0i64), - event: AnnounceEvent::Started, - ip_address: Some(Ipv4Addr::new(0, 0, 0, 0)), - key: PeerKey(0u32), - peers_wanted: NumberOfPeers(1i32), - port: Port(client.udp_client.socket.local_addr().unwrap().port()), + bytes_downloaded: NumberOfBytes(0i64.into()), + bytes_uploaded: NumberOfBytes(0i64.into()), + bytes_left: NumberOfBytes(0i64.into()), + event: AnnounceEvent::Started.into(), + ip_address: Ipv4Addr::new(0, 0, 0, 0).into(), + key: PeerKey::new(0i32), + peers_wanted: NumberOfPeers(1i32.into()), + port: Port(client.udp_client.socket.local_addr().unwrap().port().into()), }; match client.send(announce_request.into()).await { @@ -182,7 +183,7 @@ mod receiving_an_scrape_request { Err(err) => panic!("{err}"), }; - let connection_id = send_connection_request(TransactionId(123), &client).await; + let connection_id = send_connection_request(TransactionId::new(123), &client).await; // Send scrape request @@ -192,7 +193,7 @@ mod receiving_an_scrape_request { let scrape_request = ScrapeRequest { connection_id: ConnectionId(connection_id.0), - transaction_id: TransactionId(123i32), + transaction_id: TransactionId::new(123i32), info_hashes, };