extern crate futures;
extern crate tokio_core;
extern crate cobweb;
extern crate keybob;
use futures::prelude::*;
use tokio_core::net::{UdpSocket, UdpCodec};
use tokio_core::reactor::Core;
use cobweb::Tun;
use keybob::{Key, KeyType};
use std::env;
use std::net::SocketAddr;
use std::io::Result;
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())
}
fn encode(&mut self, msg: Self::Out, buf: &mut Vec<u8>) -> SocketAddr {
buf.extend(&msg);
self.0
}
}
fn main() {
let loc_addr = env::args()
.nth(1)
.unwrap()
.parse()
.unwrap();
let rem_addr = env::args()
.nth(2)
.unwrap()
.parse()
.unwrap();
let mut core = Core::new().unwrap();
let handle = core.handle();
let key = Key::new(KeyType::Aes256);
let tun = Tun::new(&handle)
.unwrap()
.encrypt(&key)
.unwrap();
let (tun_sink, tun_stream) = tun.split();
let sock = UdpSocket::bind(&loc_addr, &handle).unwrap();
sock.send_to(&key.as_slice(), &rem_addr).unwrap();
let (udp_sink, udp_stream) = sock.framed(VecCodec(rem_addr))
.split();
let sender = tun_stream.forward(udp_sink);
let receiver = udp_stream.forward(tun_sink);
core.run(sender.join(receiver))
.unwrap();
}