Skip to content

Commit

Permalink
Merge pull request #1 from docheio/dev
Browse files Browse the repository at this point in the history
0.2.0
  • Loading branch information
yush authored Aug 18, 2023
2 parents 39b23db + 905b900 commit cb4aec8
Show file tree
Hide file tree
Showing 10 changed files with 396 additions and 80 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/target
Cargo.lock
Cargo.lock
.memo
6 changes: 4 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
[package]
name = "tardis"
version = "0.1.1"
version = "0.2.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
futures = "0.1"
tokio = { version = "1.31.0", features = ["full"] }
tokio-core = "0.1.18"
tun-tap = { path="./modules/tuntap" }
anyhow = "1.0"
tun-tap = { path = "./modules/tuntap" }
13 changes: 9 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@
# #
# ************************************************************************************************************ #

all:
cargo build --release;
all: update re install

clean:
rm -rf ./target/release
Expand All @@ -20,9 +19,15 @@ fclean:
rm -rf ./target;
rm -rf ./Cargo.lock;

re: fclean all
re: fclean build

build:
cargo build --release;

update:
git pull;

build: all
upgrade: update build install

install:
sudo install ./target/release/tardis /usr/local/bin;
Expand Down
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Tardis VPN
Tardis is a high-speed VPN (not encrypted) for server-to-server communication.

## Usage
- **Install Tardis (Ubuntu)**
```bash
sudo apt install -y cargo make
git clone https://github.com/docheio/tardis.git
cd tardis
make all
make install
```

- **Update Tardis**
```bash
make update
make re
make install
```

- **Tardis command usage**
```bash
# Peer mode [peer-to-peer]
tardis peer <LISTEN-IP>:<PORT> <TARGET-IP>:<PORT> <INTERFACE-NAME> <INTERFACE-IP>/<IP-RANGE>

# Server mode [server-to-client]
tardis server <LISTEN-IP>:<PORT> <INTERFACE-NAME> <INTERFACE-IP>/<IP-RANGE>

# Client mode [client-to-server]
tardis client <TARGET-IP>:<PORT> <INTERFACE-NAME> <INTERFACE-IP>/<IP-RANGE>
```
- **Start Service**
```bash
# Must edit config „/etc/systemd/system/tardisd.service“
systemctl enable --now tardisd
```
4 changes: 2 additions & 2 deletions service/tardisd.service
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ After=network.service
Type=simple
ExecStart=/bin/bash -ec "\
LISTEN=0.0.0.0:30000; \
TARGET=192.168.100.1:30000; \
TARGET=172.105.222.222:30000; \
IFNAME=vpn0; \
IP=172.16.42.1/24; \
tardis $LISTEN $TARGET $IFNAME $IP"
tardis peer $LISTEN $TARGET $IFNAME $IP"
ExecStop=/bin/kill -WINCH ${MAINPID}
Restart=always

Expand Down
89 changes: 18 additions & 71 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,76 +10,23 @@
/* */
/* ********************************************************************************************************** */

use std::io::Result;
use std::net::SocketAddr;
use std::process::Command;
use std::{env, process};

use futures::{Future, Stream};
use tokio_core::net::{UdpCodec, UdpSocket};
use tokio_core::reactor::Core;

use tun_tap::asynclib::Async;
use tun_tap::{Iface, Mode};

struct VecCodec(SocketAddr);

impl UdpCodec for VecCodec {
type In = Vec<u8>;
type Out = Vec<u8>;
fn decode(&mut self, _src: &SocketAddr, buf: &[u8]) -> Result<Self::In> {
Ok(buf.to_owned())
mod modules;
use std::env;

use modules::client::client;
use modules::peer::peer;
use modules::server::server;

#[tokio::main(flavor = "multi_thread")]
async fn main() {
let mode = env::args().nth(1).expect("Unable to select mode");
if mode.eq("peer") {
peer().await;
} else if mode.eq("server") {
server().await;
} else if mode.eq("client") {
client().await;
} else {
eprintln!("Unable to select mode");
}
fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> SocketAddr {
buf.extend(&msg);
self.0
}
}

fn cmd(cmd: &str, args: &[&str]) {
let ecode = Command::new(cmd)
.args(args)
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(ecode.success(), "Failed to execte {}", cmd);
}

fn main() {
let mut core = Core::new().unwrap();

// Read Local & Remote IP from args
let loc_address = env::args().nth(1).unwrap().parse().unwrap_or_else(|err| {
eprintln!("Unable to recognize listen ip: {}", err);
process::exit(1);
});
let rem_address = env::args().nth(2).unwrap().parse().unwrap_or_else(|err| {
eprintln!("Unable to recognize remote ip: {}", err);
process::exit(1);
});

// Create socket
let socket = UdpSocket::bind(&loc_address, &core.handle()).unwrap();
let (sender, receiver) = socket.framed(VecCodec(rem_address)).split();

// Create interface
let name = &env::args().nth(3).expect("Unable to read Interface name");
let tap = Iface::new(&name, Mode::Tap).unwrap_or_else(|err| {
eprintln!("Failed to configure the interface name: {}", err);
process::exit(1);
});

// Configure the „local“ (kernel) endpoint.
let ip = &env::args()
.nth(4)
.expect("Unable to recognize remote interface IP");
cmd("ip", &["addr", "add", "dev", tap.name(), &ip]);
cmd("ip", &["link", "set", "up", "dev", tap.name()]);

// Handshake
let (sink, stream) = Async::new(tap, &core.handle()).unwrap().split();
let reader = stream.forward(sender);
let writer = receiver.forward(sink);
core.run(reader.join(writer)).unwrap();
}
107 changes: 107 additions & 0 deletions src/modules/client.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
/* ********************************************************************************************************** */
/* */
/* ::::::::: :::::::: :::::::: ::: ::: :::::::::: */
/* client.rs :+: :+: :+: :+: :+: :+: :+: :+: :+: */
/* +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ */
/* By: se-yukun <[email protected]> +#+ +:+ +#+ +:+ +#+ +#++:++#++ +#++:++# */
/* +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ */
/* Created: 2023/08/18 02:58:41 by se-yukun #+# #+# #+# #+# #+# #+# #+# #+# #+# */
/* Updated: 2023/08/18 02:58:44 by se-yukun ######### ######## ######## ### ### ##########.io. */
/* */
/* ********************************************************************************************************** */

use std::net::SocketAddr;
use std::process::Command;
use std::sync::Arc;
use std::time::Duration;
use std::{env, process, thread};

use std::net::UdpSocket;

use tun_tap::{Iface, Mode};

fn cmd(cmd: &str, args: &[&str]) {
let ecode = Command::new(cmd)
.args(args)
.spawn()
.unwrap()
.wait()
.unwrap();
assert!(ecode.success(), "Failed to execte {}", cmd);
}

pub async fn client() {
// Read Local & Remote IP from args
let loc_address = "0.0.0.0:0".parse::<SocketAddr>().unwrap_or_else(|err| {
eprintln!("Unable to bind udp socket: {}", err);
process::exit(1);
});
let rem_address = env::args()
.nth(2)
.unwrap()
.parse::<SocketAddr>()
.unwrap_or_else(|err| {
eprintln!("Unable to recognize listen ip: {}", err);
process::exit(1);
});

// Create socket
let socket = UdpSocket::bind(&loc_address).unwrap();
let socket = Arc::new(socket);

// Create interface
let name = &env::args().nth(3).expect("Unable to read Interface name");
let iface = Iface::new(&name, Mode::Tap).unwrap_or_else(|err| {
eprintln!("Failed to configure the interface name: {}", err);
process::exit(1);
});
let iface = Arc::new(iface);

// Configure the „local“ (kernel) endpoint.
let ip = &env::args()
.nth(4)
.expect("Unable to recognize remote interface IP");
cmd("ip", &["addr", "add", "dev", iface.name(), &ip]);
cmd("ip", &["link", "set", "up", "dev", iface.name()]);

let iface = Arc::new(iface);
let iface_writer = Arc::clone(&iface);
let iface_reader = Arc::clone(&iface);
let socket_keep = socket.clone();
let socket_send = socket.clone();
let socket_recv = socket.clone();

socket.connect(&rem_address).unwrap();
let buf = vec![0; 1];
socket.send(&buf).unwrap();

let keeper = thread::spawn(move || loop {
thread::sleep(Duration::from_secs(4));
socket_keep.send(&[]).unwrap();
});
let writer = thread::spawn(move || {
println!("w loaded");
loop {
let mut buf = vec![0; 1518];
let len = socket_recv.recv(&mut buf).unwrap();
println!("recv: {:?}", len);
iface_writer.send(&buf[..len]).unwrap();
}
});
let reader = thread::spawn(move || {
println!("r loaded");
loop {
let mut buf = vec![0; 1518];
let len = iface_reader.recv(&mut buf).unwrap();
println!("{:?}", buf);
println!("if recv");
if len > 18 {
socket_send.send(&buf[..len]).unwrap();
println!("send: {:?}", len);
}
}
});
keeper.join().unwrap();
writer.join().unwrap();
reader.join().unwrap();
}
15 changes: 15 additions & 0 deletions src/modules/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* ********************************************************************************************************** */
/* */
/* ::::::::: :::::::: :::::::: ::: ::: :::::::::: */
/* mod.rs :+: :+: :+: :+: :+: :+: :+: :+: :+: */
/* +:+ +:+ +:+ +:+ +:+ +:+ +:+ +:+ */
/* By: se-yukun <[email protected]> +#+ +:+ +#+ +:+ +#+ +#++:++#++ +#++:++# */
/* +#+ +#+ +#+ +#+ +#+ +#+ +#+ +#+ */
/* Created: 2023/08/18 02:58:47 by se-yukun #+# #+# #+# #+# #+# #+# #+# #+# #+# */
/* Updated: 2023/08/18 02:58:48 by se-yukun ######### ######## ######## ### ### ##########.io. */
/* */
/* ********************************************************************************************************** */

pub mod peer;
pub mod server;
pub mod client;
Loading

0 comments on commit cb4aec8

Please sign in to comment.