Просмотр исходного кода

net/transport/tor: Remove regex dependency.

Luther Blissett 3 лет назад
Родитель
Сommit
fd9c32f729
5 измененных файлов с 32 добавлено и 23 удалено
  1. 0 1
      Cargo.lock
  2. 0 2
      Cargo.toml
  3. 0 4
      src/error.rs
  4. 1 2
      src/net/transport.rs
  5. 31 14
      src/net/transport/tor.rs

+ 0 - 1
Cargo.lock

@@ -1219,7 +1219,6 @@ dependencies = [
  "plotters",
  "rand",
  "rcgen",
- "regex",
  "rustls-pemfile",
  "serde",
  "serde_json",

+ 0 - 2
Cargo.toml

@@ -93,7 +93,6 @@ itertools = {version = "0.10.3", optional = true}
 darkfi-derive = {path = "src/util/derive", optional = true}
 darkfi-derive-internal = {path = "src/util/derive-internal", optional = true}
 chrono = {version = "0.4.22", optional = true}
-regex = {version = "1.6.0", optional = true}
 
 # Misc
 termion = {version = "1.5.6", optional = true}
@@ -226,7 +225,6 @@ net = [
 	"fast-socks5",
 	"ed25519-compact",
 	"rcgen",
-	"regex",
 	"rustls-pemfile",
 	"structopt",
 	"structopt-toml",

+ 0 - 4
src/error.rs

@@ -291,10 +291,6 @@ pub enum Error {
     #[error("Failed decoding bincode: {0}")]
     ZkasDecoderError(String),
 
-    #[cfg(feature = "regex")]
-    #[error(transparent)]
-    RegexError(#[from] regex::Error),
-
     #[cfg(feature = "util")]
     #[error("System clock is not correct!")]
     InvalidClock,

+ 1 - 2
src/net/transport.rs

@@ -1,7 +1,6 @@
 use std::{net::SocketAddr, time::Duration};
 
 use async_trait::async_trait;
-// TODO remove *
 use futures::prelude::*;
 use futures_rustls::{TlsAcceptor, TlsStream};
 use url::Url;
@@ -26,7 +25,7 @@ pub(crate) fn socket_addr_to_url(addr: SocketAddr, scheme: &str) -> Result<Url>
     Ok(url)
 }
 
-/// Used as wrapper for stream used by  Transport trait
+/// Used as wrapper for stream used by Transport trait
 pub trait TransportStream: AsyncWrite + AsyncRead + Unpin + Send + Sync {}
 
 /// Used as wrapper for listener used by Transport trait

+ 31 - 14
src/net/transport/tor.rs

@@ -1,7 +1,3 @@
-use async_std::{
-    net::{TcpListener, TcpStream},
-    sync::Arc,
-};
 use std::{
     io,
     io::{BufRead, BufReader, Write},
@@ -10,11 +6,14 @@ use std::{
     time::Duration,
 };
 
+use async_std::{
+    net::{TcpListener, TcpStream},
+    sync::Arc,
+};
 use fast_socks5::client::{Config, Socks5Stream};
 use futures::prelude::*;
 use futures_rustls::{TlsAcceptor, TlsStream};
-use regex::Regex;
-use socket2::{Domain, Socket, Type};
+use socket2::{Domain, Socket, TcpKeepalive, Type};
 use url::Url;
 
 use crate::{Error, Result};
@@ -111,13 +110,14 @@ impl TorController {
         let port = url.port().unwrap();
 
         let payload = format!(
-            "AUTHENTICATE {a}\r\nADD_ONION NEW:BEST Flags=DiscardPK Port={p},{h}:{p}\r\n",
+            "AUTHENTICATE {a}\r\nADD_ONION NEW:ED25519-V3 Flags=DiscardPK Port={p},{h}:{p}\r\n",
             a = self.auth,
             p = port,
             h = host
         );
         stream.write_all(payload.as_bytes())?;
-        stream.set_read_timeout(Some(Duration::from_secs(1)))?; // Maybe a bit too much. Gives tor time to reply
+        // 1s is maybe a bit too much. Gives tor time to reply
+        stream.set_read_timeout(Some(Duration::from_secs(1)))?;
         let mut reader = BufReader::new(stream);
         let mut repl = String::new();
         while let Ok(nbytes) = reader.read_line(&mut repl) {
@@ -125,11 +125,19 @@ impl TorController {
                 break
             }
         }
-        let re = Regex::new(r"250-ServiceID=(\w+*)")?;
-        //let cap: Result<regex::Captures<'_>> =
-        let cap = re.captures(&repl).ok_or_else(|| Error::TorError(repl.clone()));
-        let hurl = cap?.get(1).map_or(Err(Error::TorError(repl.clone())), |m| Ok(m.as_str()))?;
-        let hurl = format!("tcp://{}.onion:{}", &hurl, port);
+
+        let spl: Vec<&str> = repl.split('\n').collect();
+        if spl.len() != 4 {
+            return Err(Error::TorError(format!("Unsuccessful reply from TorControl: {:?}", spl)))
+        }
+
+        let onion: Vec<&str> = spl[1].split('=').collect();
+        if onion.len() != 2 {
+            return Err(Error::TorError(format!("Unsuccessful reply from TorControl: {:?}", spl)))
+        }
+
+        let onion = &onion[1][..onion[1].len() - 1];
+        let hurl = format!("tcp://{}.onion:{}", onion, port);
         Ok(Url::parse(&hurl)?)
     }
 }
@@ -173,7 +181,7 @@ impl TorTransport {
             return Err(Error::TorError(
                 "Please set the env var DARKFI_TOR_COOKIE to the configured Tor cookie file.\n\
                 For example:\n\
-                \'export DARKFI_TOR_COOKIE\"/var/lib/tor/control_auth_cookie\"\'"
+                export DARKFI_TOR_COOKIE='/var/lib/tor/control_auth_cookie'"
                     .to_string(),
             ))
         }
@@ -234,6 +242,14 @@ impl TorTransport {
         if socket_addr.is_ipv6() {
             socket.set_only_v6(true)?;
         }
+
+        // TODO: Perhaps make these configurable
+        socket.set_nodelay(true)?;
+        let keepalive = TcpKeepalive::new().with_time(Duration::from_secs(30));
+        socket.set_tcp_keepalive(&keepalive)?;
+        // TODO: Make sure to disallow running multiple instances of a program using this.
+        socket.set_reuse_port(true)?;
+
         Ok(socket)
     }
 
@@ -275,6 +291,7 @@ impl Transport for TorTransport {
     fn dial(self, url: Url, _timeout: Option<Duration>) -> Result<Self::Dial> {
         match url.scheme() {
             "tor" | "tor+tls" => {}
+            "tcp" | "tcp+tls" | "tls" => {}
             x => return Err(Error::UnsupportedTransport(x.to_string())),
         }
         Ok(Box::pin(self.do_dial(url)))