فهرست منبع

net: implement socks5 transport mixing

oars 1 سال پیش
والد
کامیت
7e28e2d52f
4فایلهای تغییر یافته به همراه76 افزوده شده و 8 حذف شده
  1. 26 1
      src/net/connector.rs
  2. 35 3
      src/net/hosts.rs
  3. 5 4
      src/net/session/outbound_session.rs
  4. 10 0
      src/net/settings.rs

+ 26 - 1
src/net/connector.rs

@@ -67,6 +67,7 @@ impl Connector {
         let transport_mixing = settings.transport_mixing;
         let datastore = settings.p2p_datastore.clone();
         let outbound_connect_timeout = settings.outbound_connect_timeout;
+        let socks5_proxy = settings.socks5_proxy.clone();
         drop(settings);
 
         let mut endpoint = url.clone();
@@ -81,7 +82,31 @@ impl Connector {
                 endpoint.set_scheme("nym")?;
             } else if transports.contains(&"nym+tls".to_string()) && scheme == "tcp+tls" {
                 endpoint.set_scheme("nym+tls")?;
-            } else if transports.contains(&"socks5+tls".to_string()) && scheme == "tcp+tls" {
+            } else if transports.contains(&"socks5".to_string()) &&
+                (scheme == "tcp" || scheme == "tor")
+            {
+                endpoint.set_path(&format!(
+                    "{}:{}",
+                    endpoint.host().unwrap(),
+                    endpoint.port().unwrap()
+                ));
+                endpoint.set_host(socks5_proxy.host_str())?;
+                endpoint.set_port(socks5_proxy.port())?;
+                endpoint.set_username(socks5_proxy.username())?;
+                endpoint.set_password(socks5_proxy.password())?;
+                endpoint.set_scheme("socks5")?;
+            } else if transports.contains(&"socks5+tls".to_string()) &&
+                (scheme == "tcp+tls" || scheme == "tor+tls")
+            {
+                endpoint.set_path(&format!(
+                    "{}:{}",
+                    endpoint.host().unwrap(),
+                    endpoint.port().unwrap()
+                ));
+                endpoint.set_host(socks5_proxy.host_str())?;
+                endpoint.set_port(socks5_proxy.port())?;
+                endpoint.set_username(socks5_proxy.username())?;
+                endpoint.set_password(socks5_proxy.password())?;
                 endpoint.set_scheme("socks5+tls")?;
             }
         }

+ 35 - 3
src/net/hosts.rs

@@ -420,6 +420,7 @@ impl HostContainer {
         color: HostColor,
         transports: &[String],
         transport_mixing: bool,
+        socks5_proxy: Url,
     ) -> Vec<(Url, u64)> {
         trace!(target: "net::hosts::fetch_addrs()", "[START] {:?}", color);
         let mut hosts = vec![];
@@ -440,12 +441,35 @@ impl HostContainer {
             };
         }
 
+        macro_rules! mix_socks5_transport {
+            ($a:expr, $b:expr) => {
+                if transports.contains(&$a.to_string()) && transport_mixing {
+                    let mut a_to_b = self.fetch_with_schemes(index, &[$b.to_string()], None);
+                    for (addr, last_seen) in a_to_b.iter_mut() {
+                        addr.set_path(&format!(
+                            "{}:{}",
+                            addr.host().unwrap(),
+                            addr.port().unwrap()
+                        ));
+                        addr.set_host(socks5_proxy.host_str()).unwrap();
+                        addr.set_port(socks5_proxy.port()).unwrap();
+                        addr.set_username(socks5_proxy.username()).unwrap();
+                        addr.set_password(socks5_proxy.password()).unwrap();
+                        addr.set_scheme($a).unwrap();
+                        hosts.push((addr.clone(), last_seen.clone()));
+                    }
+                }
+            };
+        }
+
         mix_transport!("tor", "tcp");
         mix_transport!("tor+tls", "tcp+tls");
         mix_transport!("nym", "tcp");
         mix_transport!("nym+tls", "tcp+tls");
-        mix_transport!("socks5", "tcp");
-        mix_transport!("socks5+tls", "tcp+tls");
+        mix_socks5_transport!("socks5", "tcp");
+        mix_socks5_transport!("socks5+tls", "tcp+tls");
+        mix_socks5_transport!("socks5", "tor");
+        mix_socks5_transport!("socks5+tls", "tor+tls");
 
         // And now the actual requested transports
         for (addr, last_seen) in self.fetch_with_schemes(index, transports, None) {
@@ -1351,7 +1375,15 @@ impl Hosts {
                 let day = 86400;
                 self.container.refresh(HostColor::Dark, day);
 
-                continue
+                // If transport mixing is disabled or Socks5 transport is not allowed we will not connect to this host
+                if !settings.transport_mixing ||
+                    !settings
+                        .allowed_transports
+                        .iter()
+                        .any(|t| t == "socks5" || t == "socks5+tls")
+                {
+                    continue;
+                }
             }
 
             // Reject this peer if it's already stored on the Gold, White or Grey list.

+ 5 - 4
src/net/session/outbound_session.rs

@@ -218,6 +218,7 @@ impl Slot {
         let transports = settings.allowed_transports.clone();
         let transport_mixing = settings.transport_mixing;
         let preference_strict = settings.slot_preference_strict;
+        let socks5_proxy = settings.socks5_proxy.clone();
 
         // Drop Settings read lock
         drop(settings);
@@ -229,13 +230,13 @@ impl Slot {
         // If we only have grey entries, select from the greylist. Otherwise,
         // use the preference defined in settings.
         let addrs = if grey_only && !preference_strict {
-            container.fetch(HostColor::Grey, &transports, transport_mixing)
+            container.fetch(HostColor::Grey, &transports, transport_mixing, socks5_proxy)
         } else if slot < gold_count {
-            container.fetch(HostColor::Gold, &transports, transport_mixing)
+            container.fetch(HostColor::Gold, &transports, transport_mixing, socks5_proxy)
         } else if slot < white_count {
-            container.fetch(HostColor::White, &transports, transport_mixing)
+            container.fetch(HostColor::White, &transports, transport_mixing, socks5_proxy)
         } else {
-            container.fetch(HostColor::Grey, &transports, transport_mixing)
+            container.fetch(HostColor::Grey, &transports, transport_mixing, socks5_proxy)
         };
 
         hosts.check_addrs(addrs).await

+ 10 - 0
src/net/settings.rs

@@ -64,6 +64,9 @@ pub struct Settings {
     pub allowed_transports: Vec<String>,
     /// Allow transport mixing (e.g. Tor would be allowed to connect to `tcp://`)
     pub transport_mixing: bool,
+    /// Socks5 proxy to connect to when socks5 or socks5+tls are added to allowed transports
+    /// and transport mixing is enabled
+    pub socks5_proxy: Url,
     /// Outbound connection slots number, this many connections will be
     /// attempted. (This does not include manual connections)
     pub outbound_connections: usize,
@@ -124,6 +127,7 @@ impl Default for Settings {
             app_version,
             allowed_transports: vec!["tcp+tls".to_string()],
             transport_mixing: true,
+            socks5_proxy: Url::parse("socks5://127.0.0.1:9050").unwrap(),
             outbound_connections: 8,
             inbound_connections: 8,
             outbound_connect_timeout: 15,
@@ -225,6 +229,11 @@ pub struct SettingsOpt {
     #[structopt(long)]
     pub transport_mixing: Option<bool>,
 
+    /// Socks5 proxy to connect to when socks5 or socks5+tls are added to allowed transports
+    /// and transport mixing is enabled
+    #[structopt(long)]
+    pub socks5_proxy: Option<Url>,
+
     /// If this is true, strictly follow the gold_connect_count and
     /// white_connect_percent settings. Otherwise, connect to greylist
     /// entries if we have no white or gold connections.
@@ -301,6 +310,7 @@ impl From<SettingsOpt> for Settings {
             app_version: def.app_version,
             allowed_transports: opt.allowed_transports.unwrap_or(def.allowed_transports),
             transport_mixing: opt.transport_mixing.unwrap_or(def.transport_mixing),
+            socks5_proxy: opt.socks5_proxy.unwrap_or(def.socks5_proxy),
             outbound_connections: opt.outbound_connections.unwrap_or(def.outbound_connections),
             inbound_connections: opt.inbound_connections.unwrap_or(def.inbound_connections),
             outbound_connect_timeout: opt