Commit 1bb93172 authored by David Goulet's avatar David Goulet
Browse files

dns: Klunky IP cookie map



Signed-off-by: default avatarDavid Goulet <dgoulet@ev0ke.net>
parent 62cf0afb
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
use std::{
    collections::HashMap,
    net::Ipv4Addr,
    sync::{Arc, Mutex},
};

use futures::stream::StreamExt;
use log::{error, info};
use smoltcp::{
@@ -9,6 +15,8 @@ use crate::socket::UdpSocket;

pub struct DnsManager {
    listener_udp_v4: UdpSocket,

    cookies: Arc<Mutex<HashMap<IpAddress, String>>>,
}

impl DnsManager {
@@ -21,7 +29,14 @@ impl DnsManager {
        let mut listener_udp_v4 = UdpSocket::new(iface, socket);
        listener_udp_v4.bind(IpAddress::v4(10, 42, 42, 53), 53);

        Self { listener_udp_v4 }
        Self {
            listener_udp_v4,
            cookies: Arc::new(Mutex::new(HashMap::new())),
        }
    }

    pub fn cookies(&self) -> Arc<Mutex<HashMap<IpAddress, String>>> {
        self.cookies.clone()
    }

    pub async fn start(&mut self) {
@@ -34,12 +49,13 @@ impl DnsManager {
                        let ret = dns_message_parser::Dns::decode(payload);
                        match ret {
                            Ok(p) => {
                                let cookie = Ipv4Addr::new(10, 42, 42, 254);
                                let q = p.questions.get(0).unwrap();
                                info!("DNS Question: {} from {}", q, endpoint);
                                let a = dns_message_parser::rr::A {
                                    domain_name: q.domain_name.clone(),
                                    ttl: 10,
                                    ipv4_addr: "10.42.42.254".parse().unwrap(),
                                    ipv4_addr: cookie,
                                };
                                let rr = dns_message_parser::rr::RR::A(a);
                                let flags = dns_message_parser::Flags {
@@ -62,6 +78,7 @@ impl DnsManager {
                                    additionals: Vec::new(),
                                };
                                let _ = self.listener_udp_v4.send(reply.encode().unwrap().as_ref(), endpoint);
                                self.cookies.lock().unwrap().insert(cookie.into(), q.domain_name.to_string().clone());
                            }
                            Err(e) => error!("Unable to parse DNS request: {}", e),
                        }
+12 −13
Original line number Diff line number Diff line
@@ -15,7 +15,7 @@ use smoltcp::{
    wire::{IpAddress, IpCidr, Ipv4Address},
};
use std::{
    collections::BTreeMap,
    collections::{BTreeMap, HashMap},
    sync::{Arc, Mutex},
};
use tor_rtcompat::tokio::TokioNativeTlsRuntime;
@@ -51,12 +51,14 @@ impl OnionTunnel {
                .expect("Unable to create Tor Client");

        let iface = iface_builder.finalize();
        let iface_fd = iface.device().as_raw_fd();
        let iface = Arc::new(Mutex::new(iface));

        Self {
            iface_fd: iface.device().as_raw_fd(),
            iface_name: iface_name.to_string(),
            iface: Arc::new(Mutex::new(iface)),
            arti,
            iface_fd,
            iface_name: iface_name.to_string(),
            iface,
        }
    }

@@ -69,21 +71,18 @@ impl OnionTunnel {
        }
    }

    fn proxy(&mut self, socket: TcpSocket) {
        let mut proxy = ArtiProxy::new(socket, self.arti.clone());
    fn proxy(&mut self, socket: TcpSocket, cookies: Arc<Mutex<HashMap<IpAddress, String>>>) {
        let mut proxy = ArtiProxy::new(socket, self.arti.clone(), cookies);
        tokio::spawn(async move { proxy.start().await });
    }

    fn dns(&mut self) {
        let mut dns_manager = DnsManager::new(self.iface.clone());
        tokio::spawn(async move { dns_manager.start().await });
    }

    pub async fn start(&mut self) {
        info!("Starting onion tunnel on TUN iface {}", self.iface_name);

        // Spawn the DNS manager service.
        self.dns();
        let mut dns_manager = DnsManager::new(self.iface.clone());
        let cookies = dns_manager.cookies();
        tokio::spawn(async move { dns_manager.start().await });

        loop {
            let timestamp = smoltcp::time::Instant::now();
@@ -97,7 +96,7 @@ impl OnionTunnel {
            while let Some(packet) = packets.pop_front() {
                if let Some(tcp_socket) = Parser::parse(packet.clone()).take() {
                    let socket = TcpSocket::new(self.iface.clone(), tcp_socket);
                    self.proxy(socket);
                    self.proxy(socket, cookies.clone());
                }
                self.iface.lock().unwrap().device_mut().put_packet(packet);
            }
+28 −7
Original line number Diff line number Diff line
use std::collections::HashMap;
use std::net::IpAddr;
use std::sync::Arc;
use std::sync::Mutex;

use arti_client::DangerouslyIntoTorAddr;
use arti_client::TorAddr;
use arti_client::TorClient;
use log::info;
use smoltcp::wire::IpAddress;
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tor_rtcompat::tokio::TokioNativeTlsRuntime;

@@ -9,23 +16,37 @@ use crate::socket::TcpSocket;
pub struct ArtiProxy {
    socket: TcpSocket,
    arti: TorClient<TokioNativeTlsRuntime>,
    cookies: Arc<Mutex<HashMap<IpAddress, String>>>,
}

impl ArtiProxy {
    pub fn new(socket: TcpSocket, arti: TorClient<TokioNativeTlsRuntime>) -> Self {
        Self { socket, arti }
    pub fn new(
        socket: TcpSocket,
        arti: TorClient<TokioNativeTlsRuntime>,
        cookies: Arc<Mutex<HashMap<IpAddress, String>>>,
    ) -> Self {
        Self {
            socket,
            arti,
            cookies,
        }
    }

    pub async fn start(&mut self) {
        info!("Starting Arti Proxy");

        let dest = self.socket.dest();
        let tor_addr;

        if let Some(hostname) = self.cookies.lock().unwrap().get(&dest.0) {
            tor_addr = TorAddr::from((hostname.clone(), dest.1));
        } else {
            let ip_addr: IpAddr = dest.0.into();
            tor_addr = (ip_addr, dest.1).into_tor_addr_dangerously();
        }

        info!("Connecting to: {:?}", dest);
        let mut arti_stream = self
            .arti
            .connect(dest.into_tor_addr_dangerously().unwrap())
            .await
            .unwrap();
        let mut arti_stream = self.arti.connect(tor_addr.unwrap()).await.unwrap();
        info!("Connected to: {:?}", dest);

        loop {
+2 −2
Original line number Diff line number Diff line
@@ -99,10 +99,10 @@ impl TcpSocket {
            .get_socket::<smoltcp::socket::TcpSocket>(self.handle))
    }

    pub fn dest(&mut self) -> (IpAddr, u16) {
    pub fn dest(&mut self) -> (smoltcp::wire::IpAddress, u16) {
        self.with(|s| {
            let endpoint = s.local_endpoint();
            (endpoint.addr.into(), endpoint.port)
            (endpoint.addr, endpoint.port)
        })
    }
}