use toxcore::crypto_core::*;
use toxcore::onion::packet::InnerOnionResponse;
use toxcore::tcp::server::client::Client;
use toxcore::tcp::packet::*;
use toxcore::io_tokio::IoFuture;
use std::io::{Error, ErrorKind};
use std::collections::HashMap;
use std::net::{IpAddr, SocketAddr};
use std::sync::Arc;
use futures::{Sink, Stream, Future, future, stream};
use futures::sync::mpsc;
use parking_lot::RwLock;
#[derive(Default, Clone)]
pub struct Server {
state: Arc<RwLock<ServerState>>,
onion_sink: Option<mpsc::UnboundedSender<(OnionRequest, SocketAddr)>>,
}
#[derive(Default)]
struct ServerState {
pub connected_clients: HashMap<PublicKey, Client>,
pub keys_by_addr: HashMap<(IpAddr, /*port*/ u16), PublicKey>,
}
impl Server {
pub fn new() -> Server {
Server::default()
}
pub fn new_with_onion(onion_sink: mpsc::UnboundedSender<(OnionRequest, SocketAddr)>) -> Server {
Server {
state: Default::default(),
onion_sink: Some(onion_sink),
}
}
pub fn insert(&self, client: Client) {
let mut state = self.state.write();
state.keys_by_addr
.insert((client.ip_addr(), client.port()), client.pk());
state.connected_clients
.insert(client.pk(), client);
}
pub fn handle_packet(&self, pk: &PublicKey, packet: Packet) -> IoFuture<()> {
match packet {
Packet::RouteRequest(packet) => self.handle_route_request(pk, packet),
Packet::RouteResponse(packet) => self.handle_route_response(pk, packet),
Packet::ConnectNotification(packet) => self.handle_connect_notification(pk, packet),
Packet::DisconnectNotification(packet) => self.handle_disconnect_notification(pk, packet),
Packet::PingRequest(packet) => self.handle_ping_request(pk, packet),
Packet::PongResponse(packet) => self.handle_pong_response(pk, packet),
Packet::OobSend(packet) => self.handle_oob_send(pk, packet),
Packet::OobReceive(packet) => self.handle_oob_receive(pk, packet),
Packet::OnionRequest(packet) => self.handle_onion_request(pk, packet),
Packet::OnionResponse(packet) => self.handle_onion_response(pk, packet),
Packet::Data(packet) => self.handle_data(pk, packet),
}
}
pub fn handle_udp_onion_response(&self, ip_addr: IpAddr, port: u16, payload: InnerOnionResponse) -> IoFuture<()> {
let state = self.state.read();
if let Some(client) = state.keys_by_addr.get(&(ip_addr, port)).and_then(|pk| state.connected_clients.get(pk)) {
client.send_onion_response(payload)
} else {
Box::new( future::err(
Error::new(ErrorKind::Other,
"Cannot find client by ip_addr to send onion response"
)))
}
}
pub fn shutdown_client(&self, pk: &PublicKey) -> IoFuture<()> {
let mut state = self.state.write();
let client_a = if let Some(client_a) = state.connected_clients.remove(pk) {
client_a
} else {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"Cannot find client by pk to shutdown it"
)))
};
state.keys_by_addr.remove(&(client_a.ip_addr(), client_a.port()));
let notifications = client_a.iter_links()
.filter_map(|&client_b_pk| client_b_pk)
.map(|client_b_pk| {
if let Some(client_b) = state.connected_clients.get(&client_b_pk) {
if let Some(a_id_in_client_b) = client_b.get_connection_id(pk) {
client_b.send_disconnect_notification(a_id_in_client_b)
} else {
Box::new( future::ok(()) )
}
} else {
Box::new( future::ok(()) )
}
});
Box::new( stream::futures_unordered(notifications).for_each(Ok) )
}
fn handle_route_request(&self, pk: &PublicKey, packet: RouteRequest) -> IoFuture<()> {
let mut state = self.state.write();
let b_id_in_client_a = {
if let Some(client_a) = state.connected_clients.get_mut(pk) {
if pk == &packet.pk {
return client_a.send_route_response(pk, 0)
}
if let Some(b_id_in_client_a) = client_a.get_connection_id(&packet.pk) {
return client_a.send_route_response(&packet.pk, b_id_in_client_a)
} else if let Some(b_id_in_client_a) = client_a.insert_connection_id(&packet.pk) {
b_id_in_client_a
} else {
return client_a.send_route_response(&packet.pk, 0)
}
} else {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"RouteRequest: no such PK"
)))
}
};
let client_a = &state.connected_clients[pk];
if let Some(client_b) = state.connected_clients.get(&packet.pk) {
if let Some(a_id_in_client_b) = client_b.get_connection_id(pk) {
let client_a_notification = client_a.send_connect_notification(b_id_in_client_a);
let client_b_notification = client_b.send_connect_notification(a_id_in_client_b);
return Box::new(
client_a.send_route_response(&packet.pk, b_id_in_client_a)
.join(client_a_notification)
.join(client_b_notification)
.map(|_| ())
)
} else {
client_a.send_route_response(&packet.pk, b_id_in_client_a)
}
} else {
client_a.send_route_response(&packet.pk, b_id_in_client_a)
}
}
fn handle_route_response(&self, _pk: &PublicKey, _packet: RouteResponse) -> IoFuture<()> {
Box::new(future::err(
Error::new(ErrorKind::Other,
"Client must not send RouteResponse to server"
)))
}
fn handle_connect_notification(&self, _pk: &PublicKey, _packet: ConnectNotification) -> IoFuture<()> {
Box::new(future::ok(()))
}
fn handle_disconnect_notification(&self, pk: &PublicKey, packet: DisconnectNotification) -> IoFuture<()> {
if packet.connection_id < 16 {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"DisconnectNotification.connection_id < 16"
)))
}
let mut state = self.state.write();
let client_b_pk = {
if let Some(client_a) = state.connected_clients.get_mut(pk) {
if let Some(client_b_pk) = client_a.take_link(packet.connection_id) {
client_b_pk
} else {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"DisconnectNotification.connection_id is not linked"
)))
}
} else {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"DisconnectNotification: no such PK"
)))
}
};
if let Some(client_b) = state.connected_clients.get_mut(&client_b_pk) {
if let Some(a_id_in_client_b) = client_b.get_connection_id(pk) {
client_b.take_link(a_id_in_client_b);
client_b.send_disconnect_notification(a_id_in_client_b)
} else {
Box::new( future::ok(()) )
}
} else {
Box::new( future::ok(()) )
}
}
fn handle_ping_request(&self, pk: &PublicKey, packet: PingRequest) -> IoFuture<()> {
if packet.ping_id == 0 {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"PingRequest.ping_id == 0"
)))
}
let state = self.state.read();
if let Some(client_a) = state.connected_clients.get(pk) {
client_a.send_pong_response(packet.ping_id)
} else {
Box::new( future::err(
Error::new(ErrorKind::Other,
"PingRequest: no such PK"
)) )
}
}
fn handle_pong_response(&self, pk: &PublicKey, packet: PongResponse) -> IoFuture<()> {
if packet.ping_id == 0 {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"PongResponse.ping_id == 0"
)))
}
let state = self.state.read();
if let Some(client_a) = state.connected_clients.get(pk) {
if packet.ping_id == client_a.ping_id() {
Box::new( future::ok(()) )
} else {
Box::new( future::err(
Error::new(ErrorKind::Other, "PongResponse.ping_id does not match")
))
}
} else {
Box::new( future::err(
Error::new(ErrorKind::Other,
"PongResponse: no such PK"
)) )
}
}
fn handle_oob_send(&self, pk: &PublicKey, packet: OobSend) -> IoFuture<()> {
if packet.data.is_empty() || packet.data.len() > 1024 {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"OobSend wrong data length"
)))
}
let state = self.state.read();
if let Some(client_b) = state.connected_clients.get(&packet.destination_pk) {
client_b.send_oob(pk, packet.data)
} else {
Box::new( future::ok(()) )
}
}
fn handle_oob_receive(&self, _pk: &PublicKey, _packet: OobReceive) -> IoFuture<()> {
Box::new( future::err(
Error::new(ErrorKind::Other,
"Client must not send OobReceive to server"
)))
}
fn handle_onion_request(&self, pk: &PublicKey, packet: OnionRequest) -> IoFuture<()> {
if let Some(ref onion_sink) = self.onion_sink {
let mut state = self.state.read();
if let Some(client) = state.connected_clients.get(&pk) {
let saddr = SocketAddr::new(client.ip_addr(), client.port());
Box::new(onion_sink.clone() .send((packet, saddr))
.map(|_sink| ()) .map_err(|_| {
Error::from(ErrorKind::UnexpectedEof)
})
)
} else {
Box::new( future::err(
Error::new(ErrorKind::Other,
"PongResponse: no such PK"
)) )
}
} else {
Box::new( future::ok(()) )
}
}
fn handle_onion_response(&self, _pk: &PublicKey, _packet: OnionResponse) -> IoFuture<()> {
Box::new( future::err(
Error::new(ErrorKind::Other,
"Client must not send OnionResponse to server"
)))
}
fn handle_data(&self, pk: &PublicKey, packet: Data) -> IoFuture<()> {
if packet.connection_id < 16 {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"Data.connection_id < 16"
)))
}
let state = self.state.read();
let client_b_pk = {
if let Some(client_a) = state.connected_clients.get(pk) {
if let Some(client_b_pk) = client_a.get_link(packet.connection_id) {
client_b_pk
} else {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"Data.connection_id is not linked"
)))
}
} else {
return Box::new( future::err(
Error::new(ErrorKind::Other,
"Data: no such PK"
)))
}
};
if let Some(client_b) = state.connected_clients.get(&client_b_pk) {
if let Some(a_id_in_client_b) = client_b.get_connection_id(pk) {
client_b.send_data(a_id_in_client_b, packet.data)
} else {
Box::new( future::ok(()) )
}
} else {
Box::new( future::ok(()) )
}
}
}
#[cfg(test)]
mod tests {
extern crate rand;
use ::toxcore::crypto_core::*;
use ::toxcore::onion::packet::*;
use ::toxcore::tcp::packet::*;
use ::toxcore::tcp::server::{Client, Server};
use futures::sync::mpsc;
use futures::{Stream, Future};
use quickcheck::{Arbitrary, StdGen};
use std::net::{IpAddr, Ipv4Addr};
#[test]
fn server_is_clonable() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
server.insert(client_1);
let _cloned = server.clone();
}
fn create_random_client() -> (Client, mpsc::UnboundedReceiver<Packet>) {
let mut gen = StdGen::new(rand::thread_rng(), 1024);
let client_ip_addr = IpAddr::arbitrary(&mut gen);
let client_port = u16::arbitrary(&mut gen);
let (client_pk, _) = gen_keypair();
let (tx, rx) = mpsc::unbounded();
let client = Client::new(tx, &client_pk, client_ip_addr, client_port);
(client, rx)
}
#[test]
fn normal_communication_scenario() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
server.insert(client_2);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
server.handle_packet(&client_pk_2, Packet::RouteRequest(
RouteRequest { pk: client_pk_1 }
)).wait().unwrap();
let (packet, rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_1, connection_id: 16 }
));
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::ConnectNotification(
ConnectNotification { connection_id: 16 }
));
let (packet, rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::ConnectNotification(
ConnectNotification { connection_id: 16 }
));
server.handle_packet(&client_pk_1, Packet::Data(
Data { connection_id: 16, data: vec![13, 42] }
)).wait().unwrap();
let (packet, rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::Data(
Data { connection_id: 16, data: vec![13, 42] }
));
server.shutdown_client(&client_pk_1).wait().unwrap();
let (packet, _rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::DisconnectNotification(
DisconnectNotification { connection_id: 16 }
));
}
#[test]
fn handle_route_request() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
}
#[test]
fn handle_route_request_to_itself() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_1 }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_1, connection_id: 0 }
));
}
#[test]
fn handle_route_request_too_many_connections() {
let server = Server::new();
let (client_1, mut rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
for i in 0..240 {
let (other_client, _other_rx) = create_random_client();
let other_client_pk = other_client.pk();
server.insert(other_client);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: other_client_pk }
)).wait().unwrap();
let (packet, rx_1_nested) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: other_client_pk, connection_id: i + 16 }
));
rx_1 = rx_1_nested;
}
let (other_client, _other_rx) = create_random_client();
let other_client_pk = other_client.pk();
server.insert(other_client);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: other_client_pk }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: other_client_pk, connection_id: 0 }
));
}
#[test]
fn handle_connect_notification() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::ConnectNotification(
ConnectNotification { connection_id: 42 }
)).wait();
assert!(handle_res.is_ok());
}
#[test]
fn handle_disconnect_notification() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
server.handle_packet(&client_pk_2, Packet::RouteRequest(
RouteRequest { pk: client_pk_1 }
)).wait().unwrap();
let (packet, rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_1, connection_id: 16 }
));
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::ConnectNotification(
ConnectNotification { connection_id: 16 }
));
let (packet, rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::ConnectNotification(
ConnectNotification { connection_id: 16 }
));
server.handle_packet(&client_pk_1, Packet::DisconnectNotification(
DisconnectNotification { connection_id: 16 }
)).wait().unwrap();
let (packet, _rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::DisconnectNotification(
DisconnectNotification { connection_id: 16 }
));
}
#[test]
fn handle_disconnect_notification_other_not_linked() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification(
DisconnectNotification { connection_id: 16 }
)).wait();
assert!(handle_res.is_ok());
}
#[test]
fn handle_ping_request() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
server.handle_packet(&client_pk_1, Packet::PingRequest(
PingRequest { ping_id: 42 }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::PongResponse(
PongResponse { ping_id: 42 }
));
}
#[test]
fn handle_oob_send() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
server.handle_packet(&client_pk_1, Packet::OobSend(
OobSend { destination_pk: client_pk_2, data: vec![13; 1024] }
)).wait().unwrap();
let (packet, _rx_2) = rx_2.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::OobReceive(
OobReceive { sender_pk: client_pk_1, data: vec![13; 1024] }
));
}
#[test]
fn handle_onion_request() {
let (tcp_onion_sink, tcp_onion_stream) = mpsc::unbounded();
let server = Server::new_with_onion(tcp_onion_sink);
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
let client_addr_1 = client_1.ip_addr();
let client_port_1 = client_1.port();
server.insert(client_1);
let request = OnionRequest {
nonce: gen_nonce(),
ip_port: IpPort {
protocol: ProtocolType::TCP,
ip_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
port: 12345,
},
temporary_pk: gen_keypair().0,
payload: vec![13; 170]
};
let handle_res = server
.handle_packet(&client_pk_1, Packet::OnionRequest(request.clone()))
.wait();
assert!(handle_res.is_ok());
let (packet, _) = tcp_onion_stream.into_future().wait().unwrap();
let (packet, saddr) = packet.unwrap();
assert_eq!(saddr.ip(), client_addr_1);
assert_eq!(saddr.port(), client_port_1);
assert_eq!(packet, request);
}
#[test]
fn handle_udp_onion_response() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_addr_1 = client_1.ip_addr();
let client_port_1 = client_1.port();
server.insert(client_1);
let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse {
sendback_data: 12345,
nonce: gen_nonce(),
payload: vec![42; 123]
});
let handle_res = server
.handle_udp_onion_response(client_addr_1, client_port_1, payload.clone())
.wait();
assert!(handle_res.is_ok());
let (packet, _) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::OnionResponse(
OnionResponse { payload }
));
}
#[test]
fn shutdown_other_not_linked() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
let handle_res = server.shutdown_client(&client_pk_1).wait();
assert!(handle_res.is_ok());
}
#[test]
fn handle_data_other_not_linked() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
let handle_res = server.handle_packet(&client_pk_1, Packet::Data(
Data { connection_id: 16, data: vec![13, 42] }
)).wait();
assert!(handle_res.is_ok());
}
#[test]
fn handle_route_response() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::RouteResponse(
RouteResponse { pk: client_pk_1, connection_id: 42 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_disconnect_notification_0() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification(
DisconnectNotification { connection_id: 0 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_disconnect_notification_not_linked() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification(
DisconnectNotification { connection_id: 16 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_ping_request_0() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::PingRequest(
PingRequest { ping_id: 0 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_pong_response_0() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::PongResponse(
PongResponse { ping_id: 0 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_oob_send_empty_data() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
let handle_res = server.handle_packet(&client_pk_1, Packet::OobSend(
OobSend { destination_pk: client_pk_2, data: vec![] }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_data_0() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::Data(
Data { connection_id: 0, data: vec![13, 42] }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_data_self_not_linked() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::Data(
Data { connection_id: 16, data: vec![13, 42] }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_oob_send_to_loooong_data() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
let handle_res = server.handle_packet(&client_pk_1, Packet::OobSend(
OobSend { destination_pk: client_pk_2, data: vec![42; 1024 + 1] }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_oob_recv() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
let handle_res = server.handle_packet(&client_pk_1, Packet::OobReceive(
OobReceive { sender_pk: client_pk_2, data: vec![42; 1024] }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_onion_request_disabled_onion_loooong_data() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let request = OnionRequest {
nonce: gen_nonce(),
ip_port: IpPort {
protocol: ProtocolType::TCP,
ip_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
port: 12345,
},
temporary_pk: gen_keypair().0,
payload: vec![13; 1500]
};
let handle_res = server
.handle_packet(&client_pk_1, Packet::OnionRequest(request))
.wait();
assert!(handle_res.is_ok());
}
#[test]
fn handle_onion_response() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse {
sendback_data: 12345,
nonce: gen_nonce(),
payload: vec![42; 123]
});
let handle_res = server.handle_packet(&client_pk_1, Packet::OnionResponse(
OnionResponse { payload }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_udp_onion_response_for_unknown_client() {
let (tcp_onion_sink, _) = mpsc::unbounded();
let server = Server::new_with_onion(tcp_onion_sink);
let client_addr_1 = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4));
let client_port_1 = 12345u16;
let (client_pk_1, _) = gen_keypair();
let (tx_1, _rx_1) = mpsc::unbounded();
let client_1 = Client::new(tx_1, &client_pk_1, client_addr_1, client_port_1);
server.insert(client_1);
let client_addr_2 = IpAddr::V4(Ipv4Addr::new(5, 6, 7, 8));
let client_port_2 = 54321u16;
let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse {
sendback_data: 12345,
nonce: gen_nonce(),
payload: vec![42; 123]
});
let handle_res = server
.handle_udp_onion_response(client_addr_2, client_port_2, payload)
.wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_route_request_not_connected() {
let server = Server::new();
let (client_pk_1, _) = gen_keypair();
let (client_pk_2, _) = gen_keypair();
let handle_res = server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_disconnect_notification_not_connected() {
let server = Server::new();
let (client_pk_1, _) = gen_keypair();
let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification(
DisconnectNotification { connection_id: 42 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_disconnect_notification_other_not_connected() {
let server = Server::new();
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_pk_2, _) = gen_keypair();
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification(
DisconnectNotification { connection_id: 16 }
)).wait();
assert!(handle_res.is_ok());
}
#[test]
fn handle_ping_request_not_connected() {
let server = Server::new();
let (client_pk_1, _) = gen_keypair();
let handle_res = server.handle_packet(&client_pk_1, Packet::PingRequest(
PingRequest { ping_id: 42 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_pong_response_not_connected() {
let server = Server::new();
let (client_pk_1, _) = gen_keypair();
let handle_res = server.handle_packet(&client_pk_1, Packet::PongResponse(
PongResponse { ping_id: 42 }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_oob_send_not_connected() {
let server = Server::new();
let (client_pk_1, _) = gen_keypair();
let (client_pk_2, _) = gen_keypair();
let handle_res = server.handle_packet(&client_pk_1, Packet::OobSend(
OobSend { destination_pk: client_pk_2, data: vec![42; 1024] }
)).wait();
assert!(handle_res.is_ok());
}
#[test]
fn handle_data_not_connected() {
let server = Server::new();
let (client_pk_1, _) = gen_keypair();
let handle_res = server.handle_packet(&client_pk_1, Packet::Data(
Data { connection_id: 16, data: vec![13, 42] }
)).wait();
assert!(handle_res.is_err());
}
#[test]
fn handle_data_other_not_connected() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_pk_2, _) = gen_keypair();
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
let handle_res = server.handle_packet(&client_pk_1, Packet::Data(
Data { connection_id: 16, data: vec![13, 42] }
)).wait();
assert!(handle_res.is_ok());
}
#[test]
fn shutdown_not_connected() {
let server = Server::new();
let (client_pk, _) = gen_keypair();
let handle_res = server.shutdown_client(&client_pk).wait();
assert!(handle_res.is_err());
}
#[test]
fn shutdown_other_not_connected() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_pk_2, _) = gen_keypair();
server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait().unwrap();
let (packet, _rx_1) = rx_1.into_future().wait().unwrap();
assert_eq!(packet.unwrap(), Packet::RouteResponse(
RouteResponse { pk: client_pk_2, connection_id: 16 }
));
let handle_res = server.shutdown_client(&client_pk_1).wait();
assert!(handle_res.is_ok());
}
#[test]
fn send_anything_to_dropped_client() {
let server = Server::new();
let (client_1, rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
let (client_2, _rx_2) = create_random_client();
let client_pk_2 = client_2.pk();
server.insert(client_2);
drop(rx_1);
let handle_res = server.handle_packet(&client_pk_1, Packet::RouteRequest(
RouteRequest { pk: client_pk_2 }
)).wait();
assert!(handle_res.is_err())
}
#[test]
fn send_onion_request_to_dropped_stream() {
let (tcp_onion_sink, tcp_onion_stream) = mpsc::unbounded();
let server = Server::new_with_onion(tcp_onion_sink);
let (client_1, _rx_1) = create_random_client();
let client_pk_1 = client_1.pk();
server.insert(client_1);
drop(tcp_onion_stream);
let request = OnionRequest {
nonce: gen_nonce(),
ip_port: IpPort {
protocol: ProtocolType::TCP,
ip_addr: IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
port: 12345,
},
temporary_pk: gen_keypair().0,
payload: vec![13; 170]
};
let handle_res = server
.handle_packet(&client_pk_1, Packet::OnionRequest(request))
.wait();
assert!(handle_res.is_err());
}
}