|
56 | 56 | //! ```
|
57 | 57 | //!
|
58 | 58 | //! The protocol (`udp://`) in the URL is mandatory. The path (`\scrape`) is optional. It always uses `\scrape`.
|
59 |
| -use std::net::{Ipv4Addr, SocketAddr, ToSocketAddrs}; |
| 59 | +use std::net::{SocketAddr, ToSocketAddrs}; |
60 | 60 | use std::str::FromStr;
|
61 | 61 |
|
62 | 62 | use anyhow::Context;
|
63 |
| -use aquatic_udp_protocol::common::InfoHash; |
64 | 63 | use aquatic_udp_protocol::Response::{AnnounceIpv4, AnnounceIpv6, Scrape};
|
65 |
| -use aquatic_udp_protocol::{ |
66 |
| - AnnounceEvent, AnnounceRequest, ConnectRequest, ConnectionId, NumberOfBytes, NumberOfPeers, PeerId, PeerKey, Port, Response, |
67 |
| - ScrapeRequest, TransactionId, |
68 |
| -}; |
| 64 | +use aquatic_udp_protocol::{Port, TransactionId}; |
69 | 65 | use clap::{Parser, Subcommand};
|
70 | 66 | use log::{debug, LevelFilter};
|
71 | 67 | use serde_json::json;
|
72 | 68 | use url::Url;
|
73 | 69 |
|
| 70 | +use crate::console::clients::udp::checker; |
74 | 71 | use crate::shared::bit_torrent::info_hash::InfoHash as TorrustInfoHash;
|
75 |
| -use crate::shared::bit_torrent::tracker::udp::client::{UdpClient, UdpTrackerClient}; |
76 | 72 |
|
77 |
| -const ASSIGNED_BY_OS: i32 = 0; |
| 73 | +const ASSIGNED_BY_OS: u16 = 0; |
78 | 74 | const RANDOM_TRANSACTION_ID: i32 = -888_840_697;
|
79 | 75 |
|
80 | 76 | #[derive(Parser, Debug)]
|
@@ -110,41 +106,36 @@ pub async fn run() -> anyhow::Result<()> {
|
110 | 106 |
|
111 | 107 | let args = Args::parse();
|
112 | 108 |
|
113 |
| - // Configuration |
114 |
| - let local_port = ASSIGNED_BY_OS; |
115 |
| - let local_bind_to = format!("0.0.0.0:{local_port}"); |
116 |
| - let transaction_id = RANDOM_TRANSACTION_ID; |
117 |
| - |
118 |
| - // Bind to local port |
119 |
| - debug!("Binding to: {local_bind_to}"); |
120 |
| - let udp_client = UdpClient::bind(&local_bind_to).await; |
121 |
| - let bound_to = udp_client.socket.local_addr().context("binding local address")?; |
122 |
| - debug!("Bound to: {bound_to}"); |
123 |
| - |
124 |
| - let transaction_id = TransactionId(transaction_id); |
125 |
| - |
126 | 109 | let response = match args.command {
|
127 | 110 | Command::Announce {
|
128 | 111 | tracker_socket_addr,
|
129 | 112 | info_hash,
|
130 | 113 | } => {
|
131 |
| - let (connection_id, udp_tracker_client) = connect(&tracker_socket_addr, udp_client, transaction_id).await; |
132 |
| - |
133 |
| - send_announce_request( |
134 |
| - connection_id, |
135 |
| - transaction_id, |
136 |
| - info_hash, |
137 |
| - Port(bound_to.port()), |
138 |
| - &udp_tracker_client, |
139 |
| - ) |
140 |
| - .await |
| 114 | + let transaction_id = TransactionId(RANDOM_TRANSACTION_ID); |
| 115 | + |
| 116 | + let mut client = checker::Client::default(); |
| 117 | + |
| 118 | + let bound_to = client.bind_and_connect(ASSIGNED_BY_OS, &tracker_socket_addr).await?; |
| 119 | + |
| 120 | + let connection_id = client.send_connection_request(transaction_id).await?; |
| 121 | + |
| 122 | + client |
| 123 | + .send_announce_request(connection_id, transaction_id, info_hash, Port(bound_to.port())) |
| 124 | + .await? |
141 | 125 | }
|
142 | 126 | Command::Scrape {
|
143 | 127 | tracker_socket_addr,
|
144 | 128 | info_hashes,
|
145 | 129 | } => {
|
146 |
| - let (connection_id, udp_tracker_client) = connect(&tracker_socket_addr, udp_client, transaction_id).await; |
147 |
| - send_scrape_request(connection_id, transaction_id, info_hashes, &udp_tracker_client).await |
| 130 | + let transaction_id = TransactionId(RANDOM_TRANSACTION_ID); |
| 131 | + |
| 132 | + let mut client = checker::Client::default(); |
| 133 | + |
| 134 | + let _bound_to = client.bind_and_connect(ASSIGNED_BY_OS, &tracker_socket_addr).await?; |
| 135 | + |
| 136 | + let connection_id = client.send_connection_request(transaction_id).await?; |
| 137 | + |
| 138 | + client.send_scrape_request(connection_id, transaction_id, info_hashes).await? |
148 | 139 | }
|
149 | 140 | };
|
150 | 141 |
|
@@ -265,95 +256,3 @@ fn parse_info_hash(info_hash_str: &str) -> anyhow::Result<TorrustInfoHash> {
|
265 | 256 | TorrustInfoHash::from_str(info_hash_str)
|
266 | 257 | .map_err(|e| anyhow::Error::msg(format!("failed to parse info-hash `{info_hash_str}`: {e:?}")))
|
267 | 258 | }
|
268 |
| - |
269 |
| -async fn connect( |
270 |
| - tracker_socket_addr: &SocketAddr, |
271 |
| - udp_client: UdpClient, |
272 |
| - transaction_id: TransactionId, |
273 |
| -) -> (ConnectionId, UdpTrackerClient) { |
274 |
| - debug!("Connecting to tracker: udp://{tracker_socket_addr}"); |
275 |
| - |
276 |
| - udp_client.connect(&tracker_socket_addr.to_string()).await; |
277 |
| - |
278 |
| - let udp_tracker_client = UdpTrackerClient { udp_client }; |
279 |
| - |
280 |
| - let connection_id = send_connection_request(transaction_id, &udp_tracker_client).await; |
281 |
| - |
282 |
| - (connection_id, udp_tracker_client) |
283 |
| -} |
284 |
| - |
285 |
| -async fn send_connection_request(transaction_id: TransactionId, client: &UdpTrackerClient) -> ConnectionId { |
286 |
| - debug!("Sending connection request with transaction id: {transaction_id:#?}"); |
287 |
| - |
288 |
| - let connect_request = ConnectRequest { transaction_id }; |
289 |
| - |
290 |
| - client.send(connect_request.into()).await; |
291 |
| - |
292 |
| - let response = client.receive().await; |
293 |
| - |
294 |
| - debug!("connection request response:\n{response:#?}"); |
295 |
| - |
296 |
| - match response { |
297 |
| - Response::Connect(connect_response) => connect_response.connection_id, |
298 |
| - _ => panic!("error connecting to udp server. Unexpected response"), |
299 |
| - } |
300 |
| -} |
301 |
| - |
302 |
| -async fn send_announce_request( |
303 |
| - connection_id: ConnectionId, |
304 |
| - transaction_id: TransactionId, |
305 |
| - info_hash: TorrustInfoHash, |
306 |
| - port: Port, |
307 |
| - client: &UdpTrackerClient, |
308 |
| -) -> Response { |
309 |
| - debug!("Sending announce request with transaction id: {transaction_id:#?}"); |
310 |
| - |
311 |
| - let announce_request = AnnounceRequest { |
312 |
| - connection_id, |
313 |
| - transaction_id, |
314 |
| - info_hash: InfoHash(info_hash.bytes()), |
315 |
| - peer_id: PeerId(*b"-qB00000000000000001"), |
316 |
| - bytes_downloaded: NumberOfBytes(0i64), |
317 |
| - bytes_uploaded: NumberOfBytes(0i64), |
318 |
| - bytes_left: NumberOfBytes(0i64), |
319 |
| - event: AnnounceEvent::Started, |
320 |
| - ip_address: Some(Ipv4Addr::new(0, 0, 0, 0)), |
321 |
| - key: PeerKey(0u32), |
322 |
| - peers_wanted: NumberOfPeers(1i32), |
323 |
| - port, |
324 |
| - }; |
325 |
| - |
326 |
| - client.send(announce_request.into()).await; |
327 |
| - |
328 |
| - let response = client.receive().await; |
329 |
| - |
330 |
| - debug!("announce request response:\n{response:#?}"); |
331 |
| - |
332 |
| - response |
333 |
| -} |
334 |
| - |
335 |
| -async fn send_scrape_request( |
336 |
| - connection_id: ConnectionId, |
337 |
| - transaction_id: TransactionId, |
338 |
| - info_hashes: Vec<TorrustInfoHash>, |
339 |
| - client: &UdpTrackerClient, |
340 |
| -) -> Response { |
341 |
| - debug!("Sending scrape request with transaction id: {transaction_id:#?}"); |
342 |
| - |
343 |
| - let scrape_request = ScrapeRequest { |
344 |
| - connection_id, |
345 |
| - transaction_id, |
346 |
| - info_hashes: info_hashes |
347 |
| - .iter() |
348 |
| - .map(|torrust_info_hash| InfoHash(torrust_info_hash.bytes())) |
349 |
| - .collect(), |
350 |
| - }; |
351 |
| - |
352 |
| - client.send(scrape_request.into()).await; |
353 |
| - |
354 |
| - let response = client.receive().await; |
355 |
| - |
356 |
| - debug!("scrape request response:\n{response:#?}"); |
357 |
| - |
358 |
| - response |
359 |
| -} |
0 commit comments