Skip to content

Commit

Permalink
Implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
TheOnlyArtz committed Oct 29, 2021
0 parents commit 770635f
Show file tree
Hide file tree
Showing 8 changed files with 410 additions and 0 deletions.
1 change: 1 addition & 0 deletions client/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
64 changes: 64 additions & 0 deletions client/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[package]
name = "client"
version = "0.1.0"
authors = ["TheOnlyArtz <[email protected]>"]
edition = "2018"

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

[dependencies]
net2 = "0.2.37"
socket2 = {version="0.4.2", features=["all"]}
152 changes: 152 additions & 0 deletions client/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
// use std::net::{SocketAddr, TcpListener};
// use socket2::{Socket, Domain, Type};
use net2::TcpBuilder;
use std::io::prelude::*;
use std::sync::{Arc, Mutex};

fn main() -> std::io::Result<()> {
let connection_builder = TcpBuilder::new_v4()?;
connection_builder.reuse_address(true).unwrap();

let mut stream = connection_builder.connect("178.128.32.250:3000")?;

let formatted_msg = format!(
"{}:{}",
stream.local_addr()?.ip(),
stream.local_addr()?.port()
);

println!("[ME -> S] publishing local endpoint {}", formatted_msg);
stream.write(formatted_msg.as_bytes())?;

loop {
let mut buf = [0; 1024];
let size = stream.read(&mut buf).unwrap();
let buf = String::from_utf8(buf[..size].to_vec()).unwrap();

println!("[S -> ME] {}", buf);

if size == 0 {
break;
}

let connection_established = Arc::new(Mutex::new(false));
let connection_established_clone = Arc::clone(&connection_established);
let cloned_stream = stream.try_clone().unwrap();

// listen
std::thread::spawn(move || {
let listen_on = cloned_stream.local_addr().unwrap().to_string();
println!(
"[LISTENING] on the same port used to connect to S {}",
listen_on
);
listen(listen_on).unwrap();
});

// PUBLIC
let cloned_stream = stream.try_clone().unwrap();
let buf_clone = buf.clone();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(200));

let ips: Vec<&str> = buf_clone.split("|").collect();
let connect_to = ips.get(0).unwrap();
let laddr = cloned_stream.local_addr().unwrap().to_string();

connect(&laddr, connect_to, connection_established, "public").unwrap();
});

// PRIVATE
let cloned_stream = stream.try_clone().unwrap();
std::thread::spawn(move || {
std::thread::sleep(std::time::Duration::from_millis(200));

let ips: Vec<&str> = (&buf).split("|").collect();
let connect_to = ips.get(1).unwrap();
let laddr = cloned_stream.local_addr().unwrap().to_string();

connect(&laddr, connect_to, connection_established_clone, "private").unwrap();
});
}

Ok(())
}

fn connect(
laddr: &str,
ip: &str,
connection_established: Arc<Mutex<bool>>,
flag: &'static str,
) -> std::io::Result<()> {
let connection_builder = TcpBuilder::new_v4()?;
connection_builder.reuse_address(true).unwrap();
connection_builder.bind(laddr).unwrap();

loop {
let established = *connection_established.lock().unwrap();

if established {
println!("Breaking {} loop cause the other one connected", flag);
break;
}

drop(established);

println!(
"[ME -> B] Trying to connect to {} which is {} from {}",
ip, flag, laddr
);
let stream = connection_builder.connect(ip);

if stream.is_err() {
println!("[ME -> B] Connection failed: repeating");
continue;
}

println!("Connected to {} successfully!", ip);

*connection_established.lock().unwrap() = true;
let mut stream = stream.unwrap();

loop {
let mut buf = [0; 1024];
let size = stream.read(&mut buf);

if size.is_err() {
continue;
}

let size = size.unwrap();
let _buf = String::from_utf8(buf[..size].to_vec()).unwrap();

if size == 0 {
println!("Other peer closed connection!");
break
}
}
}
Ok(())
}

fn listen(ip: String) -> std::io::Result<()> {
let server_builder = TcpBuilder::new_v4()?;
println!("Listening b: {}", ip);
server_builder
.reuse_address(true)
.unwrap()
.bind(ip)
.unwrap();

let server = server_builder.listen(1)?;
for stream in server.incoming() {
let stream = stream.unwrap();

println!(
"[B -> ME] PEER: {:?} | LOCAL: {:?}",
stream.peer_addr().unwrap(),
stream.local_addr().unwrap()
);
}
Ok(())
}
1 change: 1 addition & 0 deletions server/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/target
5 changes: 5 additions & 0 deletions server/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions server/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "server"
version = "0.1.0"
authors = ["TheOnlyArtz <[email protected]>"]
edition = "2018"

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

[dependencies]
Loading

0 comments on commit 770635f

Please sign in to comment.