From 87c2cb7b0f47c8a9b136689acf7be6ef296fc944 Mon Sep 17 00:00:00 2001 From: maxomatic458 <104733404+maxomatic458@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:03:45 +0100 Subject: [PATCH 1/2] show connections per tunnel --- packages/agent_cli/src/autorun.rs | 26 ++++++++++++------- packages/agent_cli/src/main.rs | 4 +-- packages/agent_core/src/api/api.rs | 14 ++++++++++ packages/agent_core/src/api/ip_resource.rs | 13 ++++++++++ packages/agent_core/src/lib.rs | 1 + .../{agent_cli => agent_core}/src/match_ip.rs | 0 .../agent_core/src/network/tcp_clients.rs | 16 ++++++++++-- .../agent_core/src/network/udp_clients.rs | 14 +++++++++- packages/agent_core/src/tunnel_runner.rs | 8 ++++++ 9 files changed, 82 insertions(+), 14 deletions(-) rename packages/{agent_cli => agent_core}/src/match_ip.rs (100%) diff --git a/packages/agent_cli/src/autorun.rs b/packages/agent_cli/src/autorun.rs index 4ffacef..7340d48 100644 --- a/packages/agent_cli/src/autorun.rs +++ b/packages/agent_cli/src/autorun.rs @@ -6,14 +6,11 @@ use std::{ }; use playit_agent_core::{ - api::api::*, - network::address_lookup::{AddressLookup, AddressValue}, - tunnel_runner::TunnelRunner, - utils::now_milli, + api::api::*, match_ip::MatchIp, network::address_lookup::{AddressLookup, AddressValue}, tunnel_runner::TunnelRunner, utils::now_milli }; use playit_agent_core::api::api::AgentType; -use crate::{API_BASE, CliError, match_ip::MatchIp, playit_secret::PlayitSecret, ui::UI}; +use crate::{API_BASE, CliError, playit_secret::PlayitSecret, ui::UI}; pub async fn autorun(ui: &mut UI, mut secret: PlayitSecret) -> Result<(), CliError> { let secret_code = secret @@ -56,6 +53,7 @@ pub async fn autorun(ui: &mut UI, mut secret: PlayitSecret) -> Result<(), CliErr }; let signal = runner.keep_running(); + let (tcp_clients, udp_clients) = (runner.tcp_clients(), runner.udp_clients()); let runner = tokio::spawn(runner.run()); ui.write_screen("tunnel running").await; @@ -144,17 +142,27 @@ pub async fn autorun(ui: &mut UI, mut secret: PlayitSecret) -> Result<(), CliErr _ => format!("{}:{}", addr, tunnel.port.from), }; - let dst = format!("{}:{}", tunnel.local_ip, tunnel.local_port); - + let dst = SocketAddr::new(tunnel.local_ip, tunnel.local_port); + + let connection_count = match tunnel.proto { + PortType::Both => { + let tcp = tcp_clients.active_clients().client_count_by_agent_tunnel(&tunnel).await; + let udp = udp_clients.client_count_by_agent_tunnel(&tunnel).await; + tcp + udp + }, + PortType::Tcp => tcp_clients.active_clients().client_count_by_agent_tunnel(&tunnel).await, + PortType::Udp => udp_clients.client_count_by_agent_tunnel(&tunnel).await, + }; + if let Some(disabled) = tunnel.disabled { writeln!(msg, "{} => {} (disabled)", src, dst).unwrap(); if disabled == AgentTunnelDisabled::BySystem { writeln!(msg, "\tsee: https://playit.gg/account/tunnels/{}", tunnel.id).unwrap(); } } else if let Some(tunnel_type) = &tunnel.tunnel_type { - writeln!(msg, "{} => {} ({})", src, dst, tunnel_type).unwrap(); + writeln!(msg, "{} => {} ({}, connections: {})", src, dst, tunnel_type, connection_count).unwrap(); } else { - writeln!(msg, "{} => {} (proto: {:?}, port count: {})", src, dst, tunnel.proto, tunnel.port.to - tunnel.port.from).unwrap(); + writeln!(msg, "{} => {} (proto: {:?}, port count: {}, connections: {})", src, dst, tunnel.proto, tunnel.port.to - tunnel.port.from, connection_count).unwrap(); } } diff --git a/packages/agent_cli/src/main.rs b/packages/agent_cli/src/main.rs index c848bb6..9aecb42 100644 --- a/packages/agent_cli/src/main.rs +++ b/packages/agent_cli/src/main.rs @@ -7,6 +7,7 @@ use std::sync::Arc; use std::time::Duration; use clap::{arg, Command}; +use playit_agent_core::match_ip::MatchIp; use rand::Rng; use uuid::Uuid; @@ -20,7 +21,7 @@ use playit_agent_core::tunnel_runner::TunnelRunner; use playit_agent_core::utils::now_milli; use playit_secret::PlayitSecret; -use crate::match_ip::MatchIp; +// use crate::match_ip::MatchIp; use crate::signal_handle::get_signal_handle; use crate::ui::{UI, UISettings}; @@ -29,7 +30,6 @@ pub const API_BASE: &'static str = "https://api.playit.gg"; pub mod util; pub mod autorun; pub mod playit_secret; -pub mod match_ip; pub mod ui; pub mod signal_handle; diff --git a/packages/agent_core/src/api/api.rs b/packages/agent_core/src/api/api.rs index 1eb849e..2e4c07a 100644 --- a/packages/agent_core/src/api/api.rs +++ b/packages/agent_core/src/api/api.rs @@ -1,3 +1,6 @@ +use std::net::Ipv6Addr; +use super::ip_resource::{IpResource, PlayitRegion}; + impl PlayitApiClient { pub fn new(client: C) -> Self { PlayitApiClient { client } @@ -648,6 +651,17 @@ pub struct AgentTunnel { pub disabled: Option, } +impl AgentTunnel { + pub fn to_tunnel_ip(&self) -> Ipv6Addr { + let ip_resource = IpResource { + ip_num: self.ip_num, + region: PlayitRegion::from_id(self.region_num).unwrap(), + }; + + ip_resource.to_tunnel_ip() + } +} + #[derive(serde::Serialize, serde::Deserialize, Debug, Clone)] pub struct PortRange { pub from: u16, diff --git a/packages/agent_core/src/api/ip_resource.rs b/packages/agent_core/src/api/ip_resource.rs index 9e8cd95..29611a4 100644 --- a/packages/agent_core/src/api/ip_resource.rs +++ b/packages/agent_core/src/api/ip_resource.rs @@ -96,4 +96,17 @@ impl PlayitRegion { BigEndian::write_u64(&mut octs[8..], ip_number); octs.into() } + + pub fn from_id(id: u16) -> Option { + match id { + 0 => Some(PlayitRegion::Anycast), + 1 => Some(PlayitRegion::Global), + 2 => Some(PlayitRegion::NorthAmerica), + 3 => Some(PlayitRegion::Europe), + 4 => Some(PlayitRegion::Asia), + 5 => Some(PlayitRegion::India), + 6 => Some(PlayitRegion::SouthAmerica), + _ => None, + } + } } \ No newline at end of file diff --git a/packages/agent_core/src/lib.rs b/packages/agent_core/src/lib.rs index aa327fc..de63bca 100644 --- a/packages/agent_core/src/lib.rs +++ b/packages/agent_core/src/lib.rs @@ -6,6 +6,7 @@ pub mod tunnel; pub mod network; pub mod utils; pub mod tunnel_runner; +pub mod match_ip; #[cfg(test)] mod test { diff --git a/packages/agent_cli/src/match_ip.rs b/packages/agent_core/src/match_ip.rs similarity index 100% rename from packages/agent_cli/src/match_ip.rs rename to packages/agent_core/src/match_ip.rs diff --git a/packages/agent_core/src/network/tcp_clients.rs b/packages/agent_core/src/network/tcp_clients.rs index a8f5aae..af884c0 100644 --- a/packages/agent_core/src/network/tcp_clients.rs +++ b/packages/agent_core/src/network/tcp_clients.rs @@ -1,4 +1,4 @@ -use std::collections::{HashMap}; +use std::collections::HashMap; use std::collections::hash_map::Entry; use std::io::Error; use std::net::SocketAddr; @@ -11,8 +11,10 @@ use tokio::net::tcp::{OwnedReadHalf, OwnedWriteHalf}; use tokio::net::TcpStream; use tokio::sync::RwLock; -use playit_agent_proto::control_feed::{NewClient}; +use playit_agent_proto::control_feed::NewClient; +use crate::api::api::AgentTunnel; +use crate::match_ip::MatchIp; use crate::tunnel::tcp_tunnel::TcpTunnel; #[derive(Clone)] @@ -52,6 +54,16 @@ impl ActiveClients { let lock = self.active.read().await; lock.values().map(|v| v.clone()).collect() } + + pub async fn client_count_by_agent_tunnel(&self, tunnel: &AgentTunnel) -> usize { + let tunnel_ip = tunnel.to_tunnel_ip(); + let ip = MatchIp::new(tunnel_ip); + + let lock = self.active.read().await; + lock.values().filter(|v| { + ip.matches(v.connect_addr.ip()) && tunnel.port.contains(v.connect_addr.port()) + }).count() + } } impl Default for ActiveClients { diff --git a/packages/agent_core/src/network/udp_clients.rs b/packages/agent_core/src/network/udp_clients.rs index 394fd3c..de16a89 100644 --- a/packages/agent_core/src/network/udp_clients.rs +++ b/packages/agent_core/src/network/udp_clients.rs @@ -7,13 +7,15 @@ use std::time::Duration; use tokio::net::UdpSocket; use tokio::sync::RwLock; -use crate::api::api::PortType; +use crate::api::api::{AgentTunnel, PortType}; +use crate::match_ip::MatchIp; use crate::network::address_lookup::AddressLookup; use crate::network::lan_address::LanAddress; use crate::tunnel::udp_proto::UdpFlow; use crate::tunnel::udp_tunnel::UdpTunnel; use crate::utils::now_sec; +#[derive(Clone)] pub struct UdpClients { udp_tunnel: UdpTunnel, lookup: L, @@ -42,6 +44,16 @@ impl UdpClients where L::Value: Into { clients_lock.len() } + pub async fn client_count_by_agent_tunnel(&self, tunnel: &AgentTunnel) -> usize { + let tunnel_ip = tunnel.to_tunnel_ip(); + let ip = MatchIp::new(tunnel_ip); + + let lock = self.udp_clients.read().await; + lock.values().filter(|v| { + ip.matches(v.client_key.tunnel_addr.ip()) && tunnel.port.contains(v.client_key.tunnel_addr.port()) + }).count() + } + pub async fn forward_packet(&self, flow: &UdpFlow, data: &[u8]) -> std::io::Result { let flow_dst = flow.dst(); diff --git a/packages/agent_core/src/tunnel_runner.rs b/packages/agent_core/src/tunnel_runner.rs index 6356770..70f0bb7 100644 --- a/packages/agent_core/src/tunnel_runner.rs +++ b/packages/agent_core/src/tunnel_runner.rs @@ -47,6 +47,14 @@ impl TunnelRunner where L::Value: Into TcpClients { + self.tcp_clients.clone() + } + + pub fn udp_clients(&self) -> UdpClients> { + self.udp_clients.clone() + } + pub async fn run(self) { let mut tunnel = self.tunnel; let udp = tunnel.udp_tunnel(); From 591638b412d0e258741ec355c37b56bcfceeadf1 Mon Sep 17 00:00:00 2001 From: maxomatic458 <104733404+maxomatic458@users.noreply.github.com> Date: Sat, 3 Feb 2024 22:06:20 +0100 Subject: [PATCH 2/2] remove comment --- packages/agent_cli/src/main.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/agent_cli/src/main.rs b/packages/agent_cli/src/main.rs index 9aecb42..ff428d2 100644 --- a/packages/agent_cli/src/main.rs +++ b/packages/agent_cli/src/main.rs @@ -21,7 +21,6 @@ use playit_agent_core::tunnel_runner::TunnelRunner; use playit_agent_core::utils::now_milli; use playit_secret::PlayitSecret; -// use crate::match_ip::MatchIp; use crate::signal_handle::get_signal_handle; use crate::ui::{UI, UISettings};