diff --git a/packages/udp-tracker-core/src/statistics/event/mod.rs b/packages/udp-tracker-core/src/statistics/event/mod.rs index 05de5d118..216562506 100644 --- a/packages/udp-tracker-core/src/statistics/event/mod.rs +++ b/packages/udp-tracker-core/src/statistics/event/mod.rs @@ -30,10 +30,12 @@ impl ConnectionContext { } } + #[must_use] pub fn client_socket_addr(&self) -> SocketAddr { self.client_socket_addr } + #[must_use] pub fn server_socket_addr(&self) -> SocketAddr { self.server_socket_addr } diff --git a/packages/udp-tracker-server/src/handlers/announce.rs b/packages/udp-tracker-server/src/handlers/announce.rs index a0aabb765..5cc3cf3c8 100644 --- a/packages/udp-tracker-server/src/handlers/announce.rs +++ b/packages/udp-tracker-server/src/handlers/announce.rs @@ -16,7 +16,7 @@ use zerocopy::network_endian::I32; use crate::error::Error; use crate::statistics as server_statistics; -use crate::statistics::event::UdpResponseKind; +use crate::statistics::event::{ConnectionContext, UdpRequestKind}; /// It handles the `Announce` request. /// @@ -32,7 +32,7 @@ pub async fn handle_announce( core_config: &Arc, opt_udp_server_stats_event_sender: &Arc>>, cookie_valid_range: Range, -) -> Result { +) -> Result { tracing::Span::current() .record("transaction_id", request.transaction_id.0.to_string()) .record("connection_id", request.connection_id.0.to_string()) @@ -41,28 +41,18 @@ pub async fn handle_announce( tracing::trace!("handle announce"); if let Some(udp_server_stats_event_sender) = opt_udp_server_stats_event_sender.as_deref() { - match client_socket_addr.ip() { - IpAddr::V4(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp4Request { - kind: UdpResponseKind::Announce, - }) - .await; - } - IpAddr::V6(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp6Request { - kind: UdpResponseKind::Announce, - }) - .await; - } - } + udp_server_stats_event_sender + .send_event(server_statistics::event::Event::UdpRequestAccepted { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Announce, + }) + .await; } let announce_data = announce_service .handle_announce(client_socket_addr, server_socket_addr, request, cookie_valid_range) .await - .map_err(|e| (e.into(), request.transaction_id))?; + .map_err(|e| (e.into(), request.transaction_id, UdpRequestKind::Announce))?; Ok(build_response(client_socket_addr, request, core_config, &announce_data)) } @@ -226,7 +216,7 @@ mod tests { TorrentPeerBuilder, }; use crate::statistics as server_statistics; - use crate::statistics::event::UdpResponseKind; + use crate::statistics::event::UdpRequestKind; #[tokio::test] async fn an_announced_peer_should_be_added_to_the_tracker() { @@ -429,11 +419,15 @@ mod tests { #[tokio::test] async fn should_send_the_upd4_announce_event() { + let client_socket_addr = sample_ipv4_socket_address(); + let server_socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969); + let mut udp_server_stats_event_sender_mock = MockUdpServerStatsEventSender::new(); udp_server_stats_event_sender_mock .expect_send_event() - .with(eq(server_statistics::event::Event::Udp4Request { - kind: UdpResponseKind::Announce, + .with(eq(server_statistics::event::Event::UdpRequestAccepted { + context: server_statistics::event::ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Announce, })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); @@ -443,9 +437,6 @@ mod tests { let (core_tracker_services, core_udp_tracker_services, _server_udp_tracker_services) = initialize_core_tracker_services_for_default_tracker_configuration(); - let client_socket_addr = sample_ipv4_socket_address(); - let server_socket_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969); - handle_announce( &core_udp_tracker_services.announce_service, client_socket_addr, @@ -549,7 +540,7 @@ mod tests { sample_issue_time, MockUdpServerStatsEventSender, TorrentPeerBuilder, }; use crate::statistics as server_statistics; - use crate::statistics::event::UdpResponseKind; + use crate::statistics::event::UdpRequestKind; #[tokio::test] async fn an_announced_peer_should_be_added_to_the_tracker() { @@ -771,11 +762,15 @@ mod tests { #[tokio::test] async fn should_send_the_upd6_announce_event() { + let client_socket_addr = sample_ipv6_remote_addr(); + let server_socket_addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969); + let mut udp_server_stats_event_sender_mock = MockUdpServerStatsEventSender::new(); udp_server_stats_event_sender_mock .expect_send_event() - .with(eq(server_statistics::event::Event::Udp6Request { - kind: UdpResponseKind::Announce, + .with(eq(server_statistics::event::Event::UdpRequestAccepted { + context: server_statistics::event::ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Announce, })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); @@ -785,9 +780,6 @@ mod tests { let (core_tracker_services, core_udp_tracker_services, _server_udp_tracker_services) = initialize_core_tracker_services_for_default_tracker_configuration(); - let client_socket_addr = sample_ipv6_remote_addr(); - let server_socket_addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969); - let announce_request = AnnounceRequestBuilder::default() .with_connection_id(make(gen_remote_fingerprint(&client_socket_addr), sample_issue_time()).unwrap()) .into(); @@ -819,7 +811,6 @@ mod tests { use bittorrent_tracker_core::whitelist::repository::in_memory::InMemoryWhitelist; use bittorrent_udp_tracker_core::connection_cookie::{gen_remote_fingerprint, make}; use bittorrent_udp_tracker_core::services::announce::AnnounceService; - use bittorrent_udp_tracker_core::statistics::event::ConnectionContext; use bittorrent_udp_tracker_core::{self, statistics as core_statistics}; use mockall::predicate::eq; @@ -830,7 +821,7 @@ mod tests { TrackerConfigurationBuilder, }; use crate::statistics as server_statistics; - use crate::statistics::event::UdpResponseKind; + use crate::statistics::event::UdpRequestKind; #[tokio::test] async fn the_peer_ip_should_be_changed_to_the_external_ip_in_the_tracker_configuration() { @@ -860,7 +851,7 @@ mod tests { udp_core_stats_event_sender_mock .expect_send_event() .with(eq(core_statistics::event::Event::UdpAnnounce { - context: ConnectionContext::new(client_socket_addr, server_socket_addr), + context: core_statistics::event::ConnectionContext::new(client_socket_addr, server_socket_addr), })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); @@ -870,8 +861,9 @@ mod tests { let mut udp_server_stats_event_sender_mock = MockUdpServerStatsEventSender::new(); udp_server_stats_event_sender_mock .expect_send_event() - .with(eq(server_statistics::event::Event::Udp6Request { - kind: UdpResponseKind::Announce, + .with(eq(server_statistics::event::Event::UdpRequestAccepted { + context: server_statistics::event::ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Announce, })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); diff --git a/packages/udp-tracker-server/src/handlers/connect.rs b/packages/udp-tracker-server/src/handlers/connect.rs index bac3d7961..c38eb56e5 100644 --- a/packages/udp-tracker-server/src/handlers/connect.rs +++ b/packages/udp-tracker-server/src/handlers/connect.rs @@ -1,5 +1,5 @@ //! UDP tracker connect handler. -use std::net::{IpAddr, SocketAddr}; +use std::net::SocketAddr; use std::sync::Arc; use aquatic_udp_protocol::{ConnectRequest, ConnectResponse, ConnectionId, Response}; @@ -7,13 +7,13 @@ use bittorrent_udp_tracker_core::services::connect::ConnectService; use tracing::{instrument, Level}; use crate::statistics as server_statistics; -use crate::statistics::event::UdpResponseKind; +use crate::statistics::event::{ConnectionContext, UdpRequestKind}; /// It handles the `Connect` request. #[instrument(fields(transaction_id), skip(connect_service, opt_udp_server_stats_event_sender), ret(level = Level::TRACE))] pub async fn handle_connect( - remote_addr: SocketAddr, - server_addr: SocketAddr, + client_socket_addr: SocketAddr, + server_socket_addr: SocketAddr, request: &ConnectRequest, connect_service: &Arc, opt_udp_server_stats_event_sender: &Arc>>, @@ -23,26 +23,16 @@ pub async fn handle_connect( tracing::trace!("handle connect"); if let Some(udp_server_stats_event_sender) = opt_udp_server_stats_event_sender.as_deref() { - match remote_addr.ip() { - IpAddr::V4(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp4Request { - kind: UdpResponseKind::Connect, - }) - .await; - } - IpAddr::V6(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp6Request { - kind: UdpResponseKind::Connect, - }) - .await; - } - } + udp_server_stats_event_sender + .send_event(server_statistics::event::Event::UdpRequestAccepted { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Connect, + }) + .await; } let connection_id = connect_service - .handle_connect(remote_addr, server_addr, cookie_issue_time) + .handle_connect(client_socket_addr, server_socket_addr, cookie_issue_time) .await; build_response(*request, connection_id) @@ -70,7 +60,6 @@ mod tests { use bittorrent_udp_tracker_core::connection_cookie::make; use bittorrent_udp_tracker_core::services::connect::ConnectService; use bittorrent_udp_tracker_core::statistics as core_statistics; - use bittorrent_udp_tracker_core::statistics::event::ConnectionContext; use mockall::predicate::eq; use crate::handlers::handle_connect; @@ -79,7 +68,7 @@ mod tests { sample_ipv6_remote_addr_fingerprint, sample_issue_time, MockUdpCoreStatsEventSender, MockUdpServerStatsEventSender, }; use crate::statistics as server_statistics; - use crate::statistics::event::UdpResponseKind; + use crate::statistics::event::UdpRequestKind; fn sample_connect_request() -> ConnectRequest { ConnectRequest { @@ -214,8 +203,9 @@ mod tests { let mut udp_server_stats_event_sender_mock = MockUdpServerStatsEventSender::new(); udp_server_stats_event_sender_mock .expect_send_event() - .with(eq(server_statistics::event::Event::Udp4Request { - kind: UdpResponseKind::Connect, + .with(eq(server_statistics::event::Event::UdpRequestAccepted { + context: server_statistics::event::ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Connect, })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); @@ -244,7 +234,7 @@ mod tests { udp_core_stats_event_sender_mock .expect_send_event() .with(eq(core_statistics::event::Event::UdpConnect { - context: ConnectionContext::new(client_socket_addr, server_socket_addr), + context: core_statistics::event::ConnectionContext::new(client_socket_addr, server_socket_addr), })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); @@ -254,8 +244,9 @@ mod tests { let mut udp_server_stats_event_sender_mock = MockUdpServerStatsEventSender::new(); udp_server_stats_event_sender_mock .expect_send_event() - .with(eq(server_statistics::event::Event::Udp6Request { - kind: UdpResponseKind::Connect, + .with(eq(server_statistics::event::Event::UdpRequestAccepted { + context: server_statistics::event::ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Connect, })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); diff --git a/packages/udp-tracker-server/src/handlers/error.rs b/packages/udp-tracker-server/src/handlers/error.rs index e4bd382da..d1ffe2fd4 100644 --- a/packages/udp-tracker-server/src/handlers/error.rs +++ b/packages/udp-tracker-server/src/handlers/error.rs @@ -12,12 +12,14 @@ use zerocopy::network_endian::I32; use crate::error::Error; use crate::statistics as server_statistics; +use crate::statistics::event::{ConnectionContext, UdpRequestKind}; #[allow(clippy::too_many_arguments)] #[instrument(fields(transaction_id), skip(opt_udp_server_stats_event_sender), ret(level = Level::TRACE))] pub async fn handle_error( - remote_addr: SocketAddr, - local_addr: SocketAddr, + req_kind: Option, + client_socket_addr: SocketAddr, + server_socket_addr: SocketAddr, request_id: Uuid, opt_udp_server_stats_event_sender: &Arc>>, cookie_valid_range: Range, @@ -29,10 +31,10 @@ pub async fn handle_error( match transaction_id { Some(transaction_id) => { let transaction_id = transaction_id.0.to_string(); - tracing::error!(target: UDP_TRACKER_LOG_TARGET, error = %e, %remote_addr, %local_addr, %request_id, %transaction_id, "response error"); + tracing::error!(target: UDP_TRACKER_LOG_TARGET, error = %e, %client_socket_addr, %server_socket_addr, %request_id, %transaction_id, "response error"); } None => { - tracing::error!(target: UDP_TRACKER_LOG_TARGET, error = %e, %remote_addr, %local_addr, %request_id, "response error"); + tracing::error!(target: UDP_TRACKER_LOG_TARGET, error = %e, %client_socket_addr, %server_socket_addr, %request_id, "response error"); } } @@ -43,7 +45,7 @@ pub async fn handle_error( transaction_id, err, } => { - if let Err(e) = check(connection_id, gen_remote_fingerprint(&remote_addr), cookie_valid_range) { + if let Err(e) = check(connection_id, gen_remote_fingerprint(&client_socket_addr), cookie_valid_range) { (e.to_string(), Some(*transaction_id)) } else { ((*err).to_string(), Some(*transaction_id)) @@ -57,18 +59,11 @@ pub async fn handle_error( if e.1.is_some() { if let Some(udp_server_stats_event_sender) = opt_udp_server_stats_event_sender.as_deref() { - match remote_addr { - SocketAddr::V4(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp4Error) - .await; - } - SocketAddr::V6(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp6Error) - .await; - } - } + udp_server_stats_event_sender + .send_event(server_statistics::event::Event::UdpError { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + }) + .await; } } diff --git a/packages/udp-tracker-server/src/handlers/mod.rs b/packages/udp-tracker-server/src/handlers/mod.rs index 162af3020..e346d1953 100644 --- a/packages/udp-tracker-server/src/handlers/mod.rs +++ b/packages/udp-tracker-server/src/handlers/mod.rs @@ -24,6 +24,7 @@ use uuid::Uuid; use super::RawRequest; use crate::container::UdpTrackerServerContainer; use crate::error::Error; +use crate::statistics::event::UdpRequestKind; use crate::CurrentClock; #[derive(Debug, Clone, PartialEq)] @@ -60,7 +61,7 @@ pub(crate) async fn handle_packet( udp_tracker_server_container: Arc, server_socket_addr: SocketAddr, cookie_time_values: CookieTimeValues, -) -> Response { +) -> (Response, Option) { let request_id = Uuid::new_v4(); tracing::Span::current().record("request_id", request_id.to_string()); @@ -68,7 +69,7 @@ pub(crate) async fn handle_packet( let start_time = Instant::now(); - let response = + let (response, opt_req_kind) = match Request::parse_bytes(&udp_request.payload[..udp_request.payload.len()], MAX_SCRAPE_TORRENTS).map_err(Error::from) { Ok(request) => match handle_request( request, @@ -80,8 +81,8 @@ pub(crate) async fn handle_packet( ) .await { - Ok(response) => return response, - Err((error, transaction_id)) => { + Ok((response, req_kid)) => return (response, Some(req_kid)), + Err((error, transaction_id, req_kind)) => { if let Error::UdpAnnounceError { source: UdpAnnounceError::ConnectionCookieError { .. }, } = error @@ -91,7 +92,8 @@ pub(crate) async fn handle_packet( ban_service.increase_counter(&udp_request.from.ip()); } - handle_error( + let response = handle_error( + Some(req_kind.clone()), udp_request.from, server_socket_addr, request_id, @@ -100,11 +102,14 @@ pub(crate) async fn handle_packet( &error, Some(transaction_id), ) - .await + .await; + + (response, Some(req_kind)) } }, Err(e) => { - handle_error( + let response = handle_error( + None, udp_request.from, server_socket_addr, request_id, @@ -113,14 +118,16 @@ pub(crate) async fn handle_packet( &e, None, ) - .await + .await; + + (response, None) } }; let latency = start_time.elapsed(); tracing::trace!(?latency, "responded"); - response + (response, opt_req_kind) } /// It dispatches the request to the correct handler. @@ -143,21 +150,24 @@ pub async fn handle_request( udp_tracker_core_container: Arc, udp_tracker_server_container: Arc, cookie_time_values: CookieTimeValues, -) -> Result { +) -> Result<(Response, UdpRequestKind), (Error, TransactionId, UdpRequestKind)> { tracing::trace!("handle request"); match request { - Request::Connect(connect_request) => Ok(handle_connect( - client_socket_addr, - server_socket_addr, - &connect_request, - &udp_tracker_core_container.connect_service, - &udp_tracker_server_container.udp_server_stats_event_sender, - cookie_time_values.issue_time, - ) - .await), + Request::Connect(connect_request) => Ok(( + handle_connect( + client_socket_addr, + server_socket_addr, + &connect_request, + &udp_tracker_core_container.connect_service, + &udp_tracker_server_container.udp_server_stats_event_sender, + cookie_time_values.issue_time, + ) + .await, + UdpRequestKind::Connect, + )), Request::Announce(announce_request) => { - handle_announce( + match handle_announce( &udp_tracker_core_container.announce_service, client_socket_addr, server_socket_addr, @@ -167,9 +177,13 @@ pub async fn handle_request( cookie_time_values.valid_range, ) .await + { + Ok(response) => Ok((response, UdpRequestKind::Announce)), + Err(err) => Err(err), + } } Request::Scrape(scrape_request) => { - handle_scrape( + match handle_scrape( &udp_tracker_core_container.scrape_service, client_socket_addr, server_socket_addr, @@ -178,6 +192,10 @@ pub async fn handle_request( cookie_time_values.valid_range, ) .await + { + Ok(response) => Ok((response, UdpRequestKind::Scrape)), + Err(err) => Err(err), + } } } } diff --git a/packages/udp-tracker-server/src/handlers/scrape.rs b/packages/udp-tracker-server/src/handlers/scrape.rs index e820b2e96..db6b4a18b 100644 --- a/packages/udp-tracker-server/src/handlers/scrape.rs +++ b/packages/udp-tracker-server/src/handlers/scrape.rs @@ -1,5 +1,5 @@ //! UDP tracker scrape handler. -use std::net::{IpAddr, SocketAddr}; +use std::net::SocketAddr; use std::ops::Range; use std::sync::Arc; @@ -14,7 +14,7 @@ use zerocopy::network_endian::I32; use crate::error::Error; use crate::statistics as server_statistics; -use crate::statistics::event::UdpResponseKind; +use crate::statistics::event::{ConnectionContext, UdpRequestKind}; /// It handles the `Scrape` request. /// @@ -29,7 +29,7 @@ pub async fn handle_scrape( request: &ScrapeRequest, opt_udp_server_stats_event_sender: &Arc>>, cookie_valid_range: Range, -) -> Result { +) -> Result { tracing::Span::current() .record("transaction_id", request.transaction_id.0.to_string()) .record("connection_id", request.connection_id.0.to_string()); @@ -37,28 +37,18 @@ pub async fn handle_scrape( tracing::trace!("handle scrape"); if let Some(udp_server_stats_event_sender) = opt_udp_server_stats_event_sender.as_deref() { - match client_socket_addr.ip() { - IpAddr::V4(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp4Request { - kind: UdpResponseKind::Scrape, - }) - .await; - } - IpAddr::V6(_) => { - udp_server_stats_event_sender - .send_event(server_statistics::event::Event::Udp6Request { - kind: UdpResponseKind::Scrape, - }) - .await; - } - } + udp_server_stats_event_sender + .send_event(server_statistics::event::Event::UdpRequestAccepted { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: UdpRequestKind::Scrape, + }) + .await; } let scrape_data = scrape_service .handle_scrape(client_socket_addr, server_socket_addr, request, cookie_valid_range) .await - .map_err(|e| (e.into(), request.transaction_id))?; + .map_err(|e| (e.into(), request.transaction_id, UdpRequestKind::Scrape))?; Ok(build_response(request, &scrape_data)) } @@ -368,23 +358,25 @@ mod tests { sample_ipv4_remote_addr, MockUdpServerStatsEventSender, }; use crate::statistics as server_statistics; + use crate::statistics::event::ConnectionContext; #[tokio::test] async fn should_send_the_upd4_scrape_event() { + let client_socket_addr = sample_ipv4_remote_addr(); + let server_socket_addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969); + let mut udp_server_stats_event_sender_mock = MockUdpServerStatsEventSender::new(); udp_server_stats_event_sender_mock .expect_send_event() - .with(eq(server_statistics::event::Event::Udp4Request { - kind: server_statistics::event::UdpResponseKind::Scrape, + .with(eq(server_statistics::event::Event::UdpRequestAccepted { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: server_statistics::event::UdpRequestKind::Scrape, })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let udp_server_stats_event_sender: Arc>> = Arc::new(Some(Box::new(udp_server_stats_event_sender_mock))); - let client_socket_addr = sample_ipv4_remote_addr(); - let server_socket_addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969); - let (_core_tracker_services, core_udp_tracker_services, _server_udp_tracker_services) = initialize_core_tracker_services_for_default_tracker_configuration(); @@ -415,23 +407,25 @@ mod tests { sample_ipv6_remote_addr, MockUdpServerStatsEventSender, }; use crate::statistics as server_statistics; + use crate::statistics::event::ConnectionContext; #[tokio::test] async fn should_send_the_upd6_scrape_event() { + let client_socket_addr = sample_ipv6_remote_addr(); + let server_socket_addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969); + let mut udp_server_stats_event_sender_mock = MockUdpServerStatsEventSender::new(); udp_server_stats_event_sender_mock .expect_send_event() - .with(eq(server_statistics::event::Event::Udp6Request { - kind: server_statistics::event::UdpResponseKind::Scrape, + .with(eq(server_statistics::event::Event::UdpRequestAccepted { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + kind: server_statistics::event::UdpRequestKind::Scrape, })) .times(1) .returning(|_| Box::pin(future::ready(Some(Ok(()))))); let udp_server_stats_event_sender: Arc>> = Arc::new(Some(Box::new(udp_server_stats_event_sender_mock))); - let client_socket_addr = sample_ipv6_remote_addr(); - let server_socket_addr = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969); - let (_core_tracker_services, core_udp_tracker_services, _server_udp_tracker_services) = initialize_core_tracker_services_for_default_tracker_configuration(); diff --git a/packages/udp-tracker-server/src/server/launcher.rs b/packages/udp-tracker-server/src/server/launcher.rs index acd214ab0..c6a105230 100644 --- a/packages/udp-tracker-server/src/server/launcher.rs +++ b/packages/udp-tracker-server/src/server/launcher.rs @@ -1,4 +1,4 @@ -use std::net::{IpAddr, SocketAddr}; +use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; @@ -21,6 +21,7 @@ use crate::server::bound_socket::BoundSocket; use crate::server::processor::Processor; use crate::server::receiver::Receiver; use crate::statistics; +use crate::statistics::event::ConnectionContext; const IP_BANS_RESET_INTERVAL_IN_SECS: u64 = 3600; @@ -129,9 +130,9 @@ impl Launcher { ) { let active_requests = &mut ActiveRequests::default(); - let addr = receiver.bound_socket_address(); + let server_socket_addr = receiver.bound_socket_address(); - let local_addr = format!("udp://{addr}"); + let local_addr = format!("udp://{server_socket_addr}"); let cookie_lifetime = cookie_lifetime.as_secs_f64(); @@ -167,20 +168,15 @@ impl Launcher { } }; + let client_socket_addr = req.from; + if let Some(udp_server_stats_event_sender) = udp_tracker_server_container.udp_server_stats_event_sender.as_deref() { - match req.from.ip() { - IpAddr::V4(_) => { - udp_server_stats_event_sender - .send_event(statistics::event::Event::Udp4IncomingRequest) - .await; - } - IpAddr::V6(_) => { - udp_server_stats_event_sender - .send_event(statistics::event::Event::Udp6IncomingRequest) - .await; - } - } + udp_server_stats_event_sender + .send_event(statistics::event::Event::UdpRequestReceived { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + }) + .await; } if udp_tracker_core_container.ban_service.read().await.is_banned(&req.from.ip()) { @@ -190,7 +186,9 @@ impl Launcher { udp_tracker_server_container.udp_server_stats_event_sender.as_deref() { udp_server_stats_event_sender - .send_event(statistics::event::Event::UdpRequestBanned) + .send_event(statistics::event::Event::UdpRequestBanned { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + }) .await; } @@ -230,7 +228,9 @@ impl Launcher { udp_tracker_server_container.udp_server_stats_event_sender.as_deref() { udp_server_stats_event_sender - .send_event(statistics::event::Event::UdpRequestAborted) + .send_event(statistics::event::Event::UdpRequestAborted { + context: ConnectionContext::new(client_socket_addr, server_socket_addr), + }) .await; } } diff --git a/packages/udp-tracker-server/src/server/processor.rs b/packages/udp-tracker-server/src/server/processor.rs index 44b543571..4d1e4429a 100644 --- a/packages/udp-tracker-server/src/server/processor.rs +++ b/packages/udp-tracker-server/src/server/processor.rs @@ -1,5 +1,5 @@ use std::io::Cursor; -use std::net::{IpAddr, SocketAddr}; +use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; @@ -12,6 +12,7 @@ use tracing::{instrument, Level}; use super::bound_socket::BoundSocket; use crate::container::UdpTrackerServerContainer; use crate::handlers::CookieTimeValues; +use crate::statistics::event::{ConnectionContext, UdpRequestKind}; use crate::{handlers, statistics, RawRequest}; pub struct Processor { @@ -38,11 +39,11 @@ impl Processor { #[instrument(skip(self, request))] pub async fn process_request(self, request: RawRequest) { - let from = request.from; + let client_socket_addr = request.from; let start_time = Instant::now(); - let response = handlers::handle_packet( + let (response, opt_req_kind) = handlers::handle_packet( request, self.udp_tracker_core_container.clone(), self.udp_tracker_server_container.clone(), @@ -53,11 +54,18 @@ impl Processor { let elapsed_time = start_time.elapsed(); - self.send_response(from, response, elapsed_time).await; + self.send_response(client_socket_addr, response, opt_req_kind, elapsed_time) + .await; } #[instrument(skip(self))] - async fn send_response(self, target: SocketAddr, response: Response, req_processing_time: Duration) { + async fn send_response( + self, + client_socket_addr: SocketAddr, + response: Response, + opt_req_kind: Option, + req_processing_time: Duration, + ) { tracing::debug!("send response"); let response_type = match &response { @@ -69,10 +77,16 @@ impl Processor { }; let udp_response_kind = match &response { - Response::Connect(_) => statistics::event::UdpResponseKind::Connect, - Response::AnnounceIpv4(_) | Response::AnnounceIpv6(_) => statistics::event::UdpResponseKind::Announce, - Response::Scrape(_) => statistics::event::UdpResponseKind::Scrape, - Response::Error(_e) => statistics::event::UdpResponseKind::Error, + Response::Connect(_) => statistics::event::UdpResponseKind::Ok { + req_kind: statistics::event::UdpRequestKind::Connect, + }, + Response::AnnounceIpv4(_) | Response::AnnounceIpv6(_) => statistics::event::UdpResponseKind::Ok { + req_kind: statistics::event::UdpRequestKind::Announce, + }, + Response::Scrape(_) => statistics::event::UdpResponseKind::Ok { + req_kind: statistics::event::UdpRequestKind::Scrape, + }, + Response::Error(_e) => statistics::event::UdpResponseKind::Error { opt_req_kind: None }, }; let mut writer = Cursor::new(Vec::with_capacity(200)); @@ -82,7 +96,7 @@ impl Processor { let bytes_count = writer.get_ref().len(); let payload = writer.get_ref(); - let () = match self.send_packet(&target, payload).await { + let () = match self.send_packet(&client_socket_addr, payload).await { Ok(sent_bytes) => { if tracing::event_enabled!(Level::TRACE) { tracing::debug!(%bytes_count, %sent_bytes, ?payload, "sent {response_type}"); @@ -93,24 +107,13 @@ impl Processor { if let Some(udp_server_stats_event_sender) = self.udp_tracker_server_container.udp_server_stats_event_sender.as_deref() { - match target.ip() { - IpAddr::V4(_) => { - udp_server_stats_event_sender - .send_event(statistics::event::Event::Udp4Response { - kind: udp_response_kind, - req_processing_time, - }) - .await; - } - IpAddr::V6(_) => { - udp_server_stats_event_sender - .send_event(statistics::event::Event::Udp6Response { - kind: udp_response_kind, - req_processing_time, - }) - .await; - } - } + udp_server_stats_event_sender + .send_event(statistics::event::Event::UdpResponseSent { + context: ConnectionContext::new(client_socket_addr, self.socket.address()), + kind: udp_response_kind, + req_processing_time, + }) + .await; } } Err(error) => tracing::warn!(%bytes_count, %error, ?payload, "failed to send"), diff --git a/packages/udp-tracker-server/src/statistics/event/handler.rs b/packages/udp-tracker-server/src/statistics/event/handler.rs index 5ce9f6307..6abf7d3c7 100644 --- a/packages/udp-tracker-server/src/statistics/event/handler.rs +++ b/packages/udp-tracker-server/src/statistics/event/handler.rs @@ -1,86 +1,96 @@ -use crate::statistics::event::{Event, UdpResponseKind}; +use crate::statistics::event::{Event, UdpRequestKind, UdpResponseKind}; use crate::statistics::repository::Repository; +/// # Panics +/// +/// This function panics if the client IP version does not match the expected +/// version. +#[allow(clippy::too_many_lines)] pub async fn handle_event(event: Event, stats_repository: &Repository) { match event { - // UDP - Event::UdpRequestAborted => { + Event::UdpRequestAborted { .. } => { stats_repository.increase_udp_requests_aborted().await; } - Event::UdpRequestBanned => { + Event::UdpRequestBanned { .. } => { stats_repository.increase_udp_requests_banned().await; } - - // UDP4 - Event::Udp4IncomingRequest => { - stats_repository.increase_udp4_requests().await; - } - Event::Udp4Request { kind } => match kind { - UdpResponseKind::Connect => { - stats_repository.increase_udp4_connections().await; + Event::UdpRequestReceived { context } => match context.client_socket_addr().ip() { + std::net::IpAddr::V4(_) => { + stats_repository.increase_udp4_requests().await; } - UdpResponseKind::Announce => { - stats_repository.increase_udp4_announces().await; + std::net::IpAddr::V6(_) => { + stats_repository.increase_udp6_requests().await; } - UdpResponseKind::Scrape => { - stats_repository.increase_udp4_scrapes().await; - } - UdpResponseKind::Error => {} }, - Event::Udp4Response { + Event::UdpRequestAccepted { context, kind } => match kind { + UdpRequestKind::Connect => match context.client_socket_addr().ip() { + std::net::IpAddr::V4(_) => { + stats_repository.increase_udp4_connections().await; + } + std::net::IpAddr::V6(_) => { + stats_repository.increase_udp6_connections().await; + } + }, + UdpRequestKind::Announce => match context.client_socket_addr().ip() { + std::net::IpAddr::V4(_) => { + stats_repository.increase_udp4_announces().await; + } + std::net::IpAddr::V6(_) => { + stats_repository.increase_udp6_announces().await; + } + }, + UdpRequestKind::Scrape => match context.client_socket_addr().ip() { + std::net::IpAddr::V4(_) => { + stats_repository.increase_udp4_scrapes().await; + } + std::net::IpAddr::V6(_) => { + stats_repository.increase_udp6_scrapes().await; + } + }, + }, + Event::UdpResponseSent { + context, kind, req_processing_time, } => { - stats_repository.increase_udp4_responses().await; - - match kind { - UdpResponseKind::Connect => { - stats_repository - .recalculate_udp_avg_connect_processing_time_ns(req_processing_time) - .await; + match context.client_socket_addr().ip() { + std::net::IpAddr::V4(_) => { + stats_repository.increase_udp4_responses().await; } - UdpResponseKind::Announce => { - stats_repository - .recalculate_udp_avg_announce_processing_time_ns(req_processing_time) - .await; + std::net::IpAddr::V6(_) => { + stats_repository.increase_udp6_responses().await; } - UdpResponseKind::Scrape => { - stats_repository - .recalculate_udp_avg_scrape_processing_time_ns(req_processing_time) - .await; - } - UdpResponseKind::Error => {} } - } - Event::Udp4Error => { - stats_repository.increase_udp4_errors().await; - } - // UDP6 - Event::Udp6IncomingRequest => { - stats_repository.increase_udp6_requests().await; - } - Event::Udp6Request { kind } => match kind { - UdpResponseKind::Connect => { - stats_repository.increase_udp6_connections().await; + match kind { + UdpResponseKind::Ok { req_kind } => match req_kind { + UdpRequestKind::Connect => { + stats_repository + .recalculate_udp_avg_connect_processing_time_ns(req_processing_time) + .await; + } + UdpRequestKind::Announce => { + stats_repository + .recalculate_udp_avg_announce_processing_time_ns(req_processing_time) + .await; + } + UdpRequestKind::Scrape => { + stats_repository + .recalculate_udp_avg_scrape_processing_time_ns(req_processing_time) + .await; + } + }, + UdpResponseKind::Error { opt_req_kind: _ } => {} } - UdpResponseKind::Announce => { - stats_repository.increase_udp6_announces().await; + } + Event::UdpError { context } => match context.client_socket_addr().ip() { + std::net::IpAddr::V4(_) => { + stats_repository.increase_udp4_errors().await; } - UdpResponseKind::Scrape => { - stats_repository.increase_udp6_scrapes().await; + std::net::IpAddr::V6(_) => { + stats_repository.increase_udp6_errors().await; } - UdpResponseKind::Error => {} }, - Event::Udp6Response { - kind: _, - req_processing_time: _, - } => { - stats_repository.increase_udp6_responses().await; - } - Event::Udp6Error => { - stats_repository.increase_udp6_errors().await; - } } tracing::debug!("stats: {:?}", stats_repository.get_stats().await); @@ -88,15 +98,26 @@ pub async fn handle_event(event: Event, stats_repository: &Repository) { #[cfg(test)] mod tests { + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + use crate::statistics::event::handler::handle_event; - use crate::statistics::event::Event; + use crate::statistics::event::{ConnectionContext, Event, UdpRequestKind}; use crate::statistics::repository::Repository; #[tokio::test] async fn should_increase_the_number_of_aborted_requests_when_it_receives_a_udp_request_aborted_event() { let stats_repository = Repository::new(); - handle_event(Event::UdpRequestAborted, &stats_repository).await; + handle_event( + Event::UdpRequestAborted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + }, + &stats_repository, + ) + .await; let stats = stats_repository.get_stats().await; @@ -107,7 +128,16 @@ mod tests { async fn should_increase_the_number_of_banned_requests_when_it_receives_a_udp_request_banned_event() { let stats_repository = Repository::new(); - handle_event(Event::UdpRequestBanned, &stats_repository).await; + handle_event( + Event::UdpRequestBanned { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + }, + &stats_repository, + ) + .await; let stats = stats_repository.get_stats().await; @@ -118,7 +148,16 @@ mod tests { async fn should_increase_the_number_of_incoming_requests_when_it_receives_a_udp4_incoming_request_event() { let stats_repository = Repository::new(); - handle_event(Event::Udp4IncomingRequest, &stats_repository).await; + handle_event( + Event::UdpRequestReceived { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + }, + &stats_repository, + ) + .await; let stats = stats_repository.get_stats().await; @@ -129,7 +168,16 @@ mod tests { async fn should_increase_the_udp_abort_counter_when_it_receives_a_udp_abort_event() { let stats_repository = Repository::new(); - handle_event(Event::UdpRequestAborted, &stats_repository).await; + handle_event( + Event::UdpRequestAborted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + }, + &stats_repository, + ) + .await; let stats = stats_repository.get_stats().await; assert_eq!(stats.udp_requests_aborted, 1); } @@ -137,7 +185,16 @@ mod tests { async fn should_increase_the_udp_ban_counter_when_it_receives_a_udp_banned_event() { let stats_repository = Repository::new(); - handle_event(Event::UdpRequestBanned, &stats_repository).await; + handle_event( + Event::UdpRequestBanned { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + }, + &stats_repository, + ) + .await; let stats = stats_repository.get_stats().await; assert_eq!(stats.udp_requests_banned, 1); } @@ -147,8 +204,12 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp4Request { - kind: crate::statistics::event::UdpResponseKind::Connect, + Event::UdpRequestAccepted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpRequestKind::Connect, }, &stats_repository, ) @@ -164,8 +225,12 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp4Request { - kind: crate::statistics::event::UdpResponseKind::Announce, + Event::UdpRequestAccepted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpRequestKind::Announce, }, &stats_repository, ) @@ -181,8 +246,12 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp4Request { - kind: crate::statistics::event::UdpResponseKind::Scrape, + Event::UdpRequestAccepted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpRequestKind::Scrape, }, &stats_repository, ) @@ -198,8 +267,14 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp4Response { - kind: crate::statistics::event::UdpResponseKind::Announce, + Event::UdpResponseSent { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpResponseKind::Ok { + req_kind: UdpRequestKind::Announce, + }, req_processing_time: std::time::Duration::from_secs(1), }, &stats_repository, @@ -215,7 +290,16 @@ mod tests { async fn should_increase_the_udp4_errors_counter_when_it_receives_a_udp4_error_event() { let stats_repository = Repository::new(); - handle_event(Event::Udp4Error, &stats_repository).await; + handle_event( + Event::UdpError { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(203, 0, 113, 196)), 6969), + ), + }, + &stats_repository, + ) + .await; let stats = stats_repository.get_stats().await; @@ -227,8 +311,12 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp6Request { - kind: crate::statistics::event::UdpResponseKind::Connect, + Event::UdpRequestAccepted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpRequestKind::Connect, }, &stats_repository, ) @@ -244,8 +332,12 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp6Request { - kind: crate::statistics::event::UdpResponseKind::Announce, + Event::UdpRequestAccepted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpRequestKind::Announce, }, &stats_repository, ) @@ -261,8 +353,12 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp6Request { - kind: crate::statistics::event::UdpResponseKind::Scrape, + Event::UdpRequestAccepted { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpRequestKind::Scrape, }, &stats_repository, ) @@ -278,8 +374,14 @@ mod tests { let stats_repository = Repository::new(); handle_event( - Event::Udp6Response { - kind: crate::statistics::event::UdpResponseKind::Announce, + Event::UdpResponseSent { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969), + ), + kind: crate::statistics::event::UdpResponseKind::Ok { + req_kind: UdpRequestKind::Announce, + }, req_processing_time: std::time::Duration::from_secs(1), }, &stats_repository, @@ -294,7 +396,16 @@ mod tests { async fn should_increase_the_udp6_errors_counter_when_it_receives_a_udp6_error_event() { let stats_repository = Repository::new(); - handle_event(Event::Udp6Error, &stats_repository).await; + handle_event( + Event::UdpError { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969), + ), + }, + &stats_repository, + ) + .await; let stats = stats_repository.get_stats().await; diff --git a/packages/udp-tracker-server/src/statistics/event/mod.rs b/packages/udp-tracker-server/src/statistics/event/mod.rs index 6a48b9449..1b0be960b 100644 --- a/packages/udp-tracker-server/src/statistics/event/mod.rs +++ b/packages/udp-tracker-server/src/statistics/event/mod.rs @@ -1,3 +1,4 @@ +use std::net::SocketAddr; use std::time::Duration; pub mod handler; @@ -5,47 +6,73 @@ pub mod listener; pub mod sender; /// An statistics event. It is used to collect tracker metrics. -/// -/// - `Tcp` prefix means the event was triggered by the HTTP tracker -/// - `Udp` prefix means the event was triggered by the UDP tracker -/// - `4` or `6` prefixes means the IP version used by the peer -/// - Finally the event suffix is the type of request: `announce`, `scrape` or `connection` -/// -/// > NOTE: HTTP trackers do not use `connection` requests. -#[derive(Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone)] pub enum Event { - // code-review: consider one single event for request type with data: Event::Announce { scheme: HTTPorUDP, ip_version: V4orV6 } - // Attributes are enums too. - UdpRequestAborted, - UdpRequestBanned, - - // UDP4 - Udp4IncomingRequest, - Udp4Request { - kind: UdpResponseKind, + UdpRequestReceived { + context: ConnectionContext, }, - Udp4Response { - kind: UdpResponseKind, - req_processing_time: Duration, + UdpRequestAborted { + context: ConnectionContext, }, - Udp4Error, - - // UDP6 - Udp6IncomingRequest, - Udp6Request { - kind: UdpResponseKind, + UdpRequestBanned { + context: ConnectionContext, }, - Udp6Response { + UdpRequestAccepted { + context: ConnectionContext, + kind: UdpRequestKind, + }, + UdpResponseSent { + context: ConnectionContext, kind: UdpResponseKind, req_processing_time: Duration, }, - Udp6Error, + UdpError { + context: ConnectionContext, + }, } -#[derive(Debug, PartialEq, Eq)] -pub enum UdpResponseKind { +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum UdpRequestKind { Connect, Announce, Scrape, - Error, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub enum UdpResponseKind { + Ok { + req_kind: UdpRequestKind, + }, + + /// There was an error handling the request. The error contains the request + /// kind if the request was parsed successfully. + Error { + opt_req_kind: Option, + }, +} + +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct ConnectionContext { + client_socket_addr: SocketAddr, + server_socket_addr: SocketAddr, +} + +impl ConnectionContext { + #[must_use] + pub fn new(client_socket_addr: SocketAddr, server_socket_addr: SocketAddr) -> Self { + Self { + client_socket_addr, + server_socket_addr, + } + } + + #[must_use] + pub fn client_socket_addr(&self) -> SocketAddr { + self.client_socket_addr + } + + #[must_use] + pub fn server_socket_addr(&self) -> SocketAddr { + self.server_socket_addr + } } diff --git a/packages/udp-tracker-server/src/statistics/keeper.rs b/packages/udp-tracker-server/src/statistics/keeper.rs index ae80e7970..4ce832227 100644 --- a/packages/udp-tracker-server/src/statistics/keeper.rs +++ b/packages/udp-tracker-server/src/statistics/keeper.rs @@ -51,7 +51,9 @@ impl Keeper { #[cfg(test)] mod tests { - use crate::statistics::event::Event; + use std::net::{IpAddr, Ipv6Addr, SocketAddr}; + + use crate::statistics::event::{ConnectionContext, Event}; use crate::statistics::keeper::Keeper; use crate::statistics::metrics::Metrics; @@ -70,7 +72,14 @@ mod tests { let event_sender = stats_tracker.run_event_listener(); - let result = event_sender.send_event(Event::Udp4IncomingRequest).await; + let result = event_sender + .send_event(Event::UdpRequestReceived { + context: ConnectionContext::new( + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 195)), 8080), + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 203, 0, 113, 196)), 6969), + ), + }) + .await; assert!(result.is_some()); }