tunnel 0.2.0

A super easy to use encrypted tunnel with TLS and pre-shared keys.
Documentation
use std::sync::mpsc::{Sender, Receiver, channel};
use std::io::{Read, Write, Result as IoResult};
use std::thread;

use crate::{server, client, SimplePskProvider};

#[derive(Debug)]
struct BiChan {
    send: Sender<u8>,
    recv: Receiver<u8>,
}

impl BiChan {
    fn new() -> (BiChan, BiChan) {
        let (send_1, recv_2) = channel();
        let (send_2, recv_1) = channel();

        (BiChan {
            send: send_1,
            recv: recv_1,
        }, BiChan {
            send: send_2,
            recv: recv_2,
        })
    }
}

impl Write for BiChan {
    fn write(&mut self, buf: &[u8]) -> IoResult<usize> {
        for byte in buf {
            self.send.send(*byte).unwrap();
        }
        Ok(buf.len())
    }

    fn flush(&mut self) -> IoResult<()> {
        Ok(())
    }
}

impl Read for BiChan {
    fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
        let mut bytes_read = 0;
        let mut buf_left = &mut buf[..];
        buf_left[0] = self.recv.recv().unwrap();
        bytes_read += 1;
        buf_left = &mut buf_left[1..];
        if buf_left.len() == 0 {
            return Ok(bytes_read)
        }

        while let Ok(byte) = self.recv.try_recv() {
            buf_left[0] = byte;
            bytes_read += 1;
            buf_left = &mut buf_left[1..];
            if buf_left.len() == 0 {
                return Ok(bytes_read)
            }
        }

        Ok(bytes_read)
    }
}

#[test]
fn test_channels_without_encryption() {
    let (mut a, mut b) = BiChan::new();

    let mut buf = b"                ".to_owned();

    a.write(b"from A to B").unwrap();
    b.read(&mut buf).unwrap();
    assert_eq!(&buf, b"from A to B     ");

    b.write(b"from B to A").unwrap();
    a.read(&mut buf).unwrap();
    assert_eq!(&buf, b"from B to A     ");

    let mut buf = b"                ".to_owned();

    a.write(b"A to B").unwrap();
    b.write(b"B to A").unwrap();

    a.read(&mut buf).unwrap();
    assert_eq!(&buf, b"B to A          ");

    b.read(&mut buf).unwrap();
    assert_eq!(&buf, b"A to B          ");
}

#[test]
fn test_channels_with_encryption() {
    let (a, b) = BiChan::new();

    let joiner = thread::spawn(|| {
        let mut b = client(b, "test", &b"keykeykey"[..]).unwrap();
        let mut buf = b"                ".to_owned();
        b.read(&mut buf).unwrap();
        assert_eq!(&buf, b"from A to B     ");

        b.write(b"from B to A").unwrap();
        let mut buf = b"                ".to_owned();
        b.read(&mut buf).unwrap();
        assert_eq!(&buf, b"A to B          ");
    });
    let mut a = server(a, SimplePskProvider::new(&b"keykeykey"[..])).unwrap();

    let mut buf = b"                ".to_owned();

    a.write(b"from A to B").unwrap();

    a.read(&mut buf).unwrap();
    assert_eq!(&buf, b"from B to A     ");

    a.write(b"A to B").unwrap();

    joiner.join().unwrap();
}

// TODO: test that it is really encrypted and not plaintext
// TODO: test errors