diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 7da79e94c..5915ad9d6 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -49,6 +49,26 @@ jobs: command: clippy args: -- -D warnings + rustfmt: + name: Rustfmt + runs-on: ubuntu-latest + strategy: + matrix: + rust: + - stable + steps: + - uses: actions/checkout@v2 + - uses: actions-rs/toolchain@v1 + with: + profile: minimal + toolchain: ${{ matrix.rust }} + override: true + - run: rustup component add rustfmt + - uses: actions-rs/cargo@v1 + with: + command: fmt + args: --check + coverage: name: Code coverage runs-on: ubuntu-latest diff --git a/examples/common/mod.rs b/examples/common/mod.rs index a30bc5b8b..c3effbe1c 100644 --- a/examples/common/mod.rs +++ b/examples/common/mod.rs @@ -4,37 +4,62 @@ use tokio::net::UdpSocket; pub const BOOTSTRAP_NODES: [(&str, &str); 9] = [ // Impyy - ("1D5A5F2F5D6233058BF0259B09622FB40B482E4FA0931EB8FD3AB8E7BF7DAF6F", "198.98.51.198:33445"), + ( + "1D5A5F2F5D6233058BF0259B09622FB40B482E4FA0931EB8FD3AB8E7BF7DAF6F", + "198.98.51.198:33445", + ), // nurupo - ("F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67", "67.215.253.85:33445"), + ( + "F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67", + "67.215.253.85:33445", + ), // Manolis - ("461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F", "130.133.110.14:33445"), + ( + "461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F", + "130.133.110.14:33445", + ), // Busindre - ("A179B09749AC826FF01F37A9613F6B57118AE014D4196A0E1105A98F93A54702", "205.185.116.116:33445"), + ( + "A179B09749AC826FF01F37A9613F6B57118AE014D4196A0E1105A98F93A54702", + "205.185.116.116:33445", + ), // ray65536 - ("8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832", "85.172.30.117:33445"), + ( + "8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832", + "85.172.30.117:33445", + ), // fluke571 - ("3CEE1F054081E7A011234883BC4FC39F661A55B73637A5AC293DDF1251D9432B", "194.249.212.109:33445"), + ( + "3CEE1F054081E7A011234883BC4FC39F661A55B73637A5AC293DDF1251D9432B", + "194.249.212.109:33445", + ), // MAH69K - ("DA4E4ED4B697F2E9B000EEFE3A34B554ACD3F45F5C96EAEA2516DD7FF9AF7B43", "185.25.116.107:33445"), + ( + "DA4E4ED4B697F2E9B000EEFE3A34B554ACD3F45F5C96EAEA2516DD7FF9AF7B43", + "185.25.116.107:33445", + ), // clearmartin - ("CD133B521159541FB1D326DE9850F5E56A6C724B5B8E5EB5CD8D950408E95707", "46.101.197.175:443"), + ( + "CD133B521159541FB1D326DE9850F5E56A6C724B5B8E5EB5CD8D950408E95707", + "46.101.197.175:443", + ), // tastytea - ("2B2137E094F743AC8BD44652C55F41DFACC502F125E99E4FE24D40537489E32F", "5.189.176.217:5190"), + ( + "2B2137E094F743AC8BD44652C55F41DFACC502F125E99E4FE24D40537489E32F", + "5.189.176.217:5190", + ), ]; /// Bind a UDP listener to the socket address. pub async fn bind_socket(addr: SocketAddr) -> UdpSocket { - let socket = UdpSocket::bind(&addr) - .await - .expect("Failed to bind UDP socket"); + let socket = UdpSocket::bind(&addr).await.expect("Failed to bind UDP socket"); socket.set_broadcast(true).expect("set_broadcast call failed"); if addr.is_ipv6() { - socket.set_multicast_loop_v6(true) + socket + .set_multicast_loop_v6(true) .expect("set_multicast_loop_v6 call failed"); } socket } - diff --git a/examples/dht_server.rs b/examples/dht_server.rs index 688f6b3ae..e5199dda2 100644 --- a/examples/dht_server.rs +++ b/examples/dht_server.rs @@ -1,24 +1,24 @@ // an example of DHT node with current code // -#![type_length_limit="4194304"] +#![type_length_limit = "4194304"] #[macro_use] extern crate log; -use futures::future::FutureExt; -use futures::channel::mpsc; use anyhow::Error; +use futures::channel::mpsc; +use futures::future::FutureExt; use rand::thread_rng; use std::net::SocketAddr; -use tox_crypto::*; -use tox_packet::dht::packed_node::PackedNode; +use tox_core::dht::lan_discovery::*; use tox_core::dht::server::Server as DhtServer; use tox_core::dht::server_ext::dht_run_socket; -use tox_core::dht::lan_discovery::*; -use tox_core::udp::Server as UdpServer; use tox_core::stats::Stats; +use tox_core::udp::Server as UdpServer; +use tox_crypto::*; +use tox_packet::dht::packed_node::PackedNode; mod common; @@ -42,12 +42,12 @@ async fn main() -> Result<(), Error> { let (tx, rx) = mpsc::channel(32); let local_addr: SocketAddr = "0.0.0.0:33445".parse()?; // 0.0.0.0 for IPv4 + // let local_addr: SocketAddr = "[::]:33445".parse()?; // [::] for IPv6 let stats = Stats::new(); - let mut lan_discovery_sender = - LanDiscoverySender::new(tx.clone(), server_pk.clone(), local_addr.is_ipv6()); + let mut lan_discovery_sender = LanDiscoverySender::new(tx.clone(), server_pk.clone(), local_addr.is_ipv6()); let mut dht_server = DhtServer::new(tx, server_pk, server_sk); dht_server.set_bootstrap_info(3_000_000_000, Box::new(|_| b"This is tox-rs".to_vec())); diff --git a/examples/echo.rs b/examples/echo.rs index 5a8edfb15..f60f50ae5 100644 --- a/examples/echo.rs +++ b/examples/echo.rs @@ -1,49 +1,64 @@ // an example of echo server with current code // -#![recursion_limit="256"] -#![type_length_limit="4194304"] +#![recursion_limit = "256"] +#![type_length_limit = "4194304"] #[macro_use] extern crate log; -use futures::{*, future::TryFutureExt}; +use anyhow::Error; use futures::channel::mpsc; +use futures::{future::TryFutureExt, *}; use hex::FromHex; -use anyhow::Error; use rand::thread_rng; use std::net::SocketAddr; use tox_binary_io::*; -use tox_crypto::*; -use tox_packet::dht::packed_node::PackedNode; -use tox_packet::friend_connection::*; -use tox_packet::onion::InnerOnionResponse; -use tox_packet::relay::DataPayload; -use tox_packet::toxid::ToxId; +use tox_core::dht::lan_discovery::LanDiscoverySender; use tox_core::dht::server::Server as DhtServer; use tox_core::dht::server_ext::dht_run_socket; -use tox_core::dht::lan_discovery::LanDiscoverySender; -use tox_core::udp::Server as UdpServer; use tox_core::friend_connection::FriendConnections; use tox_core::net_crypto::{NetCrypto, NetCryptoNewArgs}; use tox_core::onion::client::OnionClient; use tox_core::relay::client::{Connections, IncomingPacket}; use tox_core::stats::Stats; +use tox_core::udp::Server as UdpServer; +use tox_crypto::*; +use tox_packet::dht::packed_node::PackedNode; +use tox_packet::friend_connection::*; +use tox_packet::onion::InnerOnionResponse; +use tox_packet::relay::DataPayload; +use tox_packet::toxid::ToxId; mod common; const TCP_RELAYS: [(&str, &str); 5] = [ // ray65536 - ("8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832", "85.172.30.117:33445"), + ( + "8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832", + "85.172.30.117:33445", + ), // MAH69K - ("DA4E4ED4B697F2E9B000EEFE3A34B554ACD3F45F5C96EAEA2516DD7FF9AF7B43", "185.25.116.107:33445"), + ( + "DA4E4ED4B697F2E9B000EEFE3A34B554ACD3F45F5C96EAEA2516DD7FF9AF7B43", + "185.25.116.107:33445", + ), // Deliran - ("1C5293AEF2114717547B39DA8EA6F1E331E5E358B35F9B6B5F19317911C5F976", "84.22.115.205:33445"), + ( + "1C5293AEF2114717547B39DA8EA6F1E331E5E358B35F9B6B5F19317911C5F976", + "84.22.115.205:33445", + ), // kpp - ("A04F5FE1D006871588C8EC163676458C1EC75B20B4A147433D271E1E85DAF839", "52.53.185.100:33445"), + ( + "A04F5FE1D006871588C8EC163676458C1EC75B20B4A147433D271E1E85DAF839", + "52.53.185.100:33445", + ), // kurnevsky - ("82EF82BA33445A1F91A7DB27189ECFC0C013E06E3DA71F588ED692BED625EC23", "37.139.29.40:33445"), + ( + "82EF82BA33445A1F91A7DB27189ECFC0C013E06E3DA71F588ED692BED625EC23", + "37.139.29.40:33445", + ), ]; #[tokio::main] @@ -59,12 +74,13 @@ async fn main() -> Result<(), Error> { let real_sk = SecretKey::generate(&mut rng); let real_pk = real_sk.public_key(); let id = ToxId::new(&mut rng, real_pk.clone()); - println!("your tox id is: {:X}",id); + println!("your tox id is: {:X}", id); // Create a channel for server to communicate with network let (tx, rx) = mpsc::channel(32); let local_addr: SocketAddr = "0.0.0.0:33447".parse()?; // 0.0.0.0 for IPv4 + // let local_addr: SocketAddr = "[::]:33445".parse()?; // [::] for IPv6 info!("Running echo server on {}", local_addr); @@ -81,7 +97,12 @@ async fn main() -> Result<(), Error> { dht_server.enable_ipv6_mode(local_addr.is_ipv6()); let tcp_connections = Connections::new(dht_pk.clone(), dht_sk.clone(), tcp_incoming_tx); - let onion_client = OnionClient::new(dht_server.clone(), tcp_connections.clone(), real_sk.clone(), real_pk.clone()); + let onion_client = OnionClient::new( + dht_server.clone(), + tcp_connections.clone(), + real_sk.clone(), + real_pk.clone(), + ); let (lossless_tx, mut lossless_rx) = mpsc::unbounded(); let (lossy_tx, mut lossy_rx) = mpsc::unbounded(); @@ -137,18 +158,46 @@ async fn main() -> Result<(), Error> { let onion_client_c = onion_client.clone(); let net_crypto_c = net_crypto.clone(); let tcp_incoming_future = async { - while let Some((_relay_pk, packet)) = tcp_incoming_rx.next().await { // TODO: do we need relay_pk at all? + while let Some((_relay_pk, packet)) = tcp_incoming_rx.next().await { + // TODO: do we need relay_pk at all? match packet { IncomingPacket::Data(sender_pk, packet) => match packet { - DataPayload::CookieRequest(packet) => net_crypto_c.handle_tcp_cookie_request(&packet, sender_pk).map_err(Error::from).await, - DataPayload::CookieResponse(packet) => net_crypto_c.handle_tcp_cookie_response(&packet, sender_pk).map_err(Error::from).await, - DataPayload::CryptoHandshake(packet) => net_crypto_c.handle_tcp_crypto_handshake(&packet, sender_pk).map_err(Error::from).await, - DataPayload::CryptoData(packet) => net_crypto_c.handle_tcp_crypto_data(&packet, sender_pk).map_err(Error::from).await, + DataPayload::CookieRequest(packet) => { + net_crypto_c + .handle_tcp_cookie_request(&packet, sender_pk) + .map_err(Error::from) + .await + } + DataPayload::CookieResponse(packet) => { + net_crypto_c + .handle_tcp_cookie_response(&packet, sender_pk) + .map_err(Error::from) + .await + } + DataPayload::CryptoHandshake(packet) => { + net_crypto_c + .handle_tcp_crypto_handshake(&packet, sender_pk) + .map_err(Error::from) + .await + } + DataPayload::CryptoData(packet) => { + net_crypto_c + .handle_tcp_crypto_data(&packet, sender_pk) + .map_err(Error::from) + .await + } }, IncomingPacket::Oob(_sender_pk, _packet) => Ok(()), IncomingPacket::Onion(packet) => match packet { - InnerOnionResponse::OnionAnnounceResponse(packet) => onion_client_c.handle_announce_response(&packet, true).map_err(Error::from).await, - InnerOnionResponse::OnionDataResponse(packet) => onion_client_c.handle_data_response(&packet).map_err(Error::from).await, + InnerOnionResponse::OnionAnnounceResponse(packet) => { + onion_client_c + .handle_announce_response(&packet, true) + .map_err(Error::from) + .await + } + InnerOnionResponse::OnionDataResponse(packet) => { + onion_client_c.handle_data_response(&packet).map_err(Error::from).await + } }, }?; } @@ -166,24 +215,36 @@ async fn main() -> Result<(), Error> { match packet[0] { PACKET_ID_ALIVE => { friend_connections_c.handle_ping(pk).await; - }, - PACKET_ID_SHARE_RELAYS => { - match ShareRelays::from_bytes(&packet) { - Ok((_, share_relays)) => - friend_connections_c.handle_share_relays(pk, share_relays) - .map_err(Error::from).await?, - _ => return Err(Error::msg("Failed to parse ShareRelays")) + } + PACKET_ID_SHARE_RELAYS => match ShareRelays::from_bytes(&packet) { + Ok((_, share_relays)) => { + friend_connections_c + .handle_share_relays(pk, share_relays) + .map_err(Error::from) + .await? } + _ => return Err(Error::msg("Failed to parse ShareRelays")), }, - 0x18 => { // PACKET_ID_ONLINE - net_crypto_c.send_lossless(pk.clone(), vec![0x18]).map_err(Error::from).await?; - net_crypto_c.send_lossless(pk.clone(), vec![0x32, 0x00]).map_err(Error::from).await?; // PACKET_ID_USERSTATUS - net_crypto_c.send_lossless(pk, b"\x30tox-rs".to_vec()).map_err(Error::from).await?; - }, - 0x40 => { // PACKET_ID_CHAT_MESSAGE + 0x18 => { + // PACKET_ID_ONLINE + net_crypto_c + .send_lossless(pk.clone(), vec![0x18]) + .map_err(Error::from) + .await?; + net_crypto_c + .send_lossless(pk.clone(), vec![0x32, 0x00]) + .map_err(Error::from) + .await?; // PACKET_ID_USERSTATUS + net_crypto_c + .send_lossless(pk, b"\x30tox-rs".to_vec()) + .map_err(Error::from) + .await?; + } + 0x40 => { + // PACKET_ID_CHAT_MESSAGE net_crypto_c.send_lossless(pk, packet).map_err(Error::from).await?; - }, - _ => { }, + } + _ => {} } } Result::<(), Error>::Ok(()) @@ -212,7 +273,10 @@ async fn main() -> Result<(), Error> { // create PK from bytes let relay_pk = PublicKey::from(relay_pk_bytes); - tcp_connections.add_relay_global(saddr.parse().unwrap(), relay_pk).await.map_err(Error::from)?; + tcp_connections + .add_relay_global(saddr.parse().unwrap(), relay_pk) + .await + .map_err(Error::from)?; } futures::select!( diff --git a/examples/onion_client.rs b/examples/onion_client.rs index aef512839..773fe7c8b 100644 --- a/examples/onion_client.rs +++ b/examples/onion_client.rs @@ -1,25 +1,25 @@ #[macro_use] extern crate log; -use std::net::{SocketAddr, IpAddr}; +use std::net::{IpAddr, SocketAddr}; use anyhow::Error; +use futures::channel::mpsc; use futures::future::FutureExt; -use futures::stream::StreamExt; use futures::sink::SinkExt; -use futures::channel::mpsc; +use futures::stream::StreamExt; use rand::thread_rng; use tokio_util::udp::UdpFramed; -use tox_crypto::*; -use tox_packet::dht::*; -use tox_packet::dht::packed_node::PackedNode; use tox_core::dht::codec::*; use tox_core::dht::ip_port::IsGlobal; use tox_core::dht::server::Server; use tox_core::onion::client::*; use tox_core::relay::client::Connections; use tox_core::stats::Stats; +use tox_crypto::*; +use tox_packet::dht::packed_node::PackedNode; +use tox_packet::dht::*; mod common; @@ -57,6 +57,7 @@ async fn main() -> Result<(), Error> { let (tx, mut rx) = mpsc::channel(32); let local_addr: SocketAddr = "0.0.0.0:33445".parse().unwrap(); // 0.0.0.0 for IPv4 + // let local_addr: SocketAddr = "[::]:33445".parse().unwrap(); // [::] for IPv6 let is_ipv4 = local_addr.is_ipv4(); @@ -108,19 +109,21 @@ async fn main() -> Result<(), Error> { Packet::OnionAnnounceResponse(packet) => { let is_global = IsGlobal::is_global(&addr.ip()); - onion_client.handle_announce_response(&packet, is_global).await + onion_client + .handle_announce_response(&packet, is_global) + .await .map_err(Error::from) - }, - Packet::OnionDataResponse(packet) => - onion_client.handle_data_response(&packet).await - .map_err(Error::from), + } + Packet::OnionDataResponse(packet) => { + onion_client.handle_data_response(&packet).await.map_err(Error::from) + } _ => Ok(()), }; if let Err(err) = res { error!("Failed to handle packet: {:?}", err); - return Err(err) + return Err(err); } } @@ -129,7 +132,9 @@ async fn main() -> Result<(), Error> { let network_writer = async { while let Some((packet, mut addr)) = rx.next().await { - if is_ipv4 && addr.is_ipv6() { continue } + if is_ipv4 && addr.is_ipv6() { + continue; + } if !is_ipv4 { if let IpAddr::V4(ip) = addr.ip() { @@ -138,22 +143,20 @@ async fn main() -> Result<(), Error> { } trace!("Sending packet {:?} to {:?}", packet, addr); - sink.send((packet, addr)).await - .map_err(Error::from)? + sink.send((packet, addr)).await.map_err(Error::from)? } Ok(()) }; - let dht_pk_future = dht_pk_rx - .for_each(|(real_pk, dht_pk)| { - let real_pk = hex::encode(real_pk.as_ref()); - let dht_pk = hex::encode(dht_pk); + let dht_pk_future = dht_pk_rx.for_each(|(real_pk, dht_pk)| { + let real_pk = hex::encode(real_pk.as_ref()); + let dht_pk = hex::encode(dht_pk); - println!("Found DHT PK for {} - {}", real_pk, dht_pk); + println!("Found DHT PK for {} - {}", real_pk, dht_pk); - futures::future::ready(()) - }); + futures::future::ready(()) + }); info!("Running onion client on {}", local_addr); diff --git a/examples/tcp_client.rs b/examples/tcp_client.rs index b50576428..ca5f58493 100644 --- a/examples/tcp_client.rs +++ b/examples/tcp_client.rs @@ -1,23 +1,23 @@ #[macro_use] extern crate log; +use tox_core::relay::codec; +use tox_core::relay::handshake::make_client_handshake; +use tox_core::stats::Stats; use tox_crypto::*; use tox_packet::dht::CryptoData; use tox_packet::relay::connection_id::ConnectionId; use tox_packet::relay::*; -use tox_core::relay::handshake::make_client_handshake; -use tox_core::relay::codec; -use tox_core::stats::Stats; use anyhow::Error; use hex::FromHex; -use futures::prelude::*; use futures::channel::mpsc; +use futures::prelude::*; -use tokio_util::codec::Framed; use tokio::net::TcpStream; +use tokio_util::codec::Framed; // Notice that create_client create a future of client processing. // The future will live untill all copies of tx is dropped or there is a IO error @@ -25,36 +25,38 @@ use tokio::net::TcpStream; // Comment out pong responser and client will be destroyed when there will be no messages to send async fn create_client(mut rx: mpsc::Receiver, tx: mpsc::Sender) -> Result<(), Error> { // Client constant keypair for examples/tests - let client_pk = PublicKey::from([252, 72, 40, 127, 213, 13, 0, 95, - 13, 230, 176, 49, 69, 252, 220, 132, - 48, 73, 227, 58, 218, 154, 215, 245, - 23, 189, 223, 216, 153, 237, 130, 88]); - let client_sk = SecretKey::from([157, 128, 29, 197, 1, 72, 47, 56, - 65, 81, 191, 67, 220, 225, 108, 193, - 46, 163, 145, 242, 139, 125, 159, - 137, 174, 14, 225, 7, 138, 120, 185, 153]); + let client_pk = PublicKey::from([ + 252, 72, 40, 127, 213, 13, 0, 95, 13, 230, 176, 49, 69, 252, 220, 132, 48, 73, 227, 58, 218, 154, 215, 245, 23, + 189, 223, 216, 153, 237, 130, 88, + ]); + let client_sk = SecretKey::from([ + 157, 128, 29, 197, 1, 72, 47, 56, 65, 81, 191, 67, 220, 225, 108, 193, 46, 163, 145, 242, 139, 125, 159, 137, + 174, 14, 225, 7, 138, 120, 185, 153, + ]); let (addr, server_pk) = match 1 { 1 => { // local tcp relay server from example let addr: std::net::SocketAddr = "0.0.0.0:12345".parse().unwrap(); // Server constant PK for examples/tests - let server_pk = PublicKey::from([177, 185, 54, 250, 10, 168, 174, - 148, 0, 93, 99, 13, 131, 131, 239, - 193, 129, 141, 80, 158, 50, 133, 100, - 182, 179, 183, 234, 116, 142, 102, 53, 38]); + let server_pk = PublicKey::from([ + 177, 185, 54, 250, 10, 168, 174, 148, 0, 93, 99, 13, 131, 131, 239, 193, 129, 141, 80, 158, 50, 133, + 100, 182, 179, 183, 234, 116, 142, 102, 53, 38, + ]); (addr, server_pk) - }, + } 2 => { // remote tcp relay server - let server_pk_bytes: [u8; 32] = FromHex::from_hex("461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F").unwrap(); + let server_pk_bytes: [u8; 32] = + FromHex::from_hex("461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F").unwrap(); let server_pk = PublicKey::from(server_pk_bytes); let addr = "130.133.110.14:33445".parse().unwrap(); (addr, server_pk) - }, + } 3 => { // local C DHT node, TODO remove this case - let server_pk_bytes: [u8; 32] = FromHex::from_hex("C4B8D288C391704E3C8840A8A7C19B21D0B76CAF3B55341D37C5A9732887F879").unwrap(); + let server_pk_bytes: [u8; 32] = + FromHex::from_hex("C4B8D288C391704E3C8840A8A7C19B21D0B76CAF3B55341D37C5A9732887F879").unwrap(); let server_pk = PublicKey::from(server_pk_bytes); let addr = "0.0.0.0:33445".parse().unwrap(); (addr, server_pk) @@ -78,11 +80,10 @@ async fn create_client(mut rx: mpsc::Receiver, tx: mpsc::Sender) debug!("Got packet {:?}", packet); // Simple pong responser if let Packet::PingRequest(ping) = packet { - tx.clone().send(Packet::PongResponse( - PongResponse { ping_id: ping.ping_id } - )) - .map_err(|_| Error::msg("Could not send pong") ) - .await?; + tx.clone() + .send(Packet::PongResponse(PongResponse { ping_id: ping.ping_id })) + .map_err(|_| Error::msg("Could not send pong")) + .await?; } } Ok(()) @@ -107,8 +108,7 @@ async fn main() -> Result<(), Error> { let (mut tx, rx) = mpsc::channel(1); - let client = create_client(rx, tx.clone()) - .inspect(|res| println!("Client ended with {:?}", res)); + let client = create_client(rx, tx.clone()).inspect(|res| println!("Client ended with {:?}", res)); let packet_sender = async { let mut i = 0u64; @@ -119,11 +119,11 @@ async fn main() -> Result<(), Error> { i += 1; if i == 1 { // Client friend constant PK for examples/tests - let friend_pk = PublicKey::from([15, 107, 126, 130, 81, 55, 154, 157, - 192, 117, 0, 225, 119, 43, 48, 117, - 84, 109, 112, 57, 243, 216, 4, 171, - 185, 111, 33, 146, 221, 31, 77, 118]); - tx.send(Packet::RouteRequest(RouteRequest { pk: friend_pk } )).await?; + let friend_pk = PublicKey::from([ + 15, 107, 126, 130, 81, 55, 154, 157, 192, 117, 0, 225, 119, 43, 48, 117, 84, 109, 112, 57, 243, + 216, 4, 171, 185, 111, 33, 146, 221, 31, 77, 118, + ]); + tx.send(Packet::RouteRequest(RouteRequest { pk: friend_pk })).await?; } else { tx.send(Packet::Data(Data { connection_id: ConnectionId::from_index(0), @@ -131,7 +131,8 @@ async fn main() -> Result<(), Error> { nonce_last_bytes: 42, payload: vec![42; 123], }), - })).await?; + })) + .await?; } } Result::<(), Error>::Ok(()) diff --git a/examples/tcp_server.rs b/examples/tcp_server.rs index 2454436be..55c62726f 100644 --- a/examples/tcp_server.rs +++ b/examples/tcp_server.rs @@ -2,9 +2,9 @@ extern crate log; use anyhow::Error; -use tox_crypto::*; -use tox_core::relay::server::{Server, tcp_run}; +use tox_core::relay::server::{tcp_run, Server}; use tox_core::stats::Stats; +use tox_crypto::*; use tokio::net::TcpListener; @@ -15,16 +15,12 @@ async fn main() -> Result<(), Error> { env_logger::init(); // Server constant PK for examples/tests let server_pk = PublicKey::from([ - 177, 185, 54, 250, 10, 168, 174, - 148, 0, 93, 99, 13, 131, 131, 239, - 193, 129, 141, 80, 158, 50, 133, 100, - 182, 179, 183, 234, 116, 142, 102, 53, 38 + 177, 185, 54, 250, 10, 168, 174, 148, 0, 93, 99, 13, 131, 131, 239, 193, 129, 141, 80, 158, 50, 133, 100, 182, + 179, 183, 234, 116, 142, 102, 53, 38, ]); let server_sk = SecretKey::from([ - 74, 163, 57, 111, 32, 145, 19, 40, - 44, 145, 233, 210, 173, 67, 88, 217, - 140, 147, 14, 176, 106, 255, 54, 249, - 159, 12, 18, 39, 123, 29, 125, 230 + 74, 163, 57, 111, 32, 145, 19, 40, 44, 145, 233, 210, 173, 67, 88, 217, 140, 147, 14, 176, 106, 255, 54, 249, + 159, 12, 18, 39, 123, 29, 125, 230, ]); let addr: std::net::SocketAddr = "0.0.0.0:12345".parse().unwrap(); @@ -35,5 +31,7 @@ async fn main() -> Result<(), Error> { let stats = Stats::new(); let listener = TcpListener::bind(&addr).await.unwrap(); - tcp_run(&server, listener, server_sk, stats, TCP_CONNECTIONS_LIMIT).await.map_err(Error::from) + tcp_run(&server, listener, server_sk, stats, TCP_CONNECTIONS_LIMIT) + .await + .map_err(Error::from) } diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 000000000..113fecc84 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,2 @@ +max_width = 120 +use_try_shorthand = true diff --git a/tox/src/lib.rs b/tox/src/lib.rs index ac2d99490..13912f1b2 100644 --- a/tox/src/lib.rs +++ b/tox/src/lib.rs @@ -1,6 +1,6 @@ //! This crate rexports all tox crates in tox-rs. -pub use tox_packet as packet; pub use tox_core as core; pub use tox_crypto as crypto; pub use tox_encryptsave as encryptsave; +pub use tox_packet as packet; diff --git a/tox_binary_io/src/crypto.rs b/tox_binary_io/src/crypto.rs index baebfe8bd..5cc695bd1 100644 --- a/tox_binary_io/src/crypto.rs +++ b/tox_binary_io/src/crypto.rs @@ -1,17 +1,19 @@ use std::convert::TryInto; -use nom::IResult; use nom::bytes::streaming::take; use nom::combinator::{map, map_opt}; +use nom::IResult; use crypto_box::{PublicKey, SecretKey, KEY_SIZE}; use super::FromBytes; - impl FromBytes for PublicKey { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - map(map_opt(take(KEY_SIZE), |pk: &[u8]| pk.try_into().ok()), |pk: [u8; KEY_SIZE]| pk.into())(input) + map( + map_opt(take(KEY_SIZE), |pk: &[u8]| pk.try_into().ok()), + |pk: [u8; KEY_SIZE]| pk.into(), + )(input) } } @@ -30,7 +32,10 @@ impl FromBytes for PublicKey { impl FromBytes for SecretKey { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - map(map_opt(take(KEY_SIZE), |sk: &[u8]| sk.try_into().ok()), |sk: [u8; KEY_SIZE]| sk.into())(input) + map( + map_opt(take(KEY_SIZE), |sk: &[u8]| sk.try_into().ok()), + |sk: [u8; KEY_SIZE]| sk.into(), + )(input) } } diff --git a/tox_binary_io/src/lib.rs b/tox_binary_io/src/lib.rs index 99e5b08f7..430784839 100644 --- a/tox_binary_io/src/lib.rs +++ b/tox_binary_io/src/lib.rs @@ -1,17 +1,16 @@ -pub use nom::IResult; pub use cookie_factory::GenError; +pub use nom::IResult; +use cookie_factory::{do_gen, gen_be_u8, gen_le_u16, gen_slice}; use nom::bytes::streaming::take; use nom::combinator::{map, map_opt}; use nom::multi::count; -use nom::number::complete::{le_u8, le_u16}; -use cookie_factory::{do_gen, gen_be_u8, gen_le_u16, gen_slice}; +use nom::number::complete::{le_u16, le_u8}; -use std::{convert::TryInto, net::{ - IpAddr, - Ipv4Addr, - Ipv6Addr, -}}; +use std::{ + convert::TryInto, + net::{IpAddr, Ipv4Addr, Ipv6Addr}, +}; #[cfg(feature = "crypto")] pub use crypto::*; @@ -41,9 +40,7 @@ impl ToBytes for IpAddr { impl FromBytes for Ipv4Addr { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - map(count(le_u8, 4), - |v| Ipv4Addr::new(v[0], v[1], v[2], v[3]) - )(input) + map(count(le_u8, 4), |v| Ipv4Addr::new(v[0], v[1], v[2], v[3]))(input) } } @@ -53,13 +50,14 @@ impl ToBytes for [u8; N] { } } -impl FromBytes for [u8; N] { +impl FromBytes for [u8; N] { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { map_opt(take(N), |bytes: &[u8]| bytes.try_into().ok())(input) } } impl ToBytes for Ipv4Addr { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { let o = self.octets(); do_gen!(buf, @@ -73,13 +71,14 @@ impl ToBytes for Ipv4Addr { impl FromBytes for Ipv6Addr { fn from_bytes(i: &[u8]) -> IResult<&[u8], Self> { - map(count(le_u16, 8), - |v| Ipv6Addr::new(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) - )(i) + map(count(le_u16, 8), |v| { + Ipv6Addr::new(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) + })(i) } } impl ToBytes for Ipv6Addr { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { let s = self.segments(); do_gen!(buf, diff --git a/tox_core/src/dht/codec.rs b/tox_core/src/dht/codec.rs index dc789d8c7..4eda7577b 100644 --- a/tox_core/src/dht/codec.rs +++ b/tox_core/src/dht/codec.rs @@ -3,14 +3,14 @@ use std::io::Error as IoError; -use tox_packet::dht::*; -use tox_binary_io::*; use crate::stats::*; +use tox_binary_io::*; +use tox_packet::dht::*; use bytes::BytesMut; use cookie_factory::GenError; -use thiserror::Error; use nom::error::Error as NomError; +use thiserror::Error; use tokio_util::codec::{Decoder, Encoder}; /// A serialized `Packet` should be not longer than 2048 bytes. @@ -23,7 +23,7 @@ pub enum DecodeError { #[error("Packet should not be longer than 2048 bytes: {} bytes", len)] TooBigPacket { /// Length of received packet. - len: usize + len: usize, }, /// Error indicates that received packet can't be parsed. #[error("Deserialize Packet error: {:?}, packet: {:?}", error, packet)] @@ -44,7 +44,10 @@ impl DecodeError { } pub(crate) fn deserialize(e: nom::Err>, packet: Vec) -> DecodeError { - DecodeError::Deserialize { error: e.map(|e| NomError::new(e.input.to_vec(), e.code)), packet } + DecodeError::Deserialize { + error: e.map(|e| NomError::new(e.input.to_vec(), e.code)), + packet, + } } } @@ -55,7 +58,7 @@ pub enum EncodeError { #[error("Serialize Packet error: {:?}", error)] Serialize { /// Serialization error. - error: GenError + error: GenError, }, /// General IO error that can happen with UDP socket. #[error("IO Error")] @@ -89,9 +92,7 @@ pub struct DhtCodec { impl DhtCodec { /// Make object pub fn new(stats: Stats) -> Self { - DhtCodec { - stats - } + DhtCodec { stats } } } @@ -106,13 +107,11 @@ impl Decoder for DhtCodec { let len = buf.len(); if len > MAX_DHT_PACKET_SIZE { - return Err(DecodeError::too_big_packet(len)) + return Err(DecodeError::too_big_packet(len)); } let result = match Packet::from_bytes(buf) { - Err(error) => { - Err(DecodeError::deserialize(error, buf.to_vec())) - }, + Err(error) => Err(DecodeError::deserialize(error, buf.to_vec())), Ok((_, packet)) => { // Add 1 to incoming counter self.stats.counters.increase_incoming(); @@ -132,26 +131,28 @@ impl Encoder for DhtCodec { fn encode(&mut self, packet: Packet, buf: &mut BytesMut) -> Result<(), Self::Error> { let mut packet_buf = [0; MAX_DHT_PACKET_SIZE]; - packet.to_bytes((&mut packet_buf, 0)) + packet + .to_bytes((&mut packet_buf, 0)) .map(|(packet_buf, size)| { // Add 1 to outgoing counter self.stats.counters.increase_outgoing(); buf.extend(&packet_buf[..size]); }) - .map_err(|error| - EncodeError::serialize(error) - ) + .map_err(|error| EncodeError::serialize(error)) } } #[cfg(test)] mod tests { use super::*; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, SecretKey, + }; + use nom::{error::ErrorKind as NomErrorKind, Err}; use rand::thread_rng; use tox_packet::onion::*; - use crypto_box::{SalsaBox, SecretKey, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; - use nom::{Err, error::ErrorKind as NomErrorKind}; const ONION_RETURN_1_PAYLOAD_SIZE: usize = ONION_RETURN_1_SIZE - xsalsa20poly1305::NONCE_SIZE; const ONION_RETURN_2_PAYLOAD_SIZE: usize = ONION_RETURN_2_SIZE - xsalsa20poly1305::NONCE_SIZE; @@ -197,7 +198,7 @@ mod tests { Packet::OnionRequest0(OnionRequest0 { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut thread_rng()).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }), Packet::OnionRequest1(OnionRequest1 { nonce: [42; ::NonceSize::USIZE], @@ -205,8 +206,8 @@ mod tests { payload: vec![42; 123], onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], + }, }), Packet::OnionRequest2(OnionRequest2 { nonce: [42; ::NonceSize::USIZE], @@ -214,78 +215,78 @@ mod tests { payload: vec![42; 123], onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], + }, }), Packet::OnionAnnounceRequest(OnionAnnounceRequest { inner: InnerOnionAnnounceRequest { nonce: [42; ::NonceSize::USIZE], pk: SecretKey::generate(&mut thread_rng()).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }, onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], + }, }), Packet::OnionDataRequest(OnionDataRequest { inner: InnerOnionDataRequest { destination_pk: SecretKey::generate(&mut thread_rng()).public_key(), nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut thread_rng()).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }, onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], + }, }), Packet::OnionDataResponse(OnionDataResponse { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut thread_rng()).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }), Packet::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }), Packet::OnionResponse3(OnionResponse3 { onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }, payload: InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] - }) + payload: vec![42; 123], + }), }), Packet::OnionResponse2(OnionResponse2 { onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], }, payload: InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] - }) + payload: vec![42; 123], + }), }), Packet::OnionResponse1(OnionResponse1 { onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], }, payload: InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] - }) + payload: vec![42; 123], + }), }), Packet::BootstrapInfo(BootstrapInfo { version: 42, - motd: vec![1, 2, 3, 4] + motd: vec![1, 2, 3, 4], }), ]; @@ -306,13 +307,13 @@ mod tests { let mut codec = DhtCodec::new(stats); let mut buf = BytesMut::new(); let packet = Packet::PingRequest(PingRequest { - pk: SecretKey::generate(&mut thread_rng()).public_key(), - nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 88], - }); - let mut packet_buf = [0;256]; + pk: SecretKey::generate(&mut thread_rng()).public_key(), + nonce: [42; ::NonceSize::USIZE], + payload: vec![42; 88], + }); + let mut packet_buf = [0; 256]; let (_, size) = packet.to_bytes((&mut packet_buf, 0)).unwrap(); - buf.extend_from_slice(&packet_buf[..(size-90)]); + buf.extend_from_slice(&packet_buf[..(size - 90)]); // not enought bytes to decode EncryptedPacket assert!(codec.decode(&mut buf).is_err()); @@ -328,7 +329,16 @@ mod tests { let res = codec.decode(&mut buf); // not enough bytes to decode EncryptedPacket - assert!(matches!(res, Err(DecodeError::Deserialize { error: Err::Error(NomError { input: _, code: NomErrorKind::Tag }), packet: _ }))); + assert!(matches!( + res, + Err(DecodeError::Deserialize { + error: Err::Error(NomError { + input: _, + code: NomErrorKind::Tag + }), + packet: _ + }) + )); } #[test] diff --git a/tox_core/src/dht/daemon_state.rs b/tox_core/src/dht/daemon_state.rs index e13d5cf41..2eda4b63a 100644 --- a/tox_core/src/dht/daemon_state.rs +++ b/tox_core/src/dht/daemon_state.rs @@ -6,14 +6,14 @@ Toxcore daemon may serialize its states to file with some interval. use futures::future; +use crate::dht::kbucket::*; +use crate::dht::ktree::*; use crate::dht::server::*; use crate::state_format::old::*; use tox_binary_io::*; -use crate::dht::kbucket::*; -use crate::dht::ktree::*; +use nom::{error::Error as NomError, Err}; use thiserror::Error; -use nom::{Err, error::Error as NomError}; /// An error that can occur while serializing/deserializing object. #[derive(Debug, PartialEq, Error)] @@ -30,7 +30,10 @@ pub enum DeserializeError { impl DeserializeError { pub(crate) fn deserialize(e: Err>, data: Vec) -> DeserializeError { - DeserializeError::Deserialize { error: e.map(|e| NomError::new(e.input.to_vec(), e.code)), data } + DeserializeError::Deserialize { + error: e.map(|e| NomError::new(e.input.to_vec(), e.code)), + data, + } } } @@ -44,10 +47,12 @@ pub const DHT_STATE_BUFFER_SIZE: usize = ( // PackedNode size ( - 32 + // PK size - 19 // SocketAddr maximum size - ) * KBUCKET_DEFAULT_SIZE as usize // num of DhtNodes per Kbucket : 8 - ) * KBUCKET_MAX_ENTRIES as usize; // 255 + // PK size + 32 + + // SocketAddr maximum size + 19 + ) * KBUCKET_DEFAULT_SIZE as usize + ) * KBUCKET_MAX_ENTRIES as usize; impl DaemonState { /// Serialize DHT states, old means that the format of seriaization is old version @@ -55,7 +60,9 @@ impl DaemonState { let nodes = server.get_all_nodes().await; let mut buf = [0u8; DHT_STATE_BUFFER_SIZE]; - let (_, buf_len) = DhtState(nodes).to_bytes((&mut buf, 0)).expect("DhtState(nodes).to_bytes has failed"); + let (_, buf_len) = DhtState(nodes) + .to_bytes((&mut buf, 0)) + .expect("DhtState(nodes).to_bytes has failed"); buf[..buf_len].to_vec() } @@ -63,16 +70,11 @@ impl DaemonState { /// Deserialize DHT close list and then re-setup close list, old means that the format of deserialization is old version pub async fn deserialize_old(server: &Server, serialized_data: &[u8]) -> Result<(), DeserializeError> { let nodes = match DhtState::from_bytes(serialized_data) { - Err(error) => { - return Err(DeserializeError::deserialize(error, serialized_data.to_vec())) - }, - Ok((_, DhtState(nodes))) => { - nodes - } + Err(error) => return Err(DeserializeError::deserialize(error, serialized_data.to_vec())), + Ok((_, DhtState(nodes))) => nodes, }; - let nodes_sender = nodes.into_iter() - .map(|node| server.ping_node(node)); + let nodes_sender = nodes.into_iter().map(|node| server.ping_node(node)); future::join_all(nodes_sender).await; @@ -86,20 +88,20 @@ mod tests { use rand::thread_rng; use tox_crypto::*; - use tox_packet::dht::*; use tox_packet::dht::packed_node::*; + use tox_packet::dht::*; use futures::channel::mpsc; use futures::StreamExt; use nom::error::ErrorKind as NomErrorKind; macro_rules! unpack { - ($variable:expr, $variant:path) => ( + ($variable:expr, $variant:path) => { match $variable { $variant(inner) => inner, other => panic!("Expected {} but got {:?}", stringify!($variant), other), } - ) + }; } #[tokio::test] @@ -116,7 +118,10 @@ mod tests { let addr_org = "1.2.3.4:1234".parse().unwrap(); let pk_org = SecretKey::generate(&mut rng).public_key(); - let pn = PackedNode { pk: pk_org.clone(), saddr: addr_org }; + let pn = PackedNode { + pk: pk_org.clone(), + saddr: addr_org, + }; alice.add_node(pn).await; let serialized_vec = DaemonState::serialize_old(&alice).await; @@ -138,14 +143,24 @@ mod tests { let error = res.err().unwrap(); let mut input = vec![2, 1, 2, 3, 4, 4, 210]; input.extend_from_slice(&pk_org.as_bytes()[..crypto_box::KEY_SIZE - 1]); - assert_eq!(error, DeserializeError::Deserialize { error: Err::Error(NomError::new( - input, NomErrorKind::Eof)), data: serialized_vec[..serialized_len - 1].to_vec() }); + assert_eq!( + error, + DeserializeError::Deserialize { + error: Err::Error(NomError::new(input, NomErrorKind::Eof)), + data: serialized_vec[..serialized_len - 1].to_vec() + } + ); // test with serialized data corrupted let serialized_vec = [42; 10]; let res = DaemonState::deserialize_old(&alice, &serialized_vec).await; let error = res.err().unwrap(); - assert_eq!(error, DeserializeError::Deserialize { error: Err::Error(NomError::new( - vec![42; 10], NomErrorKind::Tag)), data: serialized_vec.to_vec() }); + assert_eq!( + error, + DeserializeError::Deserialize { + error: Err::Error(NomError::new(vec![42; 10], NomErrorKind::Tag)), + data: serialized_vec.to_vec() + } + ); } } diff --git a/tox_core/src/dht/dht_friend.rs b/tox_core/src/dht/dht_friend.rs index f6f5417ff..452a2af63 100644 --- a/tox_core/src/dht/dht_friend.rs +++ b/tox_core/src/dht/dht_friend.rs @@ -2,16 +2,16 @@ Module for friend. */ -use std::time::Instant; -use std::net::SocketAddr; use rand::{CryptoRng, Rng}; +use std::net::SocketAddr; +use std::time::Instant; -use crate::time::*; +use crate::dht::dht_node::*; use crate::dht::kbucket::*; +use crate::dht::server::hole_punching::*; +use crate::time::*; use tox_crypto::*; -use crate::dht::dht_node::*; use tox_packet::dht::packed_node::*; -use crate::dht::server::hole_punching::*; /// Number of bootstrap nodes each friend has. pub const FRIEND_BOOTSTRAP_NODES_COUNT: u8 = 4; @@ -57,8 +57,7 @@ impl DhtFriend { pub fn is_addr_known(&self) -> bool { // Since nodes in Kbucket are sorted by distance to our PublicKey the // node with the same PublicKey will be always the first - self.close_nodes.nodes.first() - .map_or(false, |node| node.pk == self.pk) + self.close_nodes.nodes.first().map_or(false, |node| node.pk == self.pk) } /// Get addresses of friend that returned by his close nodes. Close nodes @@ -98,8 +97,8 @@ impl DhtFriend { mod tests { use super::*; - use std::time::Duration; use rand::thread_rng; + use std::time::Duration; #[test] fn addr_is_unknown() { @@ -107,8 +106,14 @@ mod tests { let pk = SecretKey::generate(&mut rng).public_key(); let mut friend = DhtFriend::new(&mut thread_rng(), pk); - assert!(friend.try_add_to_close(PackedNode::new("192.168.1.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()))); - assert!(friend.try_add_to_close(PackedNode::new("192.168.1.2:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()))); + assert!(friend.try_add_to_close(PackedNode::new( + "192.168.1.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key() + ))); + assert!(friend.try_add_to_close(PackedNode::new( + "192.168.1.2:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key() + ))); assert!(!friend.is_addr_known()) } @@ -119,8 +124,14 @@ mod tests { let pk = SecretKey::generate(&mut rng).public_key(); let mut friend = DhtFriend::new(&mut thread_rng(), pk.clone()); - assert!(friend.try_add_to_close(PackedNode::new("192.168.1.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()))); - assert!(friend.try_add_to_close(PackedNode::new("192.168.1.2:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()))); + assert!(friend.try_add_to_close(PackedNode::new( + "192.168.1.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key() + ))); + assert!(friend.try_add_to_close(PackedNode::new( + "192.168.1.2:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key() + ))); assert!(friend.try_add_to_close(PackedNode::new("192.168.1.3:12345".parse().unwrap(), pk))); @@ -134,9 +145,18 @@ mod tests { let mut friend = DhtFriend::new(&mut thread_rng(), pk.clone()); let nodes = [ - PackedNode::new("192.168.1.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("192.168.1.2:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("192.168.1.3:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), + PackedNode::new( + "192.168.1.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "192.168.1.2:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "192.168.1.3:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), ]; let addrs: Vec = vec![ "192.168.2.1:12345".parse().unwrap(), @@ -167,9 +187,18 @@ mod tests { let mut friend = DhtFriend::new(&mut thread_rng(), pk.clone()); let nodes = [ - PackedNode::new("192.168.1.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("192.168.1.2:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("192.168.1.3:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), + PackedNode::new( + "192.168.1.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "192.168.1.2:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "192.168.1.3:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), ]; let addrs: Vec = vec![ "192.168.2.1:12345".parse().unwrap(), @@ -194,7 +223,7 @@ mod tests { let pk = PublicKey::from([0; crypto_box::KEY_SIZE]); let mut friend = DhtFriend::new(&mut thread_rng(), pk); - for i in 0 .. 8 { + for i in 0..8 { let addr = SocketAddr::new("1.2.3.4".parse().unwrap(), 12345 + u16::from(i)); let node = PackedNode::new(addr, PublicKey::from([i + 2; crypto_box::KEY_SIZE])); assert!(friend.try_add_to_close(node)); @@ -202,7 +231,7 @@ mod tests { let closer_node = PackedNode::new( "1.2.3.5:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); // should add a new closer node with eviction diff --git a/tox_core/src/dht/dht_node.rs b/tox_core/src/dht/dht_node.rs index fb01d4a47..f983ea691 100644 --- a/tox_core/src/dht/dht_node.rs +++ b/tox_core/src/dht/dht_node.rs @@ -9,10 +9,10 @@ Here, GOOD node is the node responded within 162 seconds, BAD node is the node n use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::time::{Duration, Instant}; -use tox_crypto::*; use crate::dht::kbucket::*; -use tox_packet::dht::packed_node::*; use crate::time::*; +use tox_crypto::*; +use tox_packet::dht::packed_node::*; /// Ping interval for each node in our lists. pub const PING_INTERVAL: Duration = Duration::from_secs(60); @@ -21,8 +21,7 @@ pub const PING_INTERVAL: Duration = Duration::from_secs(60); pub const BAD_NODE_TIMEOUT: Duration = Duration::from_secs(PING_INTERVAL.as_secs() * 2 + 2); /// The timeout after which a node is discarded completely. -pub const KILL_NODE_TIMEOUT: Duration = - Duration::from_secs(BAD_NODE_TIMEOUT.as_secs() + PING_INTERVAL.as_secs()); +pub const KILL_NODE_TIMEOUT: Duration = Duration::from_secs(BAD_NODE_TIMEOUT.as_secs() + PING_INTERVAL.as_secs()); /// Struct conatains SocketAddrs and timestamps for sending and receiving packet #[derive(Clone, Debug, Eq, PartialEq)] @@ -42,11 +41,7 @@ pub struct SockAndTime + Copy> { impl + Copy> SockAndTime { /// Create SockAndTime object pub fn new(saddr: Option) -> Self { - let last_resp_time = if saddr.is_some() { - Some(clock_now()) - } else { - None - }; + let last_resp_time = if saddr.is_some() { Some(clock_now()) } else { None }; SockAndTime { saddr, last_resp_time, @@ -58,18 +53,21 @@ impl + Copy> SockAndTime { /// Check if the address is considered bad i.e. it does not answer on /// addresses for `BAD_NODE_TIMEOUT`. pub fn is_bad(&self) -> bool { - self.last_resp_time.map_or(true, |time| clock_elapsed(time) > BAD_NODE_TIMEOUT) + self.last_resp_time + .map_or(true, |time| clock_elapsed(time) > BAD_NODE_TIMEOUT) } /// Check if the node is considered discarded i.e. it does not answer on /// addresses for `KILL_NODE_TIMEOUT`. pub fn is_discarded(&self) -> bool { - self.last_resp_time.map_or(true, |time| clock_elapsed(time) > KILL_NODE_TIMEOUT) + self.last_resp_time + .map_or(true, |time| clock_elapsed(time) > KILL_NODE_TIMEOUT) } /// Check if `PING_INTERVAL` is passed after last ping request. pub fn is_ping_interval_passed(&self) -> bool { - self.last_ping_req_time.map_or(true, |time| clock_elapsed(time) >= PING_INTERVAL) + self.last_ping_req_time + .map_or(true, |time| clock_elapsed(time) >= PING_INTERVAL) } /// Get address if it should be pinged and update `last_ping_req_time`. @@ -147,7 +145,11 @@ impl DhtNode { /// Returns all available socket addresses of DhtNode pub fn get_all_addrs(&self) -> Vec { - let addrs = self.assoc4.saddr.into_iter().map(SocketAddr::V4) + let addrs = self + .assoc4 + .saddr + .into_iter() + .map(SocketAddr::V4) .chain(self.assoc6.saddr.into_iter().map(SocketAddr::V6)) .collect::>(); @@ -180,11 +182,11 @@ impl DhtNode { SocketAddr::V4(v4) => { self.assoc4.ret_saddr = Some(v4); self.assoc4.ret_last_resp_time = Some(clock_now()); - }, + } SocketAddr::V6(v6) => { self.assoc6.ret_saddr = Some(v6); self.assoc6.ret_last_resp_time = Some(clock_now()); - }, + } } } } @@ -206,15 +208,15 @@ impl KbucketNode for DhtNode { type CheckNode = PackedNode; fn is_outdated(&self, other: &PackedNode) -> bool { - self.assoc4.saddr.map(SocketAddr::V4) != Some(other.saddr) && - self.assoc6.saddr.map(SocketAddr::V6) != Some(other.saddr) + self.assoc4.saddr.map(SocketAddr::V4) != Some(other.saddr) + && self.assoc6.saddr.map(SocketAddr::V6) != Some(other.saddr) } fn update(&mut self, other: &PackedNode) { match other.saddr { SocketAddr::V4(sock_v4) => { self.assoc4.saddr = Some(sock_v4); self.assoc4.last_resp_time = Some(clock_now()); - }, + } SocketAddr::V6(sock_v6) => { self.assoc6.saddr = Some(sock_v6); self.assoc6.last_resp_time = Some(clock_now()); @@ -225,8 +227,9 @@ impl KbucketNode for DhtNode { self.is_bad() } fn eviction_index(nodes: &[Self]) -> Option { - nodes.iter().rposition(|n| n.is_discarded()).or_else(|| - nodes.iter().rposition(|n| n.is_bad()) - ) + nodes + .iter() + .rposition(|n| n.is_discarded()) + .or_else(|| nodes.iter().rposition(|n| n.is_bad())) } } diff --git a/tox_core/src/dht/forced_ktree.rs b/tox_core/src/dht/forced_ktree.rs index c50599fca..a0f4f7a67 100644 --- a/tox_core/src/dht/forced_ktree.rs +++ b/tox_core/src/dht/forced_ktree.rs @@ -2,12 +2,12 @@ use std::cmp::Ordering; use itertools::Itertools; -use tox_crypto::*; -use tox_packet::dht::packed_node::*; use crate::dht::dht_node::*; +use crate::dht::ip_port::IsGlobal; use crate::dht::kbucket::*; use crate::dht::ktree::*; -use crate::dht::ip_port::IsGlobal; +use tox_crypto::*; +use tox_packet::dht::packed_node::*; /** K-buckets structure to hold up to ([`KBUCKET_MAX_ENTRIES`](./constant.KBUCKET_MAX_ENTRIES.html) + 1) * @@ -41,18 +41,18 @@ impl ForcedKtree { /// Get reference to a `DhtNode` by it's `PublicKey`. pub fn get_node(&self, pk: &PublicKey) -> Option<&DhtNode> { - self.ktree.get_node(pk).or_else(|| - self.kbucket.get_node(&self.ktree.pk, pk) - ) + self.ktree + .get_node(pk) + .or_else(|| self.kbucket.get_node(&self.ktree.pk, pk)) } /// Get mutable reference to a `DhtNode` by it's `PublicKey`. pub fn get_node_mut(&mut self, pk: &PublicKey) -> Option<&mut DhtNode> { let base_pk = self.ktree.pk.clone(); let bucket = &mut self.kbucket; - self.ktree.get_node_mut(pk).or_else(move || - bucket.get_node_mut(&base_pk, pk) - ) + self.ktree + .get_node_mut(pk) + .or_else(move || bucket.get_node_mut(&base_pk, pk)) } /** Add [`PackedNode`](./struct.PackedNode.html) to `Kbucket`. @@ -87,9 +87,9 @@ impl ForcedKtree { /// Remove [`DhtNode`](./struct.DhtNode.html) with given PK from the /// `Kbucket`. pub fn remove(&mut self, node_pk: &PublicKey) -> Option { - self.ktree.remove(node_pk).or_else(|| - self.kbucket.remove(&self.ktree.pk, node_pk) - ) + self.ktree + .remove(node_pk) + .or_else(|| self.kbucket.remove(&self.ktree.pk, node_pk)) } /** Get (up to) `count` closest nodes to given PK. @@ -119,8 +119,7 @@ impl ForcedKtree { [`PackedNode`]: ./struct.PackedNode.html */ pub fn contains(&self, pk: &PublicKey) -> bool { - self.kbucket.contains(&self.ktree.pk, pk) || - self.ktree.contains(pk) + self.kbucket.contains(&self.ktree.pk, pk) || self.ktree.contains(pk) } /** @@ -135,8 +134,9 @@ impl ForcedKtree { [`PackedNode`]: ./struct.PackedNode.html */ pub fn can_add(&self, new_node: &PackedNode) -> bool { - self.ktree.can_add(new_node) || - !self.ktree.contains(&new_node.pk) && self.kbucket.can_add(&self.ktree.pk, new_node, /* evict */ true) + self.ktree.can_add(new_node) + || !self.ktree.contains(&new_node.pk) + && self.kbucket.can_add(&self.ktree.pk, new_node, /* evict */ true) } /** Check if `Kbucket` is empty. @@ -145,8 +145,7 @@ impl ForcedKtree { otherwise. */ pub fn is_empty(&self) -> bool { - self.ktree.is_empty() && - self.kbucket.is_empty() + self.ktree.is_empty() && self.kbucket.is_empty() } /// Create iterator over [`DhtNode`](./struct.DhtNode.html)s in `Kbucket`. @@ -154,9 +153,9 @@ impl ForcedKtree { /// `PublicKey` (in ascending order). pub fn iter(&self) -> impl Iterator { let pk = self.ktree.pk.clone(); - self.ktree.iter().merge_by(self.kbucket.iter(), move |x, y| + self.ktree.iter().merge_by(self.kbucket.iter(), move |x, y| { pk.distance(&x.pk, &y.pk) == Ordering::Less - ) + }) } /// Create mutable iterator over [`DhtNode`](./struct.DhtNode.html)s in @@ -164,9 +163,9 @@ impl ForcedKtree { /// base `PublicKey` (in ascending order). pub fn iter_mut(&mut self) -> impl Iterator { let pk = self.ktree.pk.clone(); - self.ktree.iter_mut().merge_by(self.kbucket.iter_mut(), move |x, y| + self.ktree.iter_mut().merge_by(self.kbucket.iter_mut(), move |x, y| { pk.distance(&x.pk, &y.pk) == Ordering::Less - ) + }) } /// Check if all nodes in Kbucket are discarded @@ -179,9 +178,9 @@ impl ForcedKtree { mod tests { use super::*; + use rand::thread_rng; use std::net::SocketAddr; use std::time::Duration; - use rand::thread_rng; // ForcedKtree::try_add() @@ -190,7 +189,7 @@ mod tests { let pk = PublicKey::from([0; crypto_box::KEY_SIZE]); let mut ktree = ForcedKtree::new(pk); - for i in 0 .. 8 { + for i in 0..8 { let mut pk = [i + 2; crypto_box::KEY_SIZE]; // make first bit differ from base pk so all these nodes will get // into the first kbucket @@ -206,10 +205,7 @@ mod tests { let mut pk = [1; crypto_box::KEY_SIZE]; pk[0] = 255; let pk = PublicKey::from(pk); - let node = PackedNode::new( - "1.2.3.5:12345".parse().unwrap(), - pk - ); + let node = PackedNode::new("1.2.3.5:12345".parse().unwrap(), pk); assert!(ktree.try_add(node)); } @@ -222,11 +218,11 @@ mod tests { let node1 = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); let node2 = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([2; crypto_box::KEY_SIZE]) + PublicKey::from([2; crypto_box::KEY_SIZE]), ); // "removing" non-existent node @@ -258,20 +254,24 @@ mod tests { PackedNode::new(addr, PublicKey::from([i + 1; crypto_box::KEY_SIZE])) } - for i in 0 .. 4 { + for i in 0..4 { assert!(ktree.try_add(node_by_idx(i))); } - for i in 4 .. 8 { + for i in 4..8 { assert!(ktree.kbucket.try_add(&pk, node_by_idx(i), /* evict */ true)); } - for count in 1 ..= 4 { - let closest: Vec<_> = ktree.get_closest(&PublicKey::from([0; crypto_box::KEY_SIZE]), count, true).into(); - let should_be = (0 .. count).map(node_by_idx).collect::>(); + for count in 1..=4 { + let closest: Vec<_> = ktree + .get_closest(&PublicKey::from([0; crypto_box::KEY_SIZE]), count, true) + .into(); + let should_be = (0..count).map(node_by_idx).collect::>(); assert_eq!(closest, should_be); - let closest: Vec<_> = ktree.get_closest(&PublicKey::from([255; crypto_box::KEY_SIZE]), count, true).into(); - let should_be = (8 - count .. 8).rev().map(node_by_idx).collect::>(); + let closest: Vec<_> = ktree + .get_closest(&PublicKey::from([255; crypto_box::KEY_SIZE]), count, true) + .into(); + let should_be = (8 - count..8).rev().map(node_by_idx).collect::>(); assert_eq!(closest, should_be); } } @@ -288,17 +288,16 @@ mod tests { let node = PackedNode::new( "1.2.3.5:12345".parse().unwrap(), - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ); assert!(!ktree.contains(&node.pk)); assert!(ktree.try_add(node.clone())); assert!(ktree.contains(&node.pk)); - let node = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); assert!(!ktree.contains(&node.pk)); @@ -313,7 +312,7 @@ mod tests { let pk = PublicKey::from([0; crypto_box::KEY_SIZE]); let mut ktree = ForcedKtree::new(pk); - for i in 0 .. 16 { + for i in 0..16 { let mut pk = [i + 2; crypto_box::KEY_SIZE]; // make first bit differ from base pk so all these nodes will get // into the first kbucket @@ -330,20 +329,14 @@ mod tests { let mut pk = [1; crypto_box::KEY_SIZE]; pk[0] = 255; let pk = PublicKey::from(pk); - let node = PackedNode::new( - "1.2.3.5:12345".parse().unwrap(), - pk - ); + let node = PackedNode::new("1.2.3.5:12345".parse().unwrap(), pk); assert!(ktree.can_add(&node)); let mut pk = [18; crypto_box::KEY_SIZE]; pk[0] = 255; let pk = PublicKey::from(pk); - let node = PackedNode::new( - "1.2.3.5:12345".parse().unwrap(), - pk - ); + let node = PackedNode::new("1.2.3.5:12345".parse().unwrap(), pk); assert!(!ktree.can_add(&node)); } @@ -363,10 +356,10 @@ mod tests { PackedNode::new(addr, PublicKey::from([i + 1; crypto_box::KEY_SIZE])) } - for i in 0 .. 4 { + for i in 0..4 { assert!(ktree.try_add(node_by_idx(i))); } - for i in 4 .. 8 { + for i in 4..8 { assert!(ktree.kbucket.try_add(&pk, node_by_idx(i), /* evict */ true)); } @@ -393,10 +386,10 @@ mod tests { PackedNode::new(addr, PublicKey::from([i + 1; crypto_box::KEY_SIZE])) } - for i in 0 .. 4 { + for i in 0..4 { assert!(ktree.try_add(node_by_idx(i))); } - for i in 4 .. 8 { + for i in 4..8 { assert!(ktree.kbucket.try_add(&pk, node_by_idx(i), /* evict */ true)); } @@ -418,13 +411,13 @@ mod tests { let node = PackedNode::new( "1.2.3.4:33445".parse().unwrap(), - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ); assert!(ktree.try_add(node)); let node = PackedNode::new( "1.2.3.5:12345".parse().unwrap(), - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ); assert!(ktree.kbucket.try_add(&pk, node, /* evict */ true)); diff --git a/tox_core/src/dht/ip_port.rs b/tox_core/src/dht/ip_port.rs index f7b2db6af..5248f4d78 100644 --- a/tox_core/src/dht/ip_port.rs +++ b/tox_core/src/dht/ip_port.rs @@ -46,22 +46,24 @@ impl IsGlobal for IpAddr { if addrs[0] == 100 && (addrs[1] & 0xC0) == 0x40 { return false; } - }, + } IpAddr::V6(ipv6) => { let addrs = ipv6.octets(); /* autogenerated for each interface: FE80::* (up to FEBF::*) - FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ - if (addrs[0] == 0xFF && addrs[1] < 3 && addrs[15] == 1) || - (addrs[0] == 0xFE && (addrs[1] & 0xC0) == 0x80) { + FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */ + if (addrs[0] == 0xFF && addrs[1] < 3 && addrs[15] == 1) + || (addrs[0] == 0xFE && (addrs[1] & 0xC0) == 0x80) + { return false; } /* embedded IPv4-in-IPv6 */ if let Some(ipv4) = ipv6.to_ipv4() { return IsGlobal::is_global(&IpAddr::V4(ipv4)); - } else {} - }, + } else { + } + } }; true diff --git a/tox_core/src/dht/kbucket.rs b/tox_core/src/dht/kbucket.rs index fc68baa35..67819fdc4 100644 --- a/tox_core/src/dht/kbucket.rs +++ b/tox_core/src/dht/kbucket.rs @@ -26,11 +26,14 @@ According to the [spec](https://zetok.github.io/tox-spec#bucket-index). Fails (returns `None`) only if supplied keys are the same. */ pub fn kbucket_index(own_pk: &PublicKey, other_pk: &PublicKey) -> Option { - debug!(target: "KBucketIndex", "Calculating KBucketIndex for PKs."); trace!(target: "KBucketIndex", "With PK1: {:?}; PK2: {:?}", own_pk, other_pk); - let xoring = own_pk.as_bytes().iter().zip(other_pk.as_bytes().iter()).map(|(x, y)| x ^ y); + let xoring = own_pk + .as_bytes() + .iter() + .zip(other_pk.as_bytes().iter()) + .map(|(x, y)| x ^ y); for (i, byte) in xoring.enumerate() { for j in 0..8 { if byte & (0x80 >> j) != 0 { @@ -38,7 +41,7 @@ pub fn kbucket_index(own_pk: &PublicKey, other_pk: &PublicKey) -> Option { } } } - None // PKs are equal + None // PKs are equal } /// Trait for functionality related to distance between `PublicKey`s. @@ -50,11 +53,13 @@ pub trait Distance { impl Distance for PublicKey { fn distance(&self, pk1: &PublicKey, pk2: &PublicKey) -> Ordering { - trace!(target: "Distance", "Comparing distance between PKs."); for i in 0..crypto_box::KEY_SIZE { if pk1.as_bytes()[i] != pk2.as_bytes()[i] { - return Ord::cmp(&(self.as_bytes()[i] ^ pk1.as_bytes()[i]), &(self.as_bytes()[i] ^ pk2.as_bytes()[i])) + return Ord::cmp( + &(self.as_bytes()[i] ^ pk1.as_bytes()[i]), + &(self.as_bytes()[i] ^ pk2.as_bytes()[i]), + ); } } Ordering::Equal @@ -74,7 +79,7 @@ impl HasPk for PackedNode { } /// Node that can be stored in a `Kbucket`. -pub trait KbucketNode : Sized + HasPk { +pub trait KbucketNode: Sized + HasPk { /// The type of nodes that can be added to a `Kbucket`. type NewNode: HasPk; /// The type of nodes that can be checked if they can be added to a @@ -152,7 +157,7 @@ impl Kbucket where NewNode: HasPk, CheckNode: HasPk, - Node: KbucketNode + From + Node: KbucketNode + From, { /** Create a new `Kbucket` to store nodes close to the `PublicKey`. @@ -172,8 +177,7 @@ where /// Get reference to a `KbucketNode` by it's `PublicKey`. pub fn get_node(&self, base_pk: &PublicKey, pk: &PublicKey) -> Option<&Node> { - self.find(base_pk, pk) - .map(move |node_index| &self.nodes[node_index]) + self.find(base_pk, pk).map(move |node_index| &self.nodes[node_index]) } /// Get mutable reference to a `KbucketNode` by it's `PublicKey`. @@ -209,13 +213,16 @@ where pub fn try_add(&mut self, base_pk: &PublicKey, new_node: NewNode, evict: bool) -> bool { trace!(target: "Kbucket", "Trying to add PackedNode: {:?}.", new_node.pk()); - match self.nodes.binary_search_by(|n| base_pk.distance(&n.pk(), &new_node.pk())) { + match self + .nodes + .binary_search_by(|n| base_pk.distance(&n.pk(), &new_node.pk())) + { Ok(index) => { debug!(target: "Kbucket", "Updated: the node was already in the kbucket."); self.nodes[index].update(&new_node); true - }, + } Err(index) if !evict || index == self.nodes.len() => { // index is pointing past the end // we are not going to evict the farthest node or the current @@ -242,7 +249,7 @@ where self.nodes.insert(index, new_node.into()); true } - }, + } Err(index) => { // index is pointing inside the list // we are going to evict the farthest node if the kbucket is full @@ -258,7 +265,7 @@ where debug!(target: "Kbucket", "Node inserted inside the kbucket."); } true - }, + } } } @@ -336,19 +343,28 @@ where [`PackedNode`]: ./struct.PackedNode.html */ pub fn can_add(&self, base_pk: &PublicKey, new_node: &CheckNode, evict: bool) -> bool { - match self.nodes.binary_search_by(|n| base_pk.distance(&n.pk(), &new_node.pk())) { + match self + .nodes + .binary_search_by(|n| base_pk.distance(&n.pk(), &new_node.pk())) + { Ok(index) => - // if node is bad then we'd want to update it's address - self.nodes[index].is_evictable() || self.nodes[index].is_outdated(new_node), + // if node is bad then we'd want to update it's address + { + self.nodes[index].is_evictable() || self.nodes[index].is_outdated(new_node) + } Err(index) if !evict || index == self.nodes.len() => - // can't find node in the kbucket - // we are not going to evict the farthest node or the current - // node is the farthest one - !self.is_full() || self.nodes.iter().any(|n| n.is_evictable()), + // can't find node in the kbucket + // we are not going to evict the farthest node or the current + // node is the farthest one + { + !self.is_full() || self.nodes.iter().any(|n| n.is_evictable()) + } Err(_index) => - // can't find node in the kbucket - // we are going to evict the farthest node if the kbucket is full - true, + // can't find node in the kbucket + // we are going to evict the farthest node if the kbucket is full + { + true + } } } @@ -373,11 +389,7 @@ mod tests { use super::*; - use std::net::{ - Ipv4Addr, - SocketAddr, - SocketAddrV4, - }; + use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4}; use std::time::Duration; use crate::dht::dht_node::*; @@ -413,7 +425,7 @@ mod tests { let pk = PublicKey::from([0; crypto_box::KEY_SIZE]); let mut kbucket = Kbucket::::new(KBUCKET_DEFAULT_SIZE); - for i in 0 .. 8 { + for i in 0..8 { let addr = SocketAddr::new("1.2.3.4".parse().unwrap(), 12345 + u16::from(i)); let node = PackedNode::new(addr, PublicKey::from([i + 2; crypto_box::KEY_SIZE])); assert!(kbucket.try_add(&pk, node, /* evict */ false)); @@ -421,15 +433,15 @@ mod tests { let closer_node = PackedNode::new( "1.2.3.5:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); let farther_node = PackedNode::new( "1.2.3.5:12346".parse().unwrap(), - PublicKey::from([10; crypto_box::KEY_SIZE]) + PublicKey::from([10; crypto_box::KEY_SIZE]), ); let existing_node = PackedNode::new( "1.2.3.5:12347".parse().unwrap(), - PublicKey::from([2; crypto_box::KEY_SIZE]) + PublicKey::from([2; crypto_box::KEY_SIZE]), ); // can't add a new farther node @@ -451,11 +463,11 @@ mod tests { let node_1 = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); let node_2 = PackedNode::new( "1.2.3.4:12346".parse().unwrap(), - PublicKey::from([2; crypto_box::KEY_SIZE]) + PublicKey::from([2; crypto_box::KEY_SIZE]), ); assert!(kbucket.try_add(&pk, node_2, /* evict */ false)); @@ -478,22 +490,10 @@ mod tests { let pk_3 = PublicKey::from([3; crypto_box::KEY_SIZE]); let pk_4 = PublicKey::from([4; crypto_box::KEY_SIZE]); - let node_1 = PackedNode::new( - "1.2.3.4:12345".parse().unwrap(), - pk_1.clone(), - ); - let node_2 = PackedNode::new( - "1.2.3.4:12346".parse().unwrap(), - pk_2.clone(), - ); - let node_3 = PackedNode::new( - "1.2.3.4:12346".parse().unwrap(), - pk_3.clone(), - ); - let node_4 = PackedNode::new( - "1.2.3.4:12346".parse().unwrap(), - pk_4.clone(), - ); + let node_1 = PackedNode::new("1.2.3.4:12345".parse().unwrap(), pk_1.clone()); + let node_2 = PackedNode::new("1.2.3.4:12346".parse().unwrap(), pk_2.clone()); + let node_3 = PackedNode::new("1.2.3.4:12346".parse().unwrap(), pk_3.clone()); + let node_4 = PackedNode::new("1.2.3.4:12346".parse().unwrap(), pk_4.clone()); assert!(kbucket.try_add(&pk, node_2, /* evict */ false)); @@ -517,11 +517,11 @@ mod tests { let node_1 = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); let node_2 = PackedNode::new( "1.2.3.4:12346".parse().unwrap(), - PublicKey::from([2; crypto_box::KEY_SIZE]) + PublicKey::from([2; crypto_box::KEY_SIZE]), ); assert!(kbucket.try_add(&pk, node_1, /* evict */ true)); @@ -543,18 +543,9 @@ mod tests { let pk_2 = PublicKey::from([2; crypto_box::KEY_SIZE]); let pk_3 = PublicKey::from([3; crypto_box::KEY_SIZE]); - let node_1 = PackedNode::new( - "1.2.3.4:12345".parse().unwrap(), - pk_1.clone(), - ); - let node_2 = PackedNode::new( - "1.2.3.4:12346".parse().unwrap(), - pk_2.clone(), - ); - let node_3 = PackedNode::new( - "1.2.3.4:12346".parse().unwrap(), - pk_3.clone(), - ); + let node_1 = PackedNode::new("1.2.3.4:12345".parse().unwrap(), pk_1.clone()); + let node_2 = PackedNode::new("1.2.3.4:12346".parse().unwrap(), pk_2.clone()); + let node_3 = PackedNode::new("1.2.3.4:12346".parse().unwrap(), pk_3.clone()); assert!(kbucket.try_add(&pk, node_1, /* evict */ true)); @@ -576,7 +567,7 @@ mod tests { let node = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); // "removing" non-existent node @@ -601,7 +592,7 @@ mod tests { let node = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); assert!(kbucket.try_add(&pk, node, /* evict */ true)); @@ -713,6 +704,7 @@ mod tests { kbucket.try_add(&base_pk, n1.clone(), true); // => 0 kbucket.try_add(&base_pk, n2.clone(), true); // => 1 kbucket.try_add(&base_pk, n3.clone(), true); // => 2 + // test removing from the beginning (n1 => 0) kbucket.remove(&base_pk, &n1.pk); assert_eq!(kbucket.find(&base_pk, &n1.pk), None); @@ -728,6 +720,7 @@ mod tests { kbucket.try_add(&base_pk, n1.clone(), true); // => 0 kbucket.try_add(&base_pk, n2.clone(), true); // => 1 kbucket.try_add(&base_pk, n3.clone(), true); // => 2 + // test removing from the middle (n2 => 1) kbucket.remove(&base_pk, &n2.pk); assert_eq!(kbucket.find(&base_pk, &n1.pk), Some(0)); @@ -743,6 +736,7 @@ mod tests { kbucket.try_add(&base_pk, n1.clone(), true); // => 0 kbucket.try_add(&base_pk, n2.clone(), true); // => 1 kbucket.try_add(&base_pk, n3.clone(), true); // => 2 + // test removing from the end (n3 => 2) kbucket.remove(&base_pk, &n3.pk); assert_eq!(kbucket.find(&base_pk, &n1.pk), Some(0)); @@ -759,7 +753,7 @@ mod tests { let node = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); assert!(kbucket.try_add(&pk, node, /* evict */ true)); diff --git a/tox_core/src/dht/ktree.rs b/tox_core/src/dht/ktree.rs index 57c0dbb51..ae824e5f0 100644 --- a/tox_core/src/dht/ktree.rs +++ b/tox_core/src/dht/ktree.rs @@ -1,10 +1,10 @@ //! K-buckets structure -use tox_crypto::*; use crate::dht::dht_node::*; -use tox_packet::dht::packed_node::*; use crate::dht::ip_port::IsGlobal; use crate::dht::kbucket::*; +use tox_crypto::*; +use tox_packet::dht::packed_node::*; /** K-buckets structure to hold up to [`KBUCKET_MAX_ENTRIES`](./constant.KBUCKET_MAX_ENTRIES.html) * @@ -43,24 +43,20 @@ impl Ktree { trace!(target: "Ktree", "Creating new Ktree with PK: {:?}", pk); Ktree { pk, - kbuckets: vec![Kbucket::new(KBUCKET_DEFAULT_SIZE); KBUCKET_MAX_ENTRIES as usize] + kbuckets: vec![Kbucket::new(KBUCKET_DEFAULT_SIZE); KBUCKET_MAX_ENTRIES as usize], } } /// Get reference to a `DhtNode` by it's `PublicKey`. pub fn get_node(&self, pk: &PublicKey) -> Option<&DhtNode> { - self.kbucket_index(pk).and_then(|index| - self.kbuckets[index] - .get_node(&self.pk, pk) - ) + self.kbucket_index(pk) + .and_then(|index| self.kbuckets[index].get_node(&self.pk, pk)) } /// Get mutable reference to a `DhtNode` by it's `PublicKey`. pub fn get_node_mut(&mut self, pk: &PublicKey) -> Option<&mut DhtNode> { - self.kbucket_index(pk).and_then(move |index| - self.kbuckets[index] - .get_node_mut(&self.pk, pk) - ) + self.kbucket_index(pk) + .and_then(move |index| self.kbuckets[index].get_node_mut(&self.pk, pk)) } /** Return the possible internal index of [`Kbucket`](./struct.Kbucket.html) @@ -110,7 +106,7 @@ impl Ktree { None => { trace!("Failed to remove PK: {:?}", node_pk); None - }, + } } } @@ -165,8 +161,7 @@ impl Ktree { pub fn can_add(&self, new_node: &PackedNode) -> bool { match self.kbucket_index(&new_node.pk) { None => false, - Some(i) => - self.kbuckets[i].can_add(&self.pk, new_node, /* evict */ false), + Some(i) => self.kbuckets[i].can_add(&self.pk, new_node, /* evict */ false), } } @@ -183,24 +178,19 @@ impl Ktree { /// Nodes that this iterator produces are sorted by distance to a base /// `PublicKey` (in ascending order). pub fn iter(&self) -> impl Iterator + Clone { - self.kbuckets.iter() - .rev() - .flat_map(|kbucket| kbucket.iter()) + self.kbuckets.iter().rev().flat_map(|kbucket| kbucket.iter()) } /// Create mutable iterator over [`DhtNode`](./struct.DhtNode.html)s in /// `Ktree`. Nodes that this iterator produces are sorted by distance to a /// base `PublicKey` (in ascending order). pub fn iter_mut(&mut self) -> impl Iterator { - self.kbuckets.iter_mut() - .rev() - .flat_map(|kbucket| kbucket.iter_mut()) + self.kbuckets.iter_mut().rev().flat_map(|kbucket| kbucket.iter_mut()) } /// Check if all nodes in Ktree are discarded pub fn is_all_discarded(&self) -> bool { - self.iter() - .all(|node| node.is_discarded()) + self.iter().all(|node| node.is_discarded()) } } @@ -227,7 +217,7 @@ mod tests { let pk = PublicKey::from([0; crypto_box::KEY_SIZE]); let mut ktree = Ktree::new(pk); - for i in 0 .. 8 { + for i in 0..8 { let mut pk = [i + 2; crypto_box::KEY_SIZE]; // make first bit differ from base pk so all these nodes will get // into the first kbucket @@ -243,18 +233,12 @@ mod tests { let mut pk = [1; crypto_box::KEY_SIZE]; pk[0] = 255; let pk = PublicKey::from(pk); - let node = PackedNode::new( - "1.2.3.5:12345".parse().unwrap(), - pk - ); + let node = PackedNode::new("1.2.3.5:12345".parse().unwrap(), pk); assert!(!ktree.try_add(node)); // but nodes still can be added to other kbuckets let pk = PublicKey::from([1; crypto_box::KEY_SIZE]); - let node = PackedNode::new( - "1.2.3.5:12346".parse().unwrap(), - pk - ); + let node = PackedNode::new("1.2.3.5:12346".parse().unwrap(), pk); assert!(ktree.try_add(node)); } @@ -263,10 +247,7 @@ mod tests { let pk = PublicKey::from([0; crypto_box::KEY_SIZE]); let mut ktree = Ktree::new(pk.clone()); - let node = PackedNode::new( - "1.2.3.5:12345".parse().unwrap(), - pk - ); + let node = PackedNode::new("1.2.3.5:12345".parse().unwrap(), pk); assert!(!ktree.try_add(node)); } @@ -280,7 +261,7 @@ mod tests { let node = PackedNode::new( "1.2.3.4:12345".parse().unwrap(), - PublicKey::from([1; crypto_box::KEY_SIZE]) + PublicKey::from([1; crypto_box::KEY_SIZE]), ); // "removing" non-existent node @@ -308,17 +289,21 @@ mod tests { PackedNode::new(addr, PublicKey::from([i + 1; crypto_box::KEY_SIZE])) } - for i in 0 .. 8 { + for i in 0..8 { assert!(ktree.try_add(node_by_idx(i))); } - for count in 1 ..= 4 { - let closest: Vec<_> = ktree.get_closest(&PublicKey::from([0; crypto_box::KEY_SIZE]), count, true).into(); - let should_be = (0 .. count).map(node_by_idx).collect::>(); + for count in 1..=4 { + let closest: Vec<_> = ktree + .get_closest(&PublicKey::from([0; crypto_box::KEY_SIZE]), count, true) + .into(); + let should_be = (0..count).map(node_by_idx).collect::>(); assert_eq!(closest, should_be); - let closest: Vec<_> = ktree.get_closest(&PublicKey::from([255; crypto_box::KEY_SIZE]), count, true).into(); - let should_be = (8 - count .. 8).rev().map(node_by_idx).collect::>(); + let closest: Vec<_> = ktree + .get_closest(&PublicKey::from([255; crypto_box::KEY_SIZE]), count, true) + .into(); + let should_be = (8 - count..8).rev().map(node_by_idx).collect::>(); assert_eq!(closest, should_be); } } @@ -335,7 +320,7 @@ mod tests { let node = PackedNode::new( "1.2.3.5:12345".parse().unwrap(), - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ); assert!(!ktree.contains(&node.pk)); @@ -353,7 +338,7 @@ mod tests { let node = PackedNode::new( "1.2.3.5:12345".parse().unwrap(), - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ); assert!(ktree.can_add(&node)); @@ -376,7 +361,7 @@ mod tests { PackedNode::new(addr, PublicKey::from([i + 1; crypto_box::KEY_SIZE])) } - for i in 0 .. 8 { + for i in 0..8 { assert!(ktree.try_add(node_by_idx(i))); } @@ -403,7 +388,7 @@ mod tests { PackedNode::new(addr, PublicKey::from([i + 1; crypto_box::KEY_SIZE])) } - for i in 0 .. 8 { + for i in 0..8 { assert!(ktree.try_add(node_by_idx(i))); } @@ -425,13 +410,13 @@ mod tests { let node = PackedNode::new( "1.2.3.4:33445".parse().unwrap(), - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ); assert!(ktree.try_add(node)); let node = PackedNode::new( "1.2.3.5:12345".parse().unwrap(), - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ); assert!(ktree.try_add(node)); diff --git a/tox_core/src/dht/lan_discovery.rs b/tox_core/src/dht/lan_discovery.rs index 777dbc30c..f79859291 100644 --- a/tox_core/src/dht/lan_discovery.rs +++ b/tox_core/src/dht/lan_discovery.rs @@ -4,16 +4,15 @@ use std::iter; use std::net::{IpAddr, SocketAddr}; use std::time::Duration; -use thiserror::Error; -use futures::{stream, SinkExt}; use futures::channel::mpsc; +use futures::{stream, SinkExt}; use get_if_addrs::IfAddr; +use thiserror::Error; use tokio::time::error::Elapsed; use tox_crypto::*; use tox_packet::dht::*; - /// Error that can happen during lan discovery. #[derive(Debug, Eq, PartialEq, Error)] pub enum LanDiscoveryError { @@ -70,14 +69,11 @@ impl LanDiscoverySender { /// Get broadcast addresses for host's network interfaces. fn get_ipv4_broadcast_addrs() -> Vec { let ifs = get_if_addrs::get_if_addrs().expect("no network interface"); - ifs - .iter() - .filter_map(|interface| - match interface.addr { - IfAddr::V4(ref addr) => addr.broadcast, - _ => None, - } - ) + ifs.iter() + .filter_map(|interface| match interface.addr { + IfAddr::V4(ref addr) => addr.broadcast, + _ => None, + }) .map(Into::into) .collect() } @@ -107,13 +103,14 @@ impl LanDiscoverySender { } let ip_addrs = self.get_broadcast_addrs(); // range of ports to send discovery packet to - let ports_range = (self.next_port .. self.next_port + PORTS_PER_DISCOVERY).map(cycle); + let ports_range = (self.next_port..self.next_port + PORTS_PER_DISCOVERY).map(cycle); // always send discovery packet to default port let ports_range = iter::once(DEFAULT_PORT).chain(ports_range); // add ports to ip addrs - let socket_addrs = ip_addrs.into_iter().flat_map(move |ip_addr| { - ports_range.clone().map(move |port| SocketAddr::new(ip_addr, port)) - }).collect(); + let socket_addrs = ip_addrs + .into_iter() + .flat_map(move |ip_addr| ports_range.clone().map(move |port| SocketAddr::new(ip_addr, port))) + .collect(); // update port for next iteration self.next_port = cycle(self.next_port + PORTS_PER_DISCOVERY); socket_addrs @@ -126,9 +123,7 @@ impl LanDiscoverySender { pk: self.dht_pk.clone(), }); - let mut stream = stream::iter( - addrs.into_iter().map(move |addr| Ok((lan_packet.clone(), addr))) - ); + let mut stream = stream::iter(addrs.into_iter().map(move |addr| Ok((lan_packet.clone(), addr)))); self.tx.send_all(&mut stream).await?; @@ -147,7 +142,7 @@ impl LanDiscoverySender { if let Err(e) = tokio::time::timeout(interval, self.send()).await { warn!("Failed to send LAN discovery packets: {}", e); - return Err(LanDiscoveryError::Timeout(e)) + return Err(LanDiscoveryError::Timeout(e)); } } } @@ -157,17 +152,17 @@ impl LanDiscoverySender { mod tests { use super::*; use futures::StreamExt; - use tox_binary_io::*; use rand::thread_rng; + use tox_binary_io::*; fn broadcast_addrs_count() -> usize { - get_if_addrs::get_if_addrs().expect("no network interface").iter() - .filter_map(|interface| - match interface.addr { - IfAddr::V4(ref addr) => addr.broadcast, - _ => None, - } - ) + get_if_addrs::get_if_addrs() + .expect("no network interface") + .iter() + .filter_map(|interface| match interface.addr { + IfAddr::V4(ref addr) => addr.broadcast, + _ => None, + }) .count() } @@ -184,7 +179,7 @@ mod tests { assert_eq!(lan_discovery.next_port, START_PORT + PORTS_PER_DISCOVERY); - for _i in 0 .. packets_count { + for _i in 0..packets_count { let (received, rx1) = rx.into_future().await; let (packet, _addr) = received.unwrap(); @@ -209,7 +204,7 @@ mod tests { assert_eq!(lan_discovery.next_port, START_PORT + PORTS_PER_DISCOVERY); - for _i in 0 .. packets_count { + for _i in 0..packets_count { let (received, rx1) = rx.into_future().await; let (packet, _addr) = received.unwrap(); @@ -236,7 +231,7 @@ mod tests { assert_eq!(lan_discovery.next_port, START_PORT + PORTS_PER_DISCOVERY - 1); - for _i in 0 .. packets_count { + for _i in 0..packets_count { let (received, rx1) = rx.into_future().await; let (packet, _addr) = received.unwrap(); diff --git a/tox_core/src/dht/mod.rs b/tox_core/src/dht/mod.rs index a1549bc3d..425386572 100644 --- a/tox_core/src/dht/mod.rs +++ b/tox_core/src/dht/mod.rs @@ -1,16 +1,16 @@ /*! The implementaion of dht module functionalities. */ -pub mod kbucket; -pub mod ktree; -pub mod forced_ktree; pub mod codec; -pub mod server; +pub mod daemon_state; pub mod dht_friend; pub mod dht_node; -pub mod daemon_state; -pub mod lan_discovery; +pub mod forced_ktree; pub mod ip_port; -pub mod request_queue; +pub mod kbucket; +pub mod ktree; +pub mod lan_discovery; pub mod precomputed_cache; +pub mod request_queue; +pub mod server; pub mod server_ext; diff --git a/tox_core/src/dht/precomputed_cache.rs b/tox_core/src/dht/precomputed_cache.rs index 5ed57d04c..f89c24c89 100644 --- a/tox_core/src/dht/precomputed_cache.rs +++ b/tox_core/src/dht/precomputed_cache.rs @@ -1,13 +1,13 @@ //! LRU cache for `SalsaBox`es. -use std::sync::Arc; use std::num::NonZeroUsize; +use std::sync::Arc; use crypto_box::SalsaBox; use lru::LruCache; -use tox_crypto::*; use futures::lock::Mutex; +use tox_crypto::*; /// LRU cache for `SalsaBox`es. /// diff --git a/tox_core/src/dht/request_queue.rs b/tox_core/src/dht/request_queue.rs index 64c28013d..817788963 100644 --- a/tox_core/src/dht/request_queue.rs +++ b/tox_core/src/dht/request_queue.rs @@ -1,12 +1,12 @@ //! Managing requests IDs and timeouts. -use std::collections::HashMap; +use rand::{CryptoRng, Rng}; use std::collections::hash_map::Entry; +use std::collections::HashMap; use std::time::{Duration, Instant}; -use rand::{CryptoRng, Rng}; -use crate::utils::gen_ping_id; use crate::time::*; +use crate::utils::gen_ping_id; /// Struct that stores and manages requests IDs and timeouts. Every request ID /// stores generic companion data. @@ -70,9 +70,8 @@ impl RequestQueue { /// Remove timed out request IDs. pub fn clear_timed_out(&mut self) { let timeout = self.timeout; - self.ping_map.retain(|&_, &mut (time, _)| - clock_elapsed(time) <= timeout - ); + self.ping_map + .retain(|&_, &mut (time, _)| clock_elapsed(time) <= timeout); } /// Get not timed out requests stored in this `RequestQueue`. diff --git a/tox_core/src/dht/server/errors.rs b/tox_core/src/dht/server/errors.rs index 6ab880a17..f2db156f9 100644 --- a/tox_core/src/dht/server/errors.rs +++ b/tox_core/src/dht/server/errors.rs @@ -6,8 +6,11 @@ use thiserror::Error; use tokio::time::error::Elapsed; use tox_packet::dht::GetPayloadError; -use crate::onion::{client::errors::{HandleAnnounceResponseError, HandleDataResponseError}, onion_announce::HandleDataRequestError}; use crate::net_crypto::errors::HandlePacketError as HandleNetCryptoPacketError; +use crate::onion::{ + client::errors::{HandleAnnounceResponseError, HandleDataResponseError}, + onion_announce::HandleDataRequestError, +}; /// Error that can happen when calling `handle_*` of packet. #[derive(Debug, Error)] diff --git a/tox_core/src/dht/server/hole_punching.rs b/tox_core/src/dht/server/hole_punching.rs index ecf50ac4b..74203dd65 100644 --- a/tox_core/src/dht/server/hole_punching.rs +++ b/tox_core/src/dht/server/hole_punching.rs @@ -4,10 +4,10 @@ Module for hole-punching. https://zetok.github.io/tox-spec/#hole-punching */ +use rand::{CryptoRng, Rng}; +use std::collections::HashMap; use std::net::{IpAddr, SocketAddr}; use std::time::{Duration, Instant}; -use std::collections::HashMap; -use rand::{CryptoRng, Rng}; use crate::dht::dht_friend::*; use crate::dht::server::*; @@ -80,31 +80,37 @@ impl HolePunching { /// This function returns list of addresses to which we should send ///`PingRequest` packet. pub fn next_punch_addrs(&mut self, addrs: &[SocketAddr]) -> Vec { - if !self.is_punching_done && - self.last_punching_time.map_or(true, |time| time.elapsed() >= PUNCH_INTERVAL) && - self.last_recv_ping_time.elapsed() <= PUNCH_INTERVAL * 2 { - let ip = match HolePunching::get_common_ip(addrs, u32::from(FRIEND_CLOSE_NODES_COUNT) / 2) { - // A friend can have maximum 8 close node. If 4 or more close nodes returned - // the same friend's IP address but with different port we consider that friend - // is behind NAT. Otherwise we do nothing. - None => return Vec::new(), - Some(ip) => ip, - }; - - if self.last_punching_time.map_or(true, |time| time.elapsed() > RESET_PUNCH_INTERVAL) { - self.num_punch_tries = 0; - self.first_punching_index = 0; - self.last_punching_index = 0; - } - - let ports_to_try = HolePunching::get_nat_ports(addrs, ip); - - let res = self.punch_addrs(&ports_to_try, ip); - - self.last_punching_time = Some(clock_now()); - self.is_punching_done = true; - - res + if !self.is_punching_done + && self + .last_punching_time + .map_or(true, |time| time.elapsed() >= PUNCH_INTERVAL) + && self.last_recv_ping_time.elapsed() <= PUNCH_INTERVAL * 2 + { + let ip = match HolePunching::get_common_ip(addrs, u32::from(FRIEND_CLOSE_NODES_COUNT) / 2) { + // A friend can have maximum 8 close node. If 4 or more close nodes returned + // the same friend's IP address but with different port we consider that friend + // is behind NAT. Otherwise we do nothing. + None => return Vec::new(), + Some(ip) => ip, + }; + + if self + .last_punching_time + .map_or(true, |time| time.elapsed() > RESET_PUNCH_INTERVAL) + { + self.num_punch_tries = 0; + self.first_punching_index = 0; + self.last_punching_index = 0; + } + + let ports_to_try = HolePunching::get_nat_ports(addrs, ip); + + let res = self.punch_addrs(&ports_to_try, ip); + + self.last_punching_time = Some(clock_now()); + self.is_punching_done = true; + + res } else { Vec::new() } @@ -123,19 +129,16 @@ impl HolePunching { *occurrences.entry(addr.ip()).or_insert(0) += 1; } - occurrences.into_iter().max_by_key(|&(_, count)| count) - .and_then(|(common_ip, count)| - if count > need_num { - Some(common_ip) - } else { - None - } - ) + occurrences + .into_iter() + .max_by_key(|&(_, count)| count) + .and_then(|(common_ip, count)| if count > need_num { Some(common_ip) } else { None }) } /// Get ports list of given IP address. fn get_nat_ports(addrs: &[SocketAddr], ip: IpAddr) -> Vec { - addrs.iter() + addrs + .iter() .filter(|addr| addr.ip() == ip) .map(|addr| addr.port()) .collect::>() @@ -145,17 +148,19 @@ impl HolePunching { /// neighborhood) returned by close nodes of a friend. fn first_hole_punching(&self, ports: &[u16], ip: IpAddr) -> Vec { let num_ports = ports.len(); - (0..MAX_PORTS_TO_PUNCH).map(|i| { - // algorithm designed by irungentoo - // https://zetok.github.io/tox-spec/#symmetric-nat - let it = i + self.first_punching_index; - let sign: i16 = if it % 2 == 1 { -1 } else { 1 }; - let delta = sign * (it / (2 * num_ports as u32)) as i16; - let index = (it as usize / 2) % num_ports; - let port = (ports[index] as i16 + delta) as u16; - - SocketAddr::new(ip, port) - }).collect() + (0..MAX_PORTS_TO_PUNCH) + .map(|i| { + // algorithm designed by irungentoo + // https://zetok.github.io/tox-spec/#symmetric-nat + let it = i + self.first_punching_index; + let sign: i16 = if it % 2 == 1 { -1 } else { 1 }; + let delta = sign * (it / (2 * num_ports as u32)) as i16; + let index = (it as usize / 2) % num_ports; + let port = (ports[index] as i16 + delta) as u16; + + SocketAddr::new(ip, port) + }) + .collect() } /// Advanced port guessing algorithm. It uses all ports sequentially @@ -163,14 +168,16 @@ impl HolePunching { fn last_hole_punching(&self, ip: IpAddr) -> Vec { let port: u32 = 1024; - (0..MAX_PORTS_TO_PUNCH).map(|i| { - // algorithm designed by irungentoo - // https://zetok.github.io/tox-spec/#symmetric-nat - let it = i + self.last_punching_index; - let port = port + it; + (0..MAX_PORTS_TO_PUNCH) + .map(|i| { + // algorithm designed by irungentoo + // https://zetok.github.io/tox-spec/#symmetric-nat + let it = i + self.last_punching_index; + let port = port + it; - SocketAddr::new(ip, port as u16) - }).collect() + SocketAddr::new(ip, port as u16) + }) + .collect() } /// Get addresses for hole punching using different port guessing @@ -180,7 +187,7 @@ impl HolePunching { ///`PingRequest` packet. fn punch_addrs(&mut self, ports: &[u16], ip: IpAddr) -> Vec { if ports.is_empty() { - return Vec::new() + return Vec::new(); } let first_port = ports[0]; diff --git a/tox_core/src/dht/server/mod.rs b/tox_core/src/dht/server/mod.rs index 471579f71..aa3ed0674 100644 --- a/tox_core/src/dht/server/mod.rs +++ b/tox_core/src/dht/server/mod.rs @@ -3,41 +3,41 @@ Functionality needed to work as a DHT node. This module works on top of other modules. */ -pub mod hole_punching; pub mod errors; +pub mod hole_punching; -use futures::{TryFutureExt, StreamExt, SinkExt, future}; use futures::channel::mpsc; +use futures::{future, SinkExt, StreamExt, TryFutureExt}; +use rand::{prelude::SliceRandom, thread_rng, Rng}; use tokio::sync::RwLock; -use rand::{Rng, prelude::SliceRandom, thread_rng}; use std::collections::HashMap; use std::net::SocketAddr; use std::sync::Arc; use std::time::{Duration, Instant}; use std::{iter, mem}; -use xsalsa20poly1305::{XSalsa20Poly1305, KeyInit}; +use xsalsa20poly1305::{KeyInit, XSalsa20Poly1305}; -use crate::time::*; -use tox_crypto::*; -use tox_packet::dht::*; -use tox_packet::dht::packed_node::*; +use crate::dht::dht_friend::*; +use crate::dht::dht_node::*; +use crate::dht::forced_ktree::*; +use crate::dht::ip_port::IsGlobal; use crate::dht::kbucket::*; use crate::dht::ktree::*; -use crate::dht::forced_ktree::*; use crate::dht::precomputed_cache::*; -use tox_packet::onion::*; -use crate::onion::onion_announce::*; use crate::dht::request_queue::*; -use tox_packet::ip_port::*; -use crate::dht::dht_friend::*; -use crate::dht::dht_node::*; -use crate::dht::server::hole_punching::*; -use tox_packet::relay::OnionRequest; -use crate::dht::ip_port::IsGlobal; -use crate::utils::*; use crate::dht::server::errors::*; +use crate::dht::server::hole_punching::*; use crate::io_tokio::*; +use crate::onion::onion_announce::*; +use crate::time::*; +use crate::utils::*; +use tox_crypto::*; +use tox_packet::dht::packed_node::*; +use tox_packet::dht::*; +use tox_packet::ip_port::*; +use tox_packet::onion::*; +use tox_packet::relay::OnionRequest; /// Shorthand for the transmit half of the message channel. type Tx = mpsc::Sender<(Packet, SocketAddr)>; @@ -112,7 +112,9 @@ struct ServerState { impl ServerState { /// Adapt `RequestQueue.check_ping_id()`. fn check_ping_id(&mut self, ping_id: u64, packet_pk: &PublicKey) -> bool { - self.request_queue.check_ping_id(ping_id, |pk| packet_pk.eq(pk)).is_some() + self.request_queue + .check_ping_id(ping_id, |pk| packet_pk.eq(pk)) + .is_some() } } @@ -201,7 +203,8 @@ impl Server { let fake_friends_keys = iter::repeat_with(|| SecretKey::generate(&mut rng).public_key()) .take(FAKE_FRIENDS_NUMBER) .collect::>(); - let friends = fake_friends_keys.iter() + let friends = fake_friends_keys + .iter() .map(|pk| (pk.clone(), DhtFriend::new(&mut rng, pk.clone()))) .collect(); @@ -253,18 +256,16 @@ impl Server { /// Check if we have at least one node in good state. pub async fn is_connected(&self) -> bool { - self.state.read() - .await - .close_nodes - .iter() - .any(|node| !node.is_bad()) + self.state.read().await.close_nodes.iter().any(|node| !node.is_bad()) } /// Get all known nodes. pub async fn get_all_nodes(&self) -> Vec { let state = self.state.read().await; - state.close_nodes.iter() + state + .close_nodes + .iter() .flat_map(|node| node.to_packed_node()) .collect::>() } @@ -275,7 +276,7 @@ impl Server { friends: &HashMap, base_pk: &PublicKey, count: u8, - only_global: bool + only_global: bool, ) -> Kbucket { let mut kbucket = close_nodes.get_closest(base_pk, count, only_global); @@ -310,7 +311,9 @@ impl Server { let close_nodes = Server::get_closest_inner(&state.close_nodes, &state.friends, &friend.pk, 4, true); for node in close_nodes.iter() { - friend.nodes_to_bootstrap.try_add(&friend.pk, node.clone(), /* evict */ true); + friend + .nodes_to_bootstrap + .try_add(&friend.pk, node.clone(), /* evict */ true); } state.friends.insert(friend_pk, friend); @@ -330,7 +333,8 @@ impl Server { // Check if we should send `NodesRequest` packet to a random node. This // request is sent every second 5 times and then every 20 seconds. fn send_random_request(last_nodes_req_time: &mut Instant, random_requests_count: &mut u32) -> bool { - if clock_elapsed(*last_nodes_req_time) > NODES_REQ_INTERVAL || *random_requests_count < MAX_BOOTSTRAP_TIMES { + if clock_elapsed(*last_nodes_req_time) > NODES_REQ_INTERVAL || *random_requests_count < MAX_BOOTSTRAP_TIMES + { *random_requests_count = random_requests_count.saturating_add(1); *last_nodes_req_time = clock_now(); true @@ -344,28 +348,47 @@ impl Server { state.request_queue.clear_timed_out(); // Send NodesRequest packets to nodes from the Server - self.ping_nodes_to_bootstrap(&mut state.request_queue, &mut state.nodes_to_bootstrap, self.pk.clone()).await + self.ping_nodes_to_bootstrap(&mut state.request_queue, &mut state.nodes_to_bootstrap, self.pk.clone()) + .await .map_err(RunError::SendTo)?; - self.ping_close_nodes(&mut state.request_queue, state.close_nodes.iter_mut(), self.pk.clone()).await + self.ping_close_nodes(&mut state.request_queue, state.close_nodes.iter_mut(), self.pk.clone()) + .await .map_err(RunError::SendTo)?; if send_random_request(&mut state.last_nodes_req_time, &mut state.random_requests_count) { - self.send_nodes_req_random(&mut state.request_queue, state.close_nodes.iter(), self.pk.clone()).await + self.send_nodes_req_random(&mut state.request_queue, state.close_nodes.iter(), self.pk.clone()) + .await .map_err(RunError::SendTo)?; } // Send NodesRequest packets to nodes from every DhtFriend for friend in state.friends.values_mut() { - self.ping_nodes_to_bootstrap(&mut state.request_queue, &mut friend.nodes_to_bootstrap, friend.pk.clone()).await - .map_err(RunError::SendTo)?; - self.ping_close_nodes(&mut state.request_queue, friend.close_nodes.nodes.iter_mut(), friend.pk.clone()).await - .map_err(RunError::SendTo)?; + self.ping_nodes_to_bootstrap( + &mut state.request_queue, + &mut friend.nodes_to_bootstrap, + friend.pk.clone(), + ) + .await + .map_err(RunError::SendTo)?; + self.ping_close_nodes( + &mut state.request_queue, + friend.close_nodes.nodes.iter_mut(), + friend.pk.clone(), + ) + .await + .map_err(RunError::SendTo)?; if send_random_request(&mut friend.last_nodes_req_time, &mut friend.random_requests_count) { - self.send_nodes_req_random(&mut state.request_queue, friend.close_nodes.nodes.iter(), friend.pk.clone()).await - .map_err(RunError::SendTo)? + self.send_nodes_req_random( + &mut state.request_queue, + friend.close_nodes.nodes.iter(), + friend.pk.clone(), + ) + .await + .map_err(RunError::SendTo)? } } - self.send_nat_ping_req(&mut state.request_queue, &mut state.friends).await + self.send_nat_ping_req(&mut state.request_queue, &mut state.friends) + .await .map_err(RunError::SendTo) } @@ -379,7 +402,10 @@ impl Server { self.run_bootstrap_requests_sending(), ); - r1?; r2?; r3?; r4?; + r1?; + r2?; + r3?; + r4?; Ok(()) } @@ -401,24 +427,18 @@ impl Server { wakeups.tick().await; trace!("Bootstrap wake up"); - let send_res = tokio::time::timeout( - interval, - self.send_bootstrap_requests(), - ).await; - - let res = - match send_res { - Ok(Ok(_)) => Ok(()), - Ok(Err(e)) => - Err(RunError::SendTo(e)), - Err(e) => - Err(RunError::Timeout(e)), - }; + let send_res = tokio::time::timeout(interval, self.send_bootstrap_requests()).await; + + let res = match send_res { + Ok(Ok(_)) => Ok(()), + Ok(Err(e)) => Err(RunError::SendTo(e)), + Err(e) => Err(RunError::Timeout(e)), + }; if let Err(ref e) = res { warn!("Failed to send initial bootstrap packets: {}", e); - return res + return res; } } } @@ -433,13 +453,15 @@ impl Server { return Ok(()); } - let nodes = state.close_nodes + let nodes = state + .close_nodes .iter() .flat_map(|node| node.to_all_packed_nodes()) .chain(self.initial_bootstrap.iter().cloned()); for node in nodes { - self.send_nodes_req(node, &mut state.request_queue, self.pk.clone()).await?; + self.send_nodes_req(node, &mut state.request_queue, self.pk.clone()) + .await?; } Ok(()) @@ -456,20 +478,17 @@ impl Server { trace!("DHT server wake up"); - let loop_res = - tokio::time::timeout(interval, self.dht_main_loop()).await; + let loop_res = tokio::time::timeout(interval, self.dht_main_loop()).await; let res = match loop_res { Ok(Ok(_)) => Ok(()), - Ok(Err(e)) => - Err(e), - Err(e) => - Err(RunError::Timeout(e)), + Ok(Err(e)) => Err(e), + Err(e) => Err(RunError::Timeout(e)), }; if let Err(ref e) = res { warn!("Failed to send DHT periodical packets: {}", e); - return res + return res; } } } @@ -497,8 +516,7 @@ impl Server { loop { wakeups.tick().await; - self.send_pings().await - .map_err(RunError::SendTo)?; + self.send_pings().await.map_err(RunError::SendTo)?; } } @@ -506,7 +524,7 @@ impl Server { async fn send_pings(&self) -> Result<(), mpsc::SendError> { let nodes_to_ping = mem::replace( &mut *self.nodes_to_ping.write().await, - Kbucket::::new(MAX_TO_PING) + Kbucket::::new(MAX_TO_PING), ); if nodes_to_ping.is_empty() { @@ -535,11 +553,18 @@ impl Server { // If node is friend and we don't know friend's IP address yet then send // PingRequest immediately and unconditionally - if state.friends.get(&node.pk).map_or(false, |friend| !friend.is_addr_known()) { + if state + .friends + .get(&node.pk) + .map_or(false, |friend| !friend.is_addr_known()) + { return self.send_ping_req(node.clone(), &mut state.request_queue).await; } - self.nodes_to_ping.write().await.try_add(&self.pk, node, /* evict */ true); + self.nodes_to_ping + .write() + .await + .try_add(&self.pk, node, /* evict */ true); Ok(()) } @@ -547,8 +572,12 @@ impl Server { /// Send `NodesRequest` packets to nodes from bootstrap list. This is /// necessary to check whether node is alive before adding it to close /// nodes lists. - async fn ping_nodes_to_bootstrap(&self, request_queue: &mut RequestQueue, nodes_to_bootstrap: &mut Kbucket, pk: PublicKey) - -> Result<(), mpsc::SendError> { + async fn ping_nodes_to_bootstrap( + &self, + request_queue: &mut RequestQueue, + nodes_to_bootstrap: &mut Kbucket, + pk: PublicKey, + ) -> Result<(), mpsc::SendError> { let capacity = nodes_to_bootstrap.capacity() as u8; let nodes_to_bootstrap = mem::replace(nodes_to_bootstrap, Kbucket::new(capacity)); @@ -561,20 +590,26 @@ impl Server { /// Iterate over nodes from close nodes list and send `NodesRequest` packets /// to them if necessary. - async fn ping_close_nodes<'a, T>(&self, request_queue: &mut RequestQueue, nodes: T, pk: PublicKey) - -> Result<(), mpsc::SendError> - where T: Iterator + async fn ping_close_nodes<'a, T>( + &self, + request_queue: &mut RequestQueue, + nodes: T, + pk: PublicKey, + ) -> Result<(), mpsc::SendError> + where + T: Iterator, { - let nodes = nodes - .flat_map(|node| { - let ping_addr_v4 = node.assoc4 - .ping_addr() - .map(|addr| PackedNode::new(addr.into(), node.pk.clone())); - let ping_addr_v6 = node.assoc6 - .ping_addr() - .map(|addr| PackedNode::new(addr.into(), node.pk.clone())); - ping_addr_v4.into_iter().chain(ping_addr_v6.into_iter()) - }); + let nodes = nodes.flat_map(|node| { + let ping_addr_v4 = node + .assoc4 + .ping_addr() + .map(|addr| PackedNode::new(addr.into(), node.pk.clone())); + let ping_addr_v6 = node + .assoc6 + .ping_addr() + .map(|addr| PackedNode::new(addr.into(), node.pk.clone())); + ping_addr_v4.into_iter().chain(ping_addr_v6.into_iter()) + }); for node in nodes { self.send_nodes_req(node.clone(), request_queue, pk.clone()).await?; @@ -586,9 +621,14 @@ impl Server { /// Send `NodesRequest` packet to a random good node every 20 seconds or if /// it was sent less than `NODES_REQ_INTERVAL`. This function should be /// called every second. - async fn send_nodes_req_random<'a, T>(&self, request_queue: &mut RequestQueue, nodes: T, pk: PublicKey) - -> Result<(), mpsc::SendError> - where T: Iterator + async fn send_nodes_req_random<'a, T>( + &self, + request_queue: &mut RequestQueue, + nodes: T, + pk: PublicKey, + ) -> Result<(), mpsc::SendError> + where + T: Iterator, { let good_nodes = nodes .filter(|&node| !node.is_bad()) @@ -601,10 +641,10 @@ impl Server { } let rng = &mut thread_rng(); - let mut random_node_idx = rng.gen_range(0 .. good_nodes.len()); + let mut random_node_idx = rng.gen_range(0..good_nodes.len()); // Increase probability of sending packet to a close node (has lower index) if random_node_idx != 0 { - random_node_idx -= rng.gen_range(0 ..= random_node_idx); + random_node_idx -= rng.gen_range(0..=random_node_idx); } let random_node = good_nodes[random_node_idx].clone(); @@ -621,8 +661,11 @@ impl Server { } /// Send `PingRequest` packet to the node. - async fn send_ping_req(&self, node: PackedNode, request_queue: &mut RequestQueue) - -> Result<(), mpsc::SendError> { + async fn send_ping_req( + &self, + node: PackedNode, + request_queue: &mut RequestQueue, + ) -> Result<(), mpsc::SendError> { let payload = PingRequestPayload { id: request_queue.new_ping_id(&mut thread_rng(), node.pk.clone()), }; @@ -635,8 +678,12 @@ impl Server { } /// Send `NodesRequest` packet to the node. - async fn send_nodes_req(&self, node: PackedNode, request_queue: &mut RequestQueue, search_pk: PublicKey) - -> Result<(), mpsc::SendError> { + async fn send_nodes_req( + &self, + node: PackedNode, + request_queue: &mut RequestQueue, + search_pk: PublicKey, + ) -> Result<(), mpsc::SendError> { // Check if packet is going to be sent to ourselves. if self.pk == node.pk { trace!("Attempt to send NodesRequest to ourselves."); @@ -656,8 +703,11 @@ impl Server { } /// Send `NatPingRequest` packet to all friends and try to punch holes. - async fn send_nat_ping_req(&self, request_queue: &mut RequestQueue, friends: &mut HashMap) - -> Result<(), mpsc::SendError> { + async fn send_nat_ping_req( + &self, + request_queue: &mut RequestQueue, + friends: &mut HashMap, + ) -> Result<(), mpsc::SendError> { for friend in friends.values_mut() { if friend.is_addr_known() { continue; @@ -671,7 +721,11 @@ impl Server { self.punch_holes(request_queue, friend, &addrs).await?; - if friend.hole_punch.last_send_ping_time.map_or(true, |time| clock_elapsed(time) >= PUNCH_INTERVAL) { + if friend + .hole_punch + .last_send_ping_time + .map_or(true, |time| clock_elapsed(time) >= PUNCH_INTERVAL) + { friend.hole_punch.last_send_ping_time = Some(clock_now()); let payload = DhtRequestPayload::NatPingRequest(NatPingRequest { id: friend.hole_punch.ping_id, @@ -690,8 +744,12 @@ impl Server { } /// Try to punch holes to specified friend. - async fn punch_holes(&self, request_queue: &mut RequestQueue, friend: &mut DhtFriend, returned_addrs: &[SocketAddr]) - -> Result<(), mpsc::SendError> { + async fn punch_holes( + &self, + request_queue: &mut RequestQueue, + friend: &mut DhtFriend, + returned_addrs: &[SocketAddr], + ) -> Result<(), mpsc::SendError> { let punch_addrs = friend.hole_punch.next_punch_addrs(returned_addrs); let mut tx = self.tx.clone(); let payload = PingRequestPayload { @@ -703,9 +761,10 @@ impl Server { &payload, )); - let packets = punch_addrs.into_iter().map(|addr| { - (packet.clone(), addr) - }).collect::>(); + let packets = punch_addrs + .into_iter() + .map(|addr| (packet.clone(), addr)) + .collect::>(); let mut stream = futures::stream::iter(packets).map(Ok); tx.send_all(&mut stream).await @@ -713,10 +772,15 @@ impl Server { /// Send `NatPingRequest` packet to all close nodes of friend in the hope /// that they will redirect it to this friend. - async fn send_nat_ping_req_inner(&self, friend: &DhtFriend, nat_ping_req_packet: DhtRequest) - -> Result<(), mpsc::SendError> { + async fn send_nat_ping_req_inner( + &self, + friend: &DhtFriend, + nat_ping_req_packet: DhtRequest, + ) -> Result<(), mpsc::SendError> { let packet = Packet::DhtRequest(nat_ping_req_packet); - let nodes = friend.close_nodes.nodes + let nodes = friend + .close_nodes + .nodes .iter() .flat_map(|node| node.to_packed_node().into_iter()); @@ -735,35 +799,34 @@ impl Server { /// Handle received `PingRequest` packet and response with `PingResponse` /// packet. If node that sent this packet is not present in close nodes list /// and can be added there then it will be added to ping list. - pub async fn handle_ping_req(&self, packet: PingRequest, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_ping_req(&self, packet: PingRequest, addr: SocketAddr) -> Result<(), HandlePacketError> { let precomputed_key = self.precomputed_keys.get(packet.pk.clone()).await; let payload = match packet.get_payload(&precomputed_key) { Err(e) => return future::err(HandlePacketError::GetPayload(e)).await, Ok(payload) => payload, }; - let resp_payload = PingResponsePayload { - id: payload.id, - }; - let ping_resp = Packet::PingResponse(PingResponse::new( - &precomputed_key, - self.pk.clone(), - &resp_payload, - )); + let resp_payload = PingResponsePayload { id: payload.id }; + let ping_resp = Packet::PingResponse(PingResponse::new(&precomputed_key, self.pk.clone(), &resp_payload)); future::try_join( self.ping_add(PackedNode::new(addr, packet.pk)), self.send_to(addr, ping_resp), ) - .map_ok(drop) - .map_err(HandlePacketError::SendTo) - .await + .map_ok(drop) + .map_err(HandlePacketError::SendTo) + .await } /// Add node to close list after we received a response from it. If it's a /// friend then send it's IP address to appropriate sink. - async fn try_add_to_close(&self, state: &mut ServerState, payload_id: u64, node: PackedNode, check_ping_id: bool) -> Result<(), HandlePacketError> { + async fn try_add_to_close( + &self, + state: &mut ServerState, + payload_id: u64, + node: PackedNode, + check_ping_id: bool, + ) -> Result<(), HandlePacketError> { if check_ping_id && !state.check_ping_id(payload_id, &node.pk) { return Err(HandlePacketError::PingIdMismatch); } @@ -774,7 +837,8 @@ impl Server { } if state.friends.contains_key(&node.pk) { let sink = self.friend_saddr_sink.read().await.clone(); - maybe_send_unbounded(sink, node).await + maybe_send_unbounded(sink, node) + .await .map_err(HandlePacketError::FriendSaddr) } else { Ok(()) @@ -794,14 +858,19 @@ impl Server { return Err(HandlePacketError::ZeroPingId); } - self.try_add_to_close(&mut *self.state.write().await, payload.id, PackedNode::new(addr, packet.pk), true).await + self.try_add_to_close( + &mut *self.state.write().await, + payload.id, + PackedNode::new(addr, packet.pk), + true, + ) + .await } /// Handle received `NodesRequest` packet and respond with `NodesResponse` /// packet. If node that sent this packet is not present in close nodes list /// and can be added there then it will be added to ping list. - pub async fn handle_nodes_req(&self, packet: NodesRequest, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_nodes_req(&self, packet: NodesRequest, addr: SocketAddr) -> Result<(), HandlePacketError> { let precomputed_key = self.precomputed_keys.get(packet.pk.clone()).await; let payload = match packet.get_payload(&precomputed_key) { Err(e) => return Err(HandlePacketError::GetPayload(e)), @@ -814,19 +883,15 @@ impl Server { nodes: close_nodes.into(), id: payload.id, }; - let nodes_resp = Packet::NodesResponse(NodesResponse::new( - &precomputed_key, - self.pk.clone(), - &resp_payload, - )); + let nodes_resp = Packet::NodesResponse(NodesResponse::new(&precomputed_key, self.pk.clone(), &resp_payload)); future::try_join( self.ping_add(PackedNode::new(addr, packet.pk)), self.send_to(addr, nodes_resp), ) - .map_ok(drop) - .map_err(HandlePacketError::SendTo) - .await + .map_ok(drop) + .map_err(HandlePacketError::SendTo) + .await } /// Add nodes to bootstrap nodes list to send `NodesRequest` packet to them @@ -839,12 +904,16 @@ impl Server { } if state.close_nodes.can_add(node) { - state.nodes_to_bootstrap.try_add(&self.pk, node.clone(), /* evict */ true); + state + .nodes_to_bootstrap + .try_add(&self.pk, node.clone(), /* evict */ true); } for friend in state.friends.values_mut() { if friend.can_add_to_close(node) { - friend.nodes_to_bootstrap.try_add(&friend.pk, node.clone(), /* evict */ true); + friend + .nodes_to_bootstrap + .try_add(&friend.pk, node.clone(), /* evict */ true); } } @@ -856,8 +925,7 @@ impl Server { /// that sent this packet to close nodes lists. Nodes from response will be /// added to bootstrap nodes list to send `NodesRequest` packet to them /// later. - pub async fn handle_nodes_resp(&self, packet: NodesResponse, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_nodes_resp(&self, packet: NodesResponse, addr: SocketAddr) -> Result<(), HandlePacketError> { let precomputed_key = self.precomputed_keys.get(packet.pk.clone()).await; let payload = match packet.get_payload(&precomputed_key) { @@ -870,7 +938,8 @@ impl Server { if state.check_ping_id(payload.id, &packet.pk) { trace!("Received nodes with NodesResponse from {}: {:?}", addr, payload.nodes); - self.try_add_to_close(&mut state, payload.id, PackedNode::new(addr, packet.pk.clone()), false).await?; + self.try_add_to_close(&mut state, payload.id, PackedNode::new(addr, packet.pk.clone()), false) + .await?; // Process nodes from NodesResponse self.add_bootstrap_nodes(&mut state, &payload.nodes, &packet.pk).await; @@ -884,7 +953,13 @@ impl Server { } /// Update returned socket address and time of receiving packet - fn update_returned_addr(&self, node: &PackedNode, packet_pk: &PublicKey, close_nodes: &mut ForcedKtree, friends: &mut HashMap) { + fn update_returned_addr( + &self, + node: &PackedNode, + packet_pk: &PublicKey, + close_nodes: &mut ForcedKtree, + friends: &mut HashMap, + ) { if self.pk == node.pk { if let Some(node_to_update) = close_nodes.get_node_mut(packet_pk) { node_to_update.update_returned_addr(node.saddr); @@ -900,9 +975,10 @@ impl Server { /// Handle received `DhtRequest` packet, redirect it if it's sent for /// someone else or parse it and handle the payload if it's sent for us. - pub async fn handle_dht_req(&self, packet: DhtRequest, addr: SocketAddr) - -> Result<(), HandlePacketError> { // TODO: split to functions - if packet.rpk == self.pk { // the target peer is me + pub async fn handle_dht_req(&self, packet: DhtRequest, addr: SocketAddr) -> Result<(), HandlePacketError> { + // TODO: split to functions + if packet.rpk == self.pk { + // the target peer is me self.handle_dht_req_for_us(packet, addr).await } else { self.handle_dht_req_for_others(packet).await @@ -948,9 +1024,14 @@ impl Server { /// Redirect received `DhtRequest` packet. async fn handle_dht_req_for_others(&self, packet: DhtRequest) -> Result<(), HandlePacketError> { let state = self.state.read().await; - if let Some(node) = state.close_nodes.get_node(&packet.rpk).and_then(|node| node.to_packed_node()) { + if let Some(node) = state + .close_nodes + .get_node(&packet.rpk) + .and_then(|node| node.to_packed_node()) + { let packet = Packet::DhtRequest(packet); - self.send_to(node.saddr, packet).await + self.send_to(node.saddr, packet) + .await .map_err(HandlePacketError::SendTo)?; } @@ -958,8 +1039,11 @@ impl Server { } /// Set last received ping time for `DhtFriend`. - async fn set_friend_hole_punch_last_recv_ping_time(&self, spk: &PublicKey, ping_time: Instant) - -> Result<(), HandlePacketError> { + async fn set_friend_hole_punch_last_recv_ping_time( + &self, + spk: &PublicKey, + ping_time: Instant, + ) -> Result<(), HandlePacketError> { let mut state = self.state.write().await; match state.friends.get_mut(spk) { None => Err(HandlePacketError::NoFriend), @@ -972,19 +1056,24 @@ impl Server { /// Handle received `NatPingRequest` packet and respond with /// `NatPingResponse` packet. - async fn handle_nat_ping_req(&self, payload: NatPingRequest, spk: PublicKey, addr: SocketAddr) -> Result<(), HandlePacketError> { - self.set_friend_hole_punch_last_recv_ping_time(&spk, clock_now()).await?; - - let resp_payload = DhtRequestPayload::NatPingResponse(NatPingResponse { - id: payload.id, - }); + async fn handle_nat_ping_req( + &self, + payload: NatPingRequest, + spk: PublicKey, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { + self.set_friend_hole_punch_last_recv_ping_time(&spk, clock_now()) + .await?; + + let resp_payload = DhtRequestPayload::NatPingResponse(NatPingResponse { id: payload.id }); let nat_ping_resp = Packet::DhtRequest(DhtRequest::new( &self.precomputed_keys.get(spk.clone()).await, spk, self.pk.clone(), &resp_payload, )); - self.send_to(addr, nat_ping_resp).await + self.send_to(addr, nat_ping_resp) + .await .map_err(HandlePacketError::SendTo) } @@ -992,7 +1081,7 @@ impl Server { /// it's correct. async fn handle_nat_ping_resp(&self, payload: NatPingResponse, spk: &PublicKey) -> Result<(), HandlePacketError> { if payload.id == 0 { - return Err(HandlePacketError::ZeroPingId) + return Err(HandlePacketError::ZeroPingId); } let mut state = self.state.write().await; @@ -1018,8 +1107,7 @@ impl Server { /// Handle received `LanDiscovery` packet and response with `NodesRequest` /// packet. - pub async fn handle_lan_discovery(&self, packet: &LanDiscovery, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_lan_discovery(&self, packet: &LanDiscovery, addr: SocketAddr) -> Result<(), HandlePacketError> { // LanDiscovery is optional if !self.lan_discovery_enabled { return Ok(()); @@ -1032,14 +1120,22 @@ impl Server { let mut state = self.state.write().await; - self.send_nodes_req(PackedNode::new(addr, packet.pk.clone()), &mut state.request_queue, self.pk.clone()) - .await - .map_err(HandlePacketError::SendTo) + self.send_nodes_req( + PackedNode::new(addr, packet.pk.clone()), + &mut state.request_queue, + self.pk.clone(), + ) + .await + .map_err(HandlePacketError::SendTo) } /// Handle received `OnionRequest0` packet and send `OnionRequest1` packet /// to the next peer. - pub async fn handle_onion_request_0(&self, packet: OnionRequest0, addr: SocketAddr) -> Result<(), HandlePacketError> { + pub async fn handle_onion_request_0( + &self, + packet: OnionRequest0, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { let onion_symmetric_key = self.onion_symmetric_key.read().await; let onion_return = OnionReturn::new( &mut thread_rng(), @@ -1060,19 +1156,24 @@ impl Server { payload: payload.inner, onion_return, }); - self.send_to(payload.ip_port.to_saddr(), next_packet).await + self.send_to(payload.ip_port.to_saddr(), next_packet) + .await .map_err(HandlePacketError::SendTo) } /// Handle received `OnionRequest1` packet and send `OnionRequest2` packet /// to the next peer. - pub async fn handle_onion_request_1(&self, packet: OnionRequest1, addr: SocketAddr) -> Result<(), HandlePacketError> { + pub async fn handle_onion_request_1( + &self, + packet: OnionRequest1, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { let onion_symmetric_key = self.onion_symmetric_key.read().await; let onion_return = OnionReturn::new( &mut thread_rng(), &onion_symmetric_key, &IpPort::from_udp_saddr(addr), - Some(&packet.onion_return) + Some(&packet.onion_return), ); let shared_secret = self.precomputed_keys.get(packet.temporary_pk.clone()).await; let payload = packet.get_payload(&shared_secret); @@ -1086,13 +1187,18 @@ impl Server { payload: payload.inner, onion_return, }); - self.send_to(payload.ip_port.to_saddr(), next_packet).await + self.send_to(payload.ip_port.to_saddr(), next_packet) + .await .map_err(HandlePacketError::SendTo) } /// Handle received `OnionRequest2` packet and send `OnionAnnounceRequest` /// or `OnionDataRequest` packet to the next peer. - pub async fn handle_onion_request_2(&self, packet: OnionRequest2, addr: SocketAddr) -> Result<(), HandlePacketError> { + pub async fn handle_onion_request_2( + &self, + packet: OnionRequest2, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { let onion_symmetric_key = self.onion_symmetric_key.read().await; let onion_return = OnionReturn::new( &mut thread_rng(), @@ -1108,16 +1214,15 @@ impl Server { }; let next_packet = match payload.inner { - InnerOnionRequest::InnerOnionAnnounceRequest(inner) => Packet::OnionAnnounceRequest(OnionAnnounceRequest { - inner, - onion_return, - }), - InnerOnionRequest::InnerOnionDataRequest(inner) => Packet::OnionDataRequest(OnionDataRequest { - inner, - onion_return, - }), + InnerOnionRequest::InnerOnionAnnounceRequest(inner) => { + Packet::OnionAnnounceRequest(OnionAnnounceRequest { inner, onion_return }) + } + InnerOnionRequest::InnerOnionDataRequest(inner) => { + Packet::OnionDataRequest(OnionDataRequest { inner, onion_return }) + } }; - self.send_to(payload.ip_port.to_saddr(), next_packet).await + self.send_to(payload.ip_port.to_saddr(), next_packet) + .await .map_err(HandlePacketError::SendTo) } @@ -1126,14 +1231,14 @@ impl Server { &self, payload: &OnionAnnounceRequestPayload, packet: &OnionAnnounceRequest, - addr: SocketAddr + addr: SocketAddr, ) -> (AnnounceStatus, [u8; 32]) { let mut onion_announce = self.onion_announce.write().await; onion_announce.handle_onion_announce_request( payload, packet.inner.pk.clone(), packet.onion_return.clone(), - addr + addr, ) } @@ -1143,20 +1248,22 @@ impl Server { /// The response packet will contain up to 4 closest to `search_pk` nodes /// from ktree. They are used to search closest to long term `PublicKey` /// nodes to announce. - pub async fn handle_onion_announce_request(&self, packet: OnionAnnounceRequest, addr: SocketAddr) -> Result<(), HandlePacketError> { + pub async fn handle_onion_announce_request( + &self, + packet: OnionAnnounceRequest, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { let shared_secret = self.precomputed_keys.get(packet.inner.pk.clone()).await; let payload = match packet.inner.get_payload(&shared_secret) { Err(e) => return Err(HandlePacketError::GetPayload(e)), Ok(payload) => payload, }; - let (announce_status, ping_id_or_pk) = self.get_onion_announce_ping_id_or_pk( - &payload, - &packet, - addr, - ).await; + let (announce_status, ping_id_or_pk) = self.get_onion_announce_ping_id_or_pk(&payload, &packet, addr).await; - let close_nodes = self.get_closest(&payload.search_pk, 4, IsGlobal::is_global(&addr.ip())).await; + let close_nodes = self + .get_closest(&payload.search_pk, 4, IsGlobal::is_global(&addr.ip())) + .await; let response_payload = OnionAnnounceResponsePayload { announce_status, @@ -1165,24 +1272,28 @@ impl Server { }; let response = OnionAnnounceResponse::new(&shared_secret, payload.sendback_data, &response_payload); - self.send_to(addr, Packet::OnionResponse3(OnionResponse3 { - onion_return: packet.onion_return, - payload: InnerOnionResponse::OnionAnnounceResponse(response), - })) - .await - .map_err(HandlePacketError::SendTo) + self.send_to( + addr, + Packet::OnionResponse3(OnionResponse3 { + onion_return: packet.onion_return, + payload: InnerOnionResponse::OnionAnnounceResponse(response), + }), + ) + .await + .map_err(HandlePacketError::SendTo) } /// Handle received `OnionDataRequest` packet and send `OnionResponse3` /// packet with inner `OnionDataResponse` to destination node through its /// onion path. - pub async fn handle_onion_data_request(&self, packet: OnionDataRequest) - -> Result<(), HandlePacketError> { + pub async fn handle_onion_data_request(&self, packet: OnionDataRequest) -> Result<(), HandlePacketError> { let onion_announce = self.onion_announce.read().await; match onion_announce.handle_data_request(packet) { - Ok((response, addr)) => self.send_to(addr, Packet::OnionResponse3(response)).await + Ok((response, addr)) => self + .send_to(addr, Packet::OnionResponse3(response)) + .await .map_err(HandlePacketError::SendTo), - Err(e) => Err(HandlePacketError::Onion(e)) + Err(e) => Err(HandlePacketError::Onion(e)), } } @@ -1198,16 +1309,17 @@ impl Server { // onion key. So we do not consider this as error. trace!("Failed to decrypt onion_return from OnionResponse3: {}", e); return Ok(()); - }, + } Ok(payload) => payload, }; if let (ip_port, Some(next_onion_return)) = payload { let next_packet = Packet::OnionResponse2(OnionResponse2 { onion_return: next_onion_return, - payload: packet.payload + payload: packet.payload, }); - self.send_to(ip_port.to_saddr(), next_packet).await + self.send_to(ip_port.to_saddr(), next_packet) + .await .map_err(HandlePacketError::SendTo) } else { Err(HandlePacketError::OnionResponseNext) @@ -1226,16 +1338,17 @@ impl Server { // onion key. So we do not consider this as error. trace!("Failed to decrypt onion_return from OnionResponse2: {}", e); return Ok(()); - }, + } Ok(payload) => payload, }; if let (ip_port, Some(next_onion_return)) = payload { let next_packet = Packet::OnionResponse1(OnionResponse1 { onion_return: next_onion_return, - payload: packet.payload + payload: packet.payload, }); - self.send_to(ip_port.to_saddr(), next_packet).await + self.send_to(ip_port.to_saddr(), next_packet) + .await .map_err(HandlePacketError::SendTo) } else { Err(HandlePacketError::OnionResponseNext) @@ -1254,8 +1367,8 @@ impl Server { // paths expiration. It means that we can get packets with old // onion key. So we do not consider this as error. trace!("Failed to decrypt onion_return from OnionResponse1: {}", e); - return Ok(()) - }, + return Ok(()); + } Ok(payload) => payload, }; @@ -1266,17 +1379,21 @@ impl Server { InnerOnionResponse::OnionAnnounceResponse(inner) => Packet::OnionAnnounceResponse(inner), InnerOnionResponse::OnionDataResponse(inner) => Packet::OnionDataResponse(inner), }; - self.send_to(ip_port.to_saddr(), next_packet).await + self.send_to(ip_port.to_saddr(), next_packet) + .await .map_err(HandlePacketError::SendTo) - }, + } ProtocolType::Tcp => { if let Some(ref tcp_onion_sink) = self.tcp_onion_sink { - tcp_onion_sink.clone().send((packet.payload, ip_port.to_saddr())).await + tcp_onion_sink + .clone() + .send((packet.payload, ip_port.to_saddr())) + .await .map_err(HandlePacketError::OnionResponseRedirectSend) } else { Err(HandlePacketError::OnionResponseRedirect) } - }, + } } } else { Err(HandlePacketError::OnionResponseNext) @@ -1291,29 +1408,36 @@ impl Server { /// Handle `OnionRequest` from TCP relay and send `OnionRequest1` packet /// to the next node in the onion path. - pub async fn handle_tcp_onion_request(&self, packet: OnionRequest, addr: SocketAddr) - -> Result<(), mpsc::SendError> { + pub async fn handle_tcp_onion_request( + &self, + packet: OnionRequest, + addr: SocketAddr, + ) -> Result<(), mpsc::SendError> { let onion_symmetric_key = self.onion_symmetric_key.read().await; let onion_return = OnionReturn::new( &mut thread_rng(), &onion_symmetric_key, &IpPort::from_tcp_saddr(addr), - None // no previous onion return + None, // no previous onion return ); let next_packet = Packet::OnionRequest1(OnionRequest1 { nonce: packet.nonce, temporary_pk: packet.temporary_pk, payload: packet.payload, - onion_return + onion_return, }); self.send_to(packet.ip_port.to_saddr(), next_packet).await } /// Handle `BootstrapInfo` packet and response with `BootstrapInfo` packet. - pub async fn handle_bootstrap_info(&self, packet: &BootstrapInfo, addr: SocketAddr) -> Result<(), HandlePacketError> { + pub async fn handle_bootstrap_info( + &self, + packet: &BootstrapInfo, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { if packet.motd.len() != BOOSTRAP_CLIENT_MAX_MOTD_LENGTH { - return Err(HandlePacketError::BootstrapInfoLength) + return Err(HandlePacketError::BootstrapInfoLength); } if let Some(ref bootstrap_info) = self.bootstrap_info { @@ -1330,8 +1454,7 @@ impl Server { version: bootstrap_info.version, motd, }); - self.send_to(addr, packet).await - .map_err(HandlePacketError::SendTo)?; + self.send_to(addr, packet).await.map_err(HandlePacketError::SendTo)?; } Ok(()) @@ -1388,8 +1511,11 @@ mod tests { use super::*; use tox_binary_io::*; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; use std::net::SocketAddr; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; const ONION_RETURN_1_PAYLOAD_SIZE: usize = ONION_RETURN_1_SIZE - xsalsa20poly1305::NONCE_SIZE; const ONION_RETURN_2_PAYLOAD_SIZE: usize = ONION_RETURN_2_SIZE - xsalsa20poly1305::NONCE_SIZE; @@ -1405,8 +1531,14 @@ mod tests { } } - fn create_node() -> (Server, SalsaBox, PublicKey, SecretKey, - mpsc::Receiver<(Packet, SocketAddr)>, SocketAddr) { + fn create_node() -> ( + Server, + SalsaBox, + PublicKey, + SecretKey, + mpsc::Receiver<(Packet, SocketAddr)>, + SocketAddr, + ) { let mut rng = thread_rng(); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -1444,13 +1576,22 @@ mod tests { alice.add_friend(friend_pk.clone()).await; let packed_node = PackedNode::new("127.0.0.1:33445".parse().unwrap(), bob_pk.clone()); - assert!(alice.state.write().await.friends.get_mut(&friend_pk).unwrap().try_add_to_close(packed_node)); + assert!(alice + .state + .write() + .await + .friends + .get_mut(&friend_pk) + .unwrap() + .try_add_to_close(packed_node)); // adding the same friend shouldn't replace existing `DhtFriend` alice.add_friend(friend_pk.clone()).await; // so it should still contain the added node - assert!(alice.state.read().await.friends[&friend_pk].close_nodes.contains(&friend_pk, &bob_pk)); + assert!(alice.state.read().await.friends[&friend_pk] + .close_nodes + .contains(&friend_pk, &bob_pk)); } #[tokio::test] @@ -1556,20 +1697,26 @@ mod tests { let mut state = alice.state.write().await; - rx.take(2).map(|(packet, addr_to_send)| { - assert_eq!(addr_to_send, addr); - - if let Packet::PingResponse(ping_resp) = packet { - let precomputed_key = SalsaBox::new(&ping_resp.pk, &bob_sk); - let ping_resp_payload = ping_resp.get_payload(&precomputed_key).unwrap(); - assert_eq!(ping_resp_payload.id, req_payload.id); - } else { - let ping_req = unpack!(packet, Packet::PingRequest); - let precomputed_key = SalsaBox::new(&ping_req.pk, &bob_sk); - let ping_req_payload = ping_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(ping_req_payload.id, |pk| pk == &bob_pk).is_some()); - } - }).collect::>().await; + rx.take(2) + .map(|(packet, addr_to_send)| { + assert_eq!(addr_to_send, addr); + + if let Packet::PingResponse(ping_resp) = packet { + let precomputed_key = SalsaBox::new(&ping_resp.pk, &bob_sk); + let ping_resp_payload = ping_resp.get_payload(&precomputed_key).unwrap(); + assert_eq!(ping_resp_payload.id, req_payload.id); + } else { + let ping_req = unpack!(packet, Packet::PingRequest); + let precomputed_key = SalsaBox::new(&ping_req.pk, &bob_sk); + let ping_req_payload = ping_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(ping_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + } + }) + .collect::>() + .await; // In case of friend with yet unknown address we should send ping // request immediately instead of adding node to nodes_to_ping list @@ -1585,7 +1732,10 @@ mod tests { let ping_req = PingRequest::new(&precomp, alice.pk.clone(), &req_payload); let res = alice.handle_ping_req(ping_req, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } // handle_ping_resp @@ -1598,7 +1748,12 @@ mod tests { let packed_node = PackedNode::new(addr, bob_pk.clone()); assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut thread_rng(), bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut thread_rng(), bob_pk.clone()); let resp_payload = PingResponsePayload { id: ping_id }; let ping_resp = PingResponse::new(&precomp, bob_pk.clone(), &resp_payload); @@ -1634,7 +1789,12 @@ mod tests { let packed_node = PackedNode::new(addr, bob_pk.clone()); assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut thread_rng(), bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut thread_rng(), bob_pk.clone()); let resp_payload = PingResponsePayload { id: ping_id }; let ping_resp = PingResponse::new(&precomp, bob_pk, &resp_payload); @@ -1659,7 +1819,12 @@ mod tests { let packed_node = PackedNode::new(addr, bob_pk.clone()); assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut thread_rng(), bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut thread_rng(), bob_pk.clone()); let resp_payload = PingResponsePayload { id: ping_id }; let ping_resp = PingResponse::new(&precomp, bob_pk.clone(), &resp_payload); @@ -1680,14 +1845,22 @@ mod tests { let packed_node = PackedNode::new(addr, bob_pk.clone()); assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut thread_rng(), bob_pk); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut thread_rng(), bob_pk); // can't be decrypted payload since packet contains wrong key let payload = PingResponsePayload { id: ping_id }; let ping_resp = PingResponse::new(&precomp, alice.pk.clone(), &payload); let res = alice.handle_ping_resp(ping_resp, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } #[tokio::test] @@ -1711,7 +1884,12 @@ mod tests { let packed_node = PackedNode::new(addr, bob_pk.clone()); assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut thread_rng(), bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut thread_rng(), bob_pk.clone()); let payload = PingResponsePayload { id: ping_id + 1 }; let ping_resp = PingResponse::new(&precomp, bob_pk, &payload); @@ -1729,7 +1907,10 @@ mod tests { assert!(alice.state.write().await.close_nodes.try_add(packed_node.clone())); - let req_payload = NodesRequestPayload { pk: bob_pk.clone(), id: 42 }; + let req_payload = NodesRequestPayload { + pk: bob_pk.clone(), + id: 42, + }; let nodes_req = NodesRequest::new(&precomp, bob_pk.clone(), &req_payload); alice.handle_nodes_req(nodes_req, addr).await.unwrap(); @@ -1756,9 +1937,19 @@ mod tests { alice.add_friend(bob_pk.clone()).await; let packed_node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), bob_pk.clone()); - assert!(alice.state.write().await.friends.get_mut(&bob_pk).unwrap().try_add_to_close(packed_node.clone())); + assert!(alice + .state + .write() + .await + .friends + .get_mut(&bob_pk) + .unwrap() + .try_add_to_close(packed_node.clone())); - let req_payload = NodesRequestPayload { pk: bob_pk.clone(), id: 42 }; + let req_payload = NodesRequestPayload { + pk: bob_pk.clone(), + id: 42, + }; let nodes_req = NodesRequest::new(&precomp, bob_pk.clone(), &req_payload); alice.handle_nodes_req(nodes_req, addr).await.unwrap(); @@ -1786,7 +1977,10 @@ mod tests { assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let req_payload = NodesRequestPayload { pk: bob_pk.clone(), id: 42 }; + let req_payload = NodesRequestPayload { + pk: bob_pk.clone(), + id: 42, + }; let nodes_req = NodesRequest::new(&precomp, bob_pk.clone(), &req_payload); let delay = BAD_NODE_TIMEOUT + Duration::from_secs(1); @@ -1820,7 +2014,10 @@ mod tests { assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let req_payload = NodesRequestPayload { pk: bob_pk.clone(), id: 42 }; + let req_payload = NodesRequestPayload { + pk: bob_pk.clone(), + id: 42, + }; let nodes_req = NodesRequest::new(&precomp, bob_pk.clone(), &req_payload); alice.handle_nodes_req(nodes_req, addr).await.unwrap(); @@ -1849,7 +2046,10 @@ mod tests { let nodes_req = NodesRequest::new(&precomp, alice.pk.clone(), &req_payload); let res = alice.handle_nodes_req(nodes_req, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } // handle_nodes_resp @@ -1860,11 +2060,22 @@ mod tests { alice.add_friend(bob_pk.clone()).await; - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut rng, bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut rng, bob_pk.clone()); - let resp_payload = NodesResponsePayload { nodes: vec![node.clone()], id: ping_id }; + let resp_payload = NodesResponsePayload { + nodes: vec![node.clone()], + id: ping_id, + }; let nodes_resp = NodesResponse::new(&precomp, bob_pk.clone(), &resp_payload); tokio::time::pause(); @@ -1908,11 +2119,22 @@ mod tests { let packed_node = PackedNode::new(addr, bob_pk.clone()); assert!(alice.state.write().await.close_nodes.try_add(packed_node)); - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut rng, bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut rng, bob_pk.clone()); - let resp_payload = NodesResponsePayload { nodes: vec![node], id: ping_id }; + let resp_payload = NodesResponsePayload { + nodes: vec![node], + id: ping_id, + }; let nodes_resp = NodesResponse::new(&precomp, bob_pk.clone(), &resp_payload); alice.handle_nodes_resp(nodes_resp, addr).await.unwrap(); @@ -1930,13 +2152,20 @@ mod tests { let (alice, precomp, _bob_pk, _bob_sk, _rx, addr) = create_node(); // can't be decrypted payload since packet contains wrong key - let resp_payload = NodesResponsePayload { nodes: vec![ - PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()) - ], id: 38 }; + let resp_payload = NodesResponsePayload { + nodes: vec![PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )], + id: 38, + }; let nodes_resp = NodesResponse::new(&precomp, alice.pk.clone(), &resp_payload); let res = alice.handle_nodes_resp(nodes_resp, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } #[tokio::test] @@ -1944,9 +2173,13 @@ mod tests { let mut rng = thread_rng(); let (alice, precomp, bob_pk, _bob_sk, rx, addr) = create_node(); - let resp_payload = NodesResponsePayload { nodes: vec![ - PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()) - ], id: 0 }; + let resp_payload = NodesResponsePayload { + nodes: vec![PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )], + id: 0, + }; let nodes_resp = NodesResponse::new(&precomp, bob_pk, &resp_payload); alice.handle_nodes_resp(nodes_resp, addr).await.unwrap(); @@ -1962,13 +2195,19 @@ mod tests { let mut rng = thread_rng(); let (alice, precomp, bob_pk, _bob_sk, rx, addr) = create_node(); - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut rng, bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut rng, bob_pk.clone()); let resp_payload = NodesResponsePayload { - nodes: vec![ - PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()) - ], - id: ping_id + 1 + nodes: vec![PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )], + id: ping_id + 1, }; let nodes_resp = NodesResponse::new(&precomp, bob_pk, &resp_payload); @@ -2036,11 +2275,14 @@ mod tests { rpk: alice.pk.clone(), spk: bob_pk, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }; let res = alice.handle_dht_req(dht_req, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } // handle_nat_ping_request @@ -2114,7 +2356,12 @@ mod tests { let (alice, precomp, bob_pk, _bob_sk, _rx, addr) = create_node(); // error case, incorrect ping_id - let ping_id = alice.state.write().await.request_queue.new_ping_id(&mut thread_rng(), bob_pk.clone()); + let ping_id = alice + .state + .write() + .await + .request_queue + .new_ping_id(&mut thread_rng(), bob_pk.clone()); let nat_res = NatPingResponse { id: ping_id + 1 }; let nat_payload = DhtRequestPayload::NatPingResponse(nat_res); @@ -2135,12 +2382,12 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let payload = OnionRequest0Payload { ip_port: ip_port.clone(), temporary_pk: temporary_pk.clone(), - inner: inner.clone() + inner: inner.clone(), }; let packet = OnionRequest0::new(&precomp, bob_pk, &payload); @@ -2170,11 +2417,14 @@ mod tests { let packet = OnionRequest0 { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] // not encrypted with dht pk + payload: vec![42; 123], // not encrypted with dht pk }; let res = alice.handle_onion_request_0(packet, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } // handle_onion_request_1 @@ -2188,16 +2438,16 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let payload = OnionRequest1Payload { ip_port: ip_port.clone(), temporary_pk: temporary_pk.clone(), - inner: inner.clone() + inner: inner.clone(), }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], }; let packet = OnionRequest1::new(&precomp, bob_pk, &payload, onion_return); @@ -2230,12 +2480,15 @@ mod tests { payload: vec![42; 123], // not encrypted with dht pk onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], + }, }; let res = alice.handle_onion_request_1(packet, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } // handle_onion_request_2 @@ -2247,20 +2500,20 @@ mod tests { let inner = InnerOnionAnnounceRequest { nonce: [42; ::NonceSize::USIZE], pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }; let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let payload = OnionRequest2Payload { ip_port: ip_port.clone(), - inner: InnerOnionRequest::InnerOnionAnnounceRequest(inner.clone()) + inner: InnerOnionRequest::InnerOnionAnnounceRequest(inner.clone()), }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], }; let packet = OnionRequest2::new(&precomp, bob_pk, &payload, onion_return); @@ -2290,20 +2543,20 @@ mod tests { destination_pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }; let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let payload = OnionRequest2Payload { ip_port: ip_port.clone(), - inner: InnerOnionRequest::InnerOnionDataRequest(inner.clone()) + inner: InnerOnionRequest::InnerOnionDataRequest(inner.clone()), }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], }; let packet = OnionRequest2::new(&precomp, bob_pk, &payload, onion_return); @@ -2335,12 +2588,15 @@ mod tests { payload: vec![42; 123], // not encrypted with dht pk onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], + }, }; let res = alice.handle_onion_request_2(packet, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } // handle_onion_announce_request @@ -2354,16 +2610,16 @@ mod tests { ping_id: INITIAL_PING_ID, search_pk: SecretKey::generate(&mut rng).public_key(), data_pk: SecretKey::generate(&mut rng).public_key(), - sendback_data + sendback_data, }; let inner = InnerOnionAnnounceRequest::new(&precomp, bob_pk, &payload); let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let packet = OnionAnnounceRequest { inner, - onion_return: onion_return.clone() + onion_return: onion_return.clone(), }; alice.handle_onion_announce_request(packet, addr).await.unwrap(); @@ -2393,19 +2649,22 @@ mod tests { let inner = InnerOnionAnnounceRequest { nonce: [42; ::NonceSize::USIZE], pk: bob_pk, - payload: vec![42; 123] + payload: vec![42; 123], }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let packet = OnionAnnounceRequest { inner, - onion_return: onion_return.clone() + onion_return: onion_return.clone(), }; let res = alice.handle_onion_announce_request(packet, addr).await; - assert!(matches!(res, Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandlePacketError::GetPayload(GetPayloadError::Decrypt)) + )); } // handle_onion_data_request @@ -2420,16 +2679,16 @@ mod tests { ping_id: INITIAL_PING_ID, search_pk: SecretKey::generate(&mut rng).public_key(), data_pk: SecretKey::generate(&mut rng).public_key(), - sendback_data: 42 + sendback_data: 42, }; let inner = InnerOnionAnnounceRequest::new(&precomp, bob_pk.clone(), &payload); let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let packet = OnionAnnounceRequest { inner, - onion_return: onion_return.clone() + onion_return: onion_return.clone(), }; alice.handle_onion_announce_request(packet, addr).await.unwrap(); @@ -2446,12 +2705,12 @@ mod tests { ping_id: payload.ping_id_or_pk, search_pk: SecretKey::generate(&mut rng).public_key(), data_pk: SecretKey::generate(&mut rng).public_key(), - sendback_data: 42 + sendback_data: 42, }; let inner = InnerOnionAnnounceRequest::new(&precomp, bob_pk.clone(), &payload); let packet = OnionAnnounceRequest { inner, - onion_return: onion_return.clone() + onion_return: onion_return.clone(), }; alice.handle_onion_announce_request(packet, addr).await.unwrap(); @@ -2465,11 +2724,11 @@ mod tests { destination_pk: bob_pk, nonce, temporary_pk: temporary_pk.clone(), - payload: payload.clone() + payload: payload.clone(), }; let packet = OnionDataRequest { inner, - onion_return: onion_return.clone() + onion_return: onion_return.clone(), }; alice.handle_onion_data_request(packet).await.unwrap(); @@ -2500,21 +2759,26 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let next_onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], }; - let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, Some(&next_onion_return)); + let onion_return = OnionReturn::new( + &mut thread_rng(), + &onion_symmetric_key, + &ip_port, + Some(&next_onion_return), + ); let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); let packet = OnionResponse3 { onion_return, - payload: payload.clone() + payload: payload.clone(), }; alice.handle_onion_response_3(packet).await.unwrap(); @@ -2536,17 +2800,14 @@ mod tests { let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] // not encrypted with onion_symmetric_key + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], // not encrypted with onion_symmetric_key }; let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); - let packet = OnionResponse3 { - onion_return, - payload - }; + let packet = OnionResponse3 { onion_return, payload }; alice.handle_onion_response_3(packet).await.unwrap(); @@ -2566,17 +2827,17 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, None); let inner = OnionDataResponse { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }; let packet = OnionResponse3 { onion_return, - payload: InnerOnionResponse::OnionDataResponse(inner.clone()) + payload: InnerOnionResponse::OnionDataResponse(inner.clone()), }; let res = alice.handle_onion_response_3(packet).await; @@ -2593,21 +2854,26 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let next_onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], }; - let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, Some(&next_onion_return)); + let onion_return = OnionReturn::new( + &mut thread_rng(), + &onion_symmetric_key, + &ip_port, + Some(&next_onion_return), + ); let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); let packet = OnionResponse2 { onion_return, - payload: payload.clone() + payload: payload.clone(), }; alice.handle_onion_response_2(packet).await.unwrap(); @@ -2629,17 +2895,14 @@ mod tests { let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] // not encrypted with onion_symmetric_key + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], // not encrypted with onion_symmetric_key }; let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); - let packet = OnionResponse2 { - onion_return, - payload - }; + let packet = OnionResponse2 { onion_return, payload }; alice.handle_onion_response_2(packet).await.unwrap(); @@ -2659,17 +2922,17 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, None); let inner = OnionDataResponse { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }; let packet = OnionResponse2 { onion_return, - payload: InnerOnionResponse::OnionDataResponse(inner.clone()) + payload: InnerOnionResponse::OnionDataResponse(inner.clone()), }; let res = alice.handle_onion_response_2(packet).await; @@ -2686,17 +2949,17 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, None); let inner = OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }; let packet = OnionResponse1 { onion_return, - payload: InnerOnionResponse::OnionAnnounceResponse(inner.clone()) + payload: InnerOnionResponse::OnionAnnounceResponse(inner.clone()), }; alice.handle_onion_response_1(packet).await.unwrap(); @@ -2721,17 +2984,17 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, None); let inner = OnionDataResponse { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }; let packet = OnionResponse1 { onion_return, - payload: InnerOnionResponse::OnionDataResponse(inner.clone()) + payload: InnerOnionResponse::OnionDataResponse(inner.clone()), }; alice.handle_onion_response_1(packet).await.unwrap(); @@ -2757,17 +3020,17 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Tcp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, None); let inner = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); let packet = OnionResponse1 { onion_return, - payload: inner.clone() + payload: inner.clone(), }; alice.handle_onion_response_1(packet).await.unwrap(); @@ -2788,17 +3051,17 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Tcp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, None); let inner = OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }; let packet = OnionResponse1 { onion_return, - payload: InnerOnionResponse::OnionAnnounceResponse(inner.clone()) + payload: InnerOnionResponse::OnionAnnounceResponse(inner.clone()), }; let res = alice.handle_onion_response_1(packet).await; @@ -2811,17 +3074,14 @@ mod tests { let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] // not encrypted with onion_symmetric_key + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], // not encrypted with onion_symmetric_key }; let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); - let packet = OnionResponse1 { - onion_return, - payload - }; + let packet = OnionResponse1 { onion_return, payload }; alice.handle_onion_response_1(packet).await.unwrap(); @@ -2841,21 +3101,26 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let next_onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], }; - let onion_return = OnionReturn::new(&mut thread_rng(), &onion_symmetric_key, &ip_port, Some(&next_onion_return)); + let onion_return = OnionReturn::new( + &mut thread_rng(), + &onion_symmetric_key, + &ip_port, + Some(&next_onion_return), + ); let inner = OnionDataResponse { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }; let packet = OnionResponse1 { onion_return, - payload: InnerOnionResponse::OnionDataResponse(inner.clone()) + payload: InnerOnionResponse::OnionDataResponse(inner.clone()), }; let res = alice.handle_onion_response_1(packet).await; @@ -2872,10 +3137,22 @@ mod tests { let friend_pk = friend_sk.public_key(); let nodes = [ - PackedNode::new("127.1.1.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("127.1.1.2:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("127.1.1.3:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("127.1.1.4:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), + PackedNode::new( + "127.1.1.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "127.1.1.2:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "127.1.1.3:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "127.1.1.4:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), ]; alice.add_friend(friend_pk.clone()).await; @@ -2899,7 +3176,10 @@ mod tests { let nat_ping_req_payload = nat_ping_req.get_payload(&precomputed_key).unwrap(); let nat_ping_req_payload = unpack!(nat_ping_req_payload, DhtRequestPayload::NatPingRequest); - assert_eq!(alice.state.read().await.friends[&friend_pk].hole_punch.ping_id, nat_ping_req_payload.id); + assert_eq!( + alice.state.read().await.friends[&friend_pk].hole_punch.ping_id, + nat_ping_req_payload.id + ); break; } rx = rx1; @@ -2968,13 +3248,13 @@ mod tests { let ip_port = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let packet = OnionRequest { nonce: [42; ::NonceSize::USIZE], ip_port: ip_port.clone(), temporary_pk: temporary_pk.clone(), - payload: payload.clone() + payload: payload.clone(), }; alice.handle_tcp_onion_request(packet, addr).await.unwrap(); @@ -3003,29 +3283,48 @@ mod tests { let node_pk = node_sk.public_key(); let pn = PackedNode::new("127.1.1.1:12345".parse().unwrap(), node_pk.clone()); - assert!(alice.state.write().await.nodes_to_bootstrap.try_add(&alice.pk, pn, /* evict */ true)); + assert!(alice + .state + .write() + .await + .nodes_to_bootstrap + .try_add(&alice.pk, pn, /* evict */ true)); let pn = PackedNode::new("127.0.0.1:33445".parse().unwrap(), bob_pk.clone()); - assert!(alice.state.write().await.nodes_to_bootstrap.try_add(&alice.pk, pn, /* evict */ true)); + assert!(alice + .state + .write() + .await + .nodes_to_bootstrap + .try_add(&alice.pk, pn, /* evict */ true)); alice.dht_main_loop().await.unwrap(); let mut state = alice.state.write().await; - rx.take(2).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::NodesRequest); - if addr == "127.0.0.1:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk).is_some()); - assert_eq!(nodes_req_payload.pk, alice.pk); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk).is_some()); - assert_eq!(nodes_req_payload.pk, alice.pk); - } - }).collect::>().await; + rx.take(2) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::NodesRequest); + if addr == "127.0.0.1:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, alice.pk); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, alice.pk); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3036,27 +3335,44 @@ mod tests { let node_pk = node_sk.public_key(); let pn = PackedNode::new("127.1.1.1:12345".parse().unwrap(), node_pk.clone()); - assert!(alice.nodes_to_ping.write().await.try_add(&alice.pk, pn, /* evict */ true)); + assert!(alice + .nodes_to_ping + .write() + .await + .try_add(&alice.pk, pn, /* evict */ true)); let pn = PackedNode::new("127.0.0.1:33445".parse().unwrap(), bob_pk.clone()); - assert!(alice.nodes_to_ping.write().await.try_add(&alice.pk, pn, /* evict */ true)); + assert!(alice + .nodes_to_ping + .write() + .await + .try_add(&alice.pk, pn, /* evict */ true)); alice.send_pings().await.unwrap(); let mut state = alice.state.write().await; - rx.take(2).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::PingRequest); - if addr == "127.0.0.1:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let ping_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(ping_req_payload.id, |pk| pk == &bob_pk).is_some()); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let ping_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(ping_req_payload.id, |pk| pk == &node_pk).is_some()); - } - }).collect::>().await; + rx.take(2) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::PingRequest); + if addr == "127.0.0.1:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let ping_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(ping_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let ping_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(ping_req_payload.id, |pk| pk == &node_pk) + .is_some()); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3089,20 +3405,29 @@ mod tests { let mut state = alice.state.write().await; // 3 = 2 packets sent by ping_close_nodes + 1 packet sent by send_nodes_req_random - rx.take(3).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::NodesRequest); - if addr == "127.0.0.1:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk).is_some()); - assert_eq!(nodes_req_payload.pk, alice.pk); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk).is_some()); - assert_eq!(nodes_req_payload.pk, alice.pk); - } - }).collect::>().await; + rx.take(3) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::NodesRequest); + if addr == "127.0.0.1:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, alice.pk); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, alice.pk); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3123,7 +3448,7 @@ mod tests { // Random request should be sent every second MAX_BOOTSTRAP_TIMES times // This loop will produce MAX_BOOTSTRAP_TIMES random packets - for _ in 0 .. MAX_BOOTSTRAP_TIMES { + for _ in 0..MAX_BOOTSTRAP_TIMES { alice.dht_main_loop().await.unwrap(); let (received, rx1) = rx.into_future().await; @@ -3170,20 +3495,29 @@ mod tests { let mut state = alice.state.write().await; - rx.take(2).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::NodesRequest); - if addr == "127.0.0.1:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk).is_some()); - assert_eq!(nodes_req_payload.pk, friend_pk); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk).is_some()); - assert_eq!(nodes_req_payload.pk, friend_pk); - } - }).collect::>().await; + rx.take(2) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::NodesRequest); + if addr == "127.0.0.1:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, friend_pk); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, friend_pk); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3213,20 +3547,29 @@ mod tests { let mut state = alice.state.write().await; // 3 = 2 packets sent by ping_close_nodes + 1 packet sent by send_nodes_req_random - rx.take(3).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::NodesRequest); - if addr == "127.0.0.1:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk).is_some()); - assert_eq!(nodes_req_payload.pk, friend_pk); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk).is_some()); - assert_eq!(nodes_req_payload.pk, friend_pk); - } - }).collect::>().await; + rx.take(3) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::NodesRequest); + if addr == "127.0.0.1:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, friend_pk); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk) + .is_some()); + assert_eq!(nodes_req_payload.pk, friend_pk); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3253,8 +3596,16 @@ mod tests { // Random request should be sent every second MAX_BOOTSTRAP_TIMES times // This loop will produce MAX_BOOTSTRAP_TIMES random packets - for _ in 0 .. MAX_BOOTSTRAP_TIMES { - alice.state.write().await.friends.get_mut(&friend_pk).unwrap().hole_punch.last_send_ping_time = Some(clock_now()); + for _ in 0..MAX_BOOTSTRAP_TIMES { + alice + .state + .write() + .await + .friends + .get_mut(&friend_pk) + .unwrap() + .hole_punch + .last_send_ping_time = Some(clock_now()); alice.dht_main_loop().await.unwrap(); let (received, rx1) = rx.into_future().await; @@ -3302,18 +3653,27 @@ mod tests { let mut state = alice.state.write().await; - rx.take(2).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::NodesRequest); - if addr == "[FF::01]:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk).is_some()); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk).is_some()); - } - }).collect::>().await; + rx.take(2) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::NodesRequest); + if addr == "[FF::01]:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk) + .is_some()); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3335,18 +3695,27 @@ mod tests { let mut state = alice.state.write().await; - rx.take(2).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::NodesRequest); - if addr == "[FF::01]:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk).is_some()); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk).is_some()); - } - }).collect::>().await; + rx.take(2) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::NodesRequest); + if addr == "[FF::01]:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk) + .is_some()); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3397,18 +3766,27 @@ mod tests { let mut state = alice.state.write().await; - rx.take(2).map(|(packet, addr)| { - let nodes_req = unpack!(packet, Packet::NodesRequest); - if addr == "[FF::01]:33445".parse().unwrap() { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk).is_some()); - } else { - let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); - let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); - assert!(state.request_queue.check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk).is_some()); - } - }).collect::>().await; + rx.take(2) + .map(|(packet, addr)| { + let nodes_req = unpack!(packet, Packet::NodesRequest); + if addr == "[FF::01]:33445".parse().unwrap() { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &bob_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &bob_pk) + .is_some()); + } else { + let precomputed_key = SalsaBox::new(&nodes_req.pk, &node_sk); + let nodes_req_payload = nodes_req.get_payload(&precomputed_key).unwrap(); + assert!(state + .request_queue + .check_ping_id(nodes_req_payload.id, |pk| pk == &node_pk) + .is_some()); + } + }) + .collect::>() + .await; } #[tokio::test] @@ -3442,12 +3820,23 @@ mod tests { let mut state = alice.state.write().await; for pk in &alice.fake_friends_keys { - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); assert!(state.friends.get_mut(pk).unwrap().close_nodes.try_add(pk, node, true)); } - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - assert!(state.friends.get_mut(&friend_pk).unwrap().close_nodes.try_add(&friend_pk, node.clone(), true)); + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + assert!(state + .friends + .get_mut(&friend_pk) + .unwrap() + .close_nodes + .try_add(&friend_pk, node.clone(), true)); drop(state); @@ -3466,7 +3855,12 @@ mod tests { let (alice, _precomp, _bob_pk, _bob_sk, _rx, _addr) = create_node(); assert!(!alice.is_connected().await); - alice.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + alice + .add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; assert!(alice.is_connected().await); } } diff --git a/tox_core/src/dht/server_ext.rs b/tox_core/src/dht/server_ext.rs index e85289719..bfbbde8fe 100644 --- a/tox_core/src/dht/server_ext.rs +++ b/tox_core/src/dht/server_ext.rs @@ -1,30 +1,28 @@ //! Extension trait for running DHT server on `UdpSocket` use std::io::{Error, ErrorKind}; -use std::net::{SocketAddr, IpAddr}; +use std::net::{IpAddr, SocketAddr}; -use futures::{FutureExt, SinkExt, StreamExt}; use futures::channel::mpsc::Receiver; +use futures::{FutureExt, SinkExt, StreamExt}; use tokio::net::UdpSocket; use crate::dht::codec::*; -use tox_packet::dht::Packet; -use crate::udp::Server; use crate::stats::Stats; +use crate::udp::Server; +use tox_packet::dht::Packet; /// Run DHT server on `UdpSocket`. pub async fn dht_run_socket( udp: &Server, socket: UdpSocket, mut rx: Receiver<(Packet, SocketAddr)>, - stats: Stats + stats: Stats, ) -> Result<(), Error> { - let udp_addr = socket.local_addr() - .expect("Failed to get socket address"); + let udp_addr = socket.local_addr().expect("Failed to get socket address"); let codec = DhtCodec::new(stats); - let (mut sink, mut stream) = - tokio_util::udp::UdpFramed::new(socket, codec).split(); + let (mut sink, mut stream) = tokio_util::udp::UdpFramed::new(socket, codec).split(); let network_reader = async { while let Some(event) = stream.next().await { @@ -36,7 +34,7 @@ pub async fn dht_run_socket( if let Err(ref err) = res { error!("Failed to handle packet: {:?}", err); } - }, + } Err(e) => { error!("packet receive error = {:?}", e); // ignore packet decode errors @@ -53,7 +51,9 @@ pub async fn dht_run_socket( let network_writer = async { while let Some((packet, mut addr)) = rx.next().await { // filter out IPv6 packets if node is running in IPv4 mode - if udp_addr.is_ipv4() && addr.is_ipv6() { continue } + if udp_addr.is_ipv4() && addr.is_ipv6() { + continue; + } if udp_addr.is_ipv6() { if let IpAddr::V4(ip) = addr.ip() { @@ -62,7 +62,8 @@ pub async fn dht_run_socket( } trace!("Sending packet {:?} to {:?}", packet, addr); - sink.send((packet, addr)).await + sink.send((packet, addr)) + .await .map_err(|e| Error::new(ErrorKind::Other, e))? } @@ -87,9 +88,9 @@ mod tests { use futures::channel::mpsc; use futures::TryStreamExt; + use crate::dht::server::Server as DhtServer; use rand::thread_rng; use tox_packet::dht::*; - use crate::dht::server::Server as DhtServer; #[tokio::test] async fn run_socket() { @@ -118,7 +119,8 @@ mod tests { let client_future = async { // Send invalid request first to ensure that the server won't crash - client_socket.send_to(&[42; 123][..], &server_addr) + client_socket + .send_to(&[42; 123][..], &server_addr) .await .map_err(|e| Error::new(ErrorKind::Other, e))?; @@ -128,28 +130,26 @@ mod tests { // Send ping request let ping_id = 42; - let ping_request_payload = PingRequestPayload { - id: ping_id, - }; + let ping_request_payload = PingRequestPayload { id: ping_id }; let ping_request = PingRequest::new(&shared_secret, client_pk, &ping_request_payload); - sink.send((Packet::PingRequest(ping_request), server_addr)).await + sink.send((Packet::PingRequest(ping_request), server_addr)) + .await .map_err(|e| Error::new(ErrorKind::Other, e))?; // And wait for ping response let ping_response = stream - .try_filter_map(|(packet, _)| futures::future::ok( - match packet { + .try_filter_map(|(packet, _)| { + futures::future::ok(match packet { Packet::PingResponse(ping_response) => Some(ping_response), _ => None, - } - )) + }) + }) .next() .await .unwrap(); - let ping_response = ping_response - .map_err(|e| Error::new(ErrorKind::Other, e))?; + let ping_response = ping_response.map_err(|e| Error::new(ErrorKind::Other, e))?; let ping_response_payload = ping_response.get_payload(&shared_secret).unwrap(); assert_eq!(ping_response_payload.id, ping_id); diff --git a/tox_core/src/friend_connection/errors.rs b/tox_core/src/friend_connection/errors.rs index 39cef1cef..d08f9ed78 100644 --- a/tox_core/src/friend_connection/errors.rs +++ b/tox_core/src/friend_connection/errors.rs @@ -4,7 +4,10 @@ use futures::channel::mpsc::SendError; use thiserror::Error; use tokio::time::error::Elapsed; -use crate::{net_crypto::errors::{KillConnectionError, SendLosslessPacketError}, relay::client::ConnectionError}; +use crate::{ + net_crypto::errors::{KillConnectionError, SendLosslessPacketError}, + relay::client::ConnectionError, +}; /// Error that can happen while removing a friend #[derive(Clone, Debug, Eq, PartialEq, Error)] @@ -37,7 +40,7 @@ pub enum RunError { AddTcpConnection(ConnectionError), /// Failed to send connection status. #[error("Failed to send connection status")] - SendToConnectionStatus(SendError) + SendToConnectionStatus(SendError), } /// Error that can happen while handling `ShareRelays` packet. @@ -45,5 +48,5 @@ pub enum RunError { pub enum HandleShareRelaysError { /// Failed to add TCP connection. #[error("Failed to TCP connection")] - AddTcpConnection(ConnectionError) + AddTcpConnection(ConnectionError), } diff --git a/tox_core/src/friend_connection/mod.rs b/tox_core/src/friend_connection/mod.rs index 8af6426b9..976edd12e 100644 --- a/tox_core/src/friend_connection/mod.rs +++ b/tox_core/src/friend_connection/mod.rs @@ -3,28 +3,28 @@ pub mod errors; -use std::collections::HashMap; use std::collections::hash_map::Entry; +use std::collections::HashMap; use std::net::SocketAddr; use std::sync::Arc; use std::time::{Duration, Instant}; -use futures::{FutureExt, StreamExt, SinkExt, future}; use futures::channel::mpsc; +use futures::{future, FutureExt, SinkExt, StreamExt}; use tokio::sync::RwLock; -use tox_binary_io::*; -use tox_crypto::*; use crate::dht::dht_node::BAD_NODE_TIMEOUT; -use tox_packet::dht::packed_node::PackedNode; use crate::dht::server::Server as DhtServer; use crate::friend_connection::errors::*; -use tox_packet::friend_connection::*; -use crate::net_crypto::NetCrypto; use crate::net_crypto::errors::KillConnectionError; +use crate::net_crypto::NetCrypto; use crate::onion::client::OnionClient; use crate::relay::client::Connections as TcpConnections; use crate::time::*; +use tox_binary_io::*; +use tox_crypto::*; +use tox_packet::dht::packed_node::PackedNode; +use tox_packet::friend_connection::*; /// Shorthand for the transmit half of the message channel for sending a /// connection status when it becomes connected or disconnected. The key is a @@ -143,13 +143,15 @@ impl FriendConnections { }; self.net_crypto.remove_friend(friend_pk.clone()).await; self.onion_client.remove_friend(friend_pk.clone()).await; - self.net_crypto.kill_connection(friend_pk.clone()) - .then(|res| future::ready(match res { - Err(ref e) - if e == &KillConnectionError::NoConnection => - Ok(()), - res => res, - })).await + self.net_crypto + .kill_connection(friend_pk.clone()) + .then(|res| { + future::ready(match res { + Err(ref e) if e == &KillConnectionError::NoConnection => Ok(()), + res => res, + }) + }) + .await .map_err(RemoveFriendError::KillConnection) } else { Err(RemoveFriendError::NoFriend) @@ -157,11 +159,17 @@ impl FriendConnections { } /// Handle received `ShareRelays` packet. - pub async fn handle_share_relays(&self, friend_pk: PublicKey, share_relays: ShareRelays) -> Result<(), HandleShareRelaysError> { + pub async fn handle_share_relays( + &self, + friend_pk: PublicKey, + share_relays: ShareRelays, + ) -> Result<(), HandleShareRelaysError> { if let Some(friend) = self.friends.read().await.get(&friend_pk) { if let Some(ref dht_pk) = friend.dht_pk { for node in share_relays.relays { - self.tcp_connections.add_relay_connection(node.saddr, node.pk, dht_pk.clone()).await + self.tcp_connections + .add_relay_connection(node.saddr, node.pk, dht_pk.clone()) + .await .map_err(HandleShareRelaysError::AddTcpConnection)?; } } @@ -178,7 +186,10 @@ impl FriendConnections { } /// Handle the stream of found DHT `PublicKey`s. - async fn handle_dht_pk(&self, dht_pk_rx: &mut mpsc::UnboundedReceiver<(PublicKey, PublicKey)>) -> Result<(), RunError> { + async fn handle_dht_pk( + &self, + dht_pk_rx: &mut mpsc::UnboundedReceiver<(PublicKey, PublicKey)>, + ) -> Result<(), RunError> { let dht = self.dht.clone(); let net_crypto = self.net_crypto.clone(); let onion_client = self.onion_client.clone(); @@ -194,15 +205,15 @@ impl FriendConnections { if let Some(ref dht_pk) = friend.dht_pk { dht.remove_friend(dht_pk.clone()).await; - net_crypto.kill_connection(real_pk.clone()) - .then(|res| future::ready( - match res { - Err(ref e) - if e == &KillConnectionError::NoConnection => - Ok(()), + net_crypto + .kill_connection(real_pk.clone()) + .then(|res| { + future::ready(match res { + Err(ref e) if e == &KillConnectionError::NoConnection => Ok(()), res => res, - } - )).await + }) + }) + .await .map_err(RunError::KillConnection)?; // TODO: handle error properly after migrating the TCP client to failure tcp_connections.remove_connection(dht_pk.clone()).await.ok(); @@ -221,12 +232,16 @@ impl FriendConnections { } /// Handle the stream of found IP addresses. - async fn handle_friend_saddr(&self, friend_saddr_rx: &mut mpsc::UnboundedReceiver) -> Result<(), RunError> { + async fn handle_friend_saddr( + &self, + friend_saddr_rx: &mut mpsc::UnboundedReceiver, + ) -> Result<(), RunError> { let net_crypto = self.net_crypto.clone(); let friends = self.friends.clone(); while let Some(ref node) = friend_saddr_rx.next().await { let mut friends = friends.write().await; - let friend = friends.values_mut() + let friend = friends + .values_mut() .find(|friend| friend.dht_pk.as_ref() == Some(&node.pk)); if let Some(friend) = friend { friend.saddr_time = Some(clock_now()); @@ -246,7 +261,10 @@ impl FriendConnections { } /// Handle the stream of connection statuses. - async fn handle_connection_status(&self, connnection_status_rx: &mut mpsc::UnboundedReceiver<(PublicKey, bool)>) -> Result<(), RunError> { + async fn handle_connection_status( + &self, + connnection_status_rx: &mut mpsc::UnboundedReceiver<(PublicKey, bool)>, + ) -> Result<(), RunError> { let onion_client = self.onion_client.clone(); let friends = self.friends.clone(); let connection_status_tx = self.connection_status_tx.clone(); @@ -269,7 +287,9 @@ impl FriendConnections { friend.connected = status; onion_client.set_friend_connected(real_pk.clone(), status).await; if let Some(mut connection_status_tx) = connection_status_tx.read().await.clone() { - connection_status_tx.send((real_pk, status)).await + connection_status_tx + .send((real_pk, status)) + .await .map_err(RunError::SendToConnectionStatus)?; } } @@ -285,17 +305,19 @@ impl FriendConnections { let relays = self.tcp_connections.get_random_relays(MAX_SHARED_RELAYS as u8).await; if !relays.is_empty() { for relay in &relays { - self.tcp_connections.add_connection(relay.pk.clone(), friend_pk.clone()).await + self.tcp_connections + .add_connection(relay.pk.clone(), friend_pk.clone()) + .await .map_err(RunError::AddTcpConnection)?; } - let share_relays = ShareRelays { - relays, - }; + let share_relays = ShareRelays { relays }; let mut buf = vec![0; 154]; let (_, size) = share_relays.to_bytes((&mut buf, 0)).unwrap(); buf.truncate(size); - self.net_crypto.send_lossless(friend_pk, buf).await + self.net_crypto + .send_lossless(friend_pk, buf) + .await .map_err(RunError::SendTo) } else { Ok(()) @@ -306,30 +328,46 @@ impl FriendConnections { async fn main_loop(&self) -> Result<(), RunError> { for friend in self.friends.write().await.values_mut() { if friend.connected { - if friend.ping_received_time.map_or(true, |time| clock_elapsed(time) >= FRIEND_CONNECTION_TIMEOUT) { - self.net_crypto.kill_connection(friend.real_pk.clone()) - .then(|res| future::ready(match res { - Err(ref e) - if e == &KillConnectionError::NoConnection => - Ok(()), - res => res, - })).await + if friend + .ping_received_time + .map_or(true, |time| clock_elapsed(time) >= FRIEND_CONNECTION_TIMEOUT) + { + self.net_crypto + .kill_connection(friend.real_pk.clone()) + .then(|res| { + future::ready(match res { + Err(ref e) if e == &KillConnectionError::NoConnection => Ok(()), + res => res, + }) + }) + .await .map_err(RunError::KillConnection)?; continue; } - if friend.ping_sent_time.map_or(true, |time| clock_elapsed(time) >= FRIEND_PING_INTERVAL) { - self.net_crypto.send_lossless(friend.real_pk.clone(), vec![PACKET_ID_ALIVE]).await + if friend + .ping_sent_time + .map_or(true, |time| clock_elapsed(time) >= FRIEND_PING_INTERVAL) + { + self.net_crypto + .send_lossless(friend.real_pk.clone(), vec![PACKET_ID_ALIVE]) + .await .map_err(RunError::SendTo)?; friend.ping_sent_time = Some(clock_now()); } - if friend.share_relays_time.map_or(true, |time| clock_elapsed(time) >= SHARE_RELAYS_INTERVAL) { + if friend + .share_relays_time + .map_or(true, |time| clock_elapsed(time) >= SHARE_RELAYS_INTERVAL) + { self.share_relays(friend.real_pk.clone()).await?; friend.share_relays_time = Some(clock_now()); } } else { - if friend.dht_pk_time.map_or(false, |time| clock_elapsed(time) >= FRIEND_DHT_TIMEOUT) { + if friend + .dht_pk_time + .map_or(false, |time| clock_elapsed(time) >= FRIEND_DHT_TIMEOUT) + { if let Some(ref dht_pk) = friend.dht_pk { self.dht.remove_friend(dht_pk.clone()).await; } @@ -337,13 +375,18 @@ impl FriendConnections { friend.dht_pk_time = None; } - if friend.saddr_time.map_or(false, |time| clock_elapsed(time) >= FRIEND_DHT_TIMEOUT) { + if friend + .saddr_time + .map_or(false, |time| clock_elapsed(time) >= FRIEND_DHT_TIMEOUT) + { friend.saddr = None; friend.saddr_time = None; } if let Some(ref dht_pk) = friend.dht_pk { - self.net_crypto.add_connection(friend.real_pk.clone(), dht_pk.clone()).await; + self.net_crypto + .add_connection(friend.real_pk.clone(), dht_pk.clone()) + .await; if let Some(saddr) = friend.saddr { self.net_crypto.set_friend_udp_addr(friend.real_pk.clone(), saddr).await; } @@ -370,7 +413,7 @@ impl FriendConnections { if let Err(ref e) = res { warn!("Failed to send friend's periodical packets: {}", e); - return res + return res; } } } @@ -414,10 +457,13 @@ mod tests { use super::*; use rand::thread_rng; - use tox_packet::dht::{Packet as DhtPacket, *}; use crate::dht::precomputed_cache::*; use crate::net_crypto::*; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; + use tox_packet::dht::{Packet as DhtPacket, *}; type DhtRx = mpsc::Receiver<(DhtPacket, SocketAddr)>; type LosslessRx = mpsc::UnboundedReceiver<(PublicKey, Vec)>; @@ -446,12 +492,7 @@ mod tests { real_sk, precomputed_keys, }); - let friend_connections = FriendConnections::new( - dht, - tcp_connections, - onion_client, - net_crypto - ); + let friend_connections = FriendConnections::new(dht, tcp_connections, onion_client, net_crypto); (friend_connections, udp_rx, lossless_rx) } @@ -481,18 +522,29 @@ mod tests { let (_relay_incoming_rx, _relay_outgoing_rx, relay_pk) = friend_connections.tcp_connections.add_client().await; // ignore result future since it spawns the connection which should be // executed inside tokio context - let _ = friend_connections.tcp_connections.add_connection(relay_pk, friend_dht_pk.clone()); + let _ = friend_connections + .tcp_connections + .add_connection(relay_pk, friend_dht_pk.clone()); - let session_precomputed_key = SalsaBox::new(&SecretKey::generate(&mut rng).public_key(), &SecretKey::generate(&mut rng)); + let session_precomputed_key = SalsaBox::new( + &SecretKey::generate(&mut rng).public_key(), + &SecretKey::generate(&mut rng), + ); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); - friend_connections.net_crypto.add_established_connection( - SecretKey::generate(&mut rng).public_key(), - friend_pk.clone(), - sent_nonce, - [42; ::NonceSize::USIZE], - session_precomputed_key.clone() - ).await; - friend_connections.net_crypto.set_friend_udp_addr(friend_pk.clone(), saddr).await; + friend_connections + .net_crypto + .add_established_connection( + SecretKey::generate(&mut rng).public_key(), + friend_pk.clone(), + sent_nonce, + [42; ::NonceSize::USIZE], + session_precomputed_key.clone(), + ) + .await; + friend_connections + .net_crypto + .set_friend_udp_addr(friend_pk.clone(), saddr) + .await; friend_connections.remove_friend(friend_pk.clone()).await.unwrap(); @@ -527,29 +579,47 @@ mod tests { friend.dht_pk_time = Some(now); friend.saddr = Some(saddr); friend.saddr_time = Some(now); - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); friend_connections.dht.add_friend(friend_dht_pk.clone()).await; friend_connections.net_crypto.add_friend(friend_pk.clone()).await; friend_connections.onion_client.add_friend(friend_pk.clone()).await; let (_relay_incoming_rx, _relay_outgoing_rx, relay_pk) = friend_connections.tcp_connections.add_client().await; // ignore result future since it spawns the connection which should be // executed inside tokio context - let _ = friend_connections.tcp_connections.add_connection(relay_pk, friend_dht_pk.clone()); + let _ = friend_connections + .tcp_connections + .add_connection(relay_pk, friend_dht_pk.clone()); - let session_precomputed_key = SalsaBox::new(&SecretKey::generate(&mut rng).public_key(), &SecretKey::generate(&mut rng)); + let session_precomputed_key = SalsaBox::new( + &SecretKey::generate(&mut rng).public_key(), + &SecretKey::generate(&mut rng), + ); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); - friend_connections.net_crypto.add_established_connection( - SecretKey::generate(&mut rng).public_key(), - friend_pk.clone(), - sent_nonce, - [42; ::NonceSize::USIZE], - session_precomputed_key.clone() - ).await; - friend_connections.net_crypto.set_friend_udp_addr(friend_pk.clone(), saddr).await; + friend_connections + .net_crypto + .add_established_connection( + SecretKey::generate(&mut rng).public_key(), + friend_pk.clone(), + sent_nonce, + [42; ::NonceSize::USIZE], + session_precomputed_key.clone(), + ) + .await; + friend_connections + .net_crypto + .set_friend_udp_addr(friend_pk.clone(), saddr) + .await; let new_friend_dht_pk = SecretKey::generate(&mut rng).public_key(); let (mut dht_pk_tx, mut dht_pk_rx) = mpsc::unbounded(); - dht_pk_tx.send((friend_pk.clone(), new_friend_dht_pk.clone())).await.unwrap(); + dht_pk_tx + .send((friend_pk.clone(), new_friend_dht_pk.clone())) + .await + .unwrap(); drop(dht_pk_tx); let delay = Duration::from_secs(1); @@ -559,8 +629,14 @@ mod tests { assert!(!friend_connections.dht.has_friend(&friend_dht_pk).await); assert!(friend_connections.dht.has_friend(&new_friend_dht_pk).await); - assert_eq!(friend_connections.net_crypto.connection_dht_pk(&friend_pk).await, Some(new_friend_dht_pk.clone())); - assert_eq!(friend_connections.onion_client.friend_dht_pk(&friend_pk).await, Some(new_friend_dht_pk.clone())); + assert_eq!( + friend_connections.net_crypto.connection_dht_pk(&friend_pk).await, + Some(new_friend_dht_pk.clone()) + ); + assert_eq!( + friend_connections.onion_client.friend_dht_pk(&friend_pk).await, + Some(new_friend_dht_pk.clone()) + ); assert!(!friend_connections.tcp_connections.has_connection(&friend_dht_pk).await); let friend = &friend_connections.friends.read().await[&friend_pk]; @@ -590,18 +666,31 @@ mod tests { let mut friend = Friend::new(friend_pk.clone()); friend.dht_pk = Some(friend_dht_pk.clone()); friend.dht_pk_time = Some(now); - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); let saddr = "127.0.0.1:12345".parse().unwrap(); let (mut friend_saddr_tx, mut friend_saddr_rx) = mpsc::unbounded(); - friend_saddr_tx.send(PackedNode::new(saddr, friend_dht_pk.clone())).await.unwrap(); + friend_saddr_tx + .send(PackedNode::new(saddr, friend_dht_pk.clone())) + .await + .unwrap(); drop(friend_saddr_tx); let delay = Duration::from_secs(1); tokio::time::advance(delay).await; - friend_connections.handle_friend_saddr(&mut friend_saddr_rx).await.unwrap(); - assert_eq!(friend_connections.net_crypto.connection_saddr(&friend_pk).await, Some(saddr)); + friend_connections + .handle_friend_saddr(&mut friend_saddr_rx) + .await + .unwrap(); + assert_eq!( + friend_connections.net_crypto.connection_saddr(&friend_pk).await, + Some(saddr) + ); let friend = &friend_connections.friends.read().await[&friend_pk]; assert_eq!(friend.dht_pk, Some(friend_dht_pk)); @@ -624,14 +713,21 @@ mod tests { friend.dht_pk_time = Some(now); friend.ping_sent_time = Some(now); friend.share_relays_time = Some(now); - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); friend_connections.onion_client.add_friend(friend_pk.clone()).await; let (mut connnection_status_tx, mut connnection_status_rx) = mpsc::unbounded(); connnection_status_tx.send((friend_pk.clone(), true)).await.unwrap(); drop(connnection_status_tx); - friend_connections.handle_connection_status(&mut connnection_status_rx).await.unwrap(); + friend_connections + .handle_connection_status(&mut connnection_status_rx) + .await + .unwrap(); let friend = &friend_connections.friends.read().await[&friend_pk]; assert!(friend.connected); @@ -655,15 +751,25 @@ mod tests { friend.dht_pk = Some(friend_dht_pk); friend.dht_pk_time = Some(now); friend.connected = true; - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); friend_connections.onion_client.add_friend(friend_pk.clone()).await; - friend_connections.onion_client.set_friend_connected(friend_pk.clone(), true).await; + friend_connections + .onion_client + .set_friend_connected(friend_pk.clone(), true) + .await; let (mut connnection_status_tx, mut connnection_status_rx) = mpsc::unbounded(); connnection_status_tx.send((friend_pk.clone(), false)).await.unwrap(); drop(connnection_status_tx); - friend_connections.handle_connection_status(&mut connnection_status_rx).await.unwrap(); + friend_connections + .handle_connection_status(&mut connnection_status_rx) + .await + .unwrap(); let friend = &friend_connections.friends.read().await[&friend_pk]; assert!(!friend.connected); @@ -690,18 +796,31 @@ mod tests { friend.ping_sent_time = Some(now); friend.share_relays_time = Some(now); friend.connected = true; - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); - - let session_precomputed_key = SalsaBox::new(&SecretKey::generate(&mut rng).public_key(), &SecretKey::generate(&mut rng)); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); + + let session_precomputed_key = SalsaBox::new( + &SecretKey::generate(&mut rng).public_key(), + &SecretKey::generate(&mut rng), + ); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); - friend_connections.net_crypto.add_established_connection( - SecretKey::generate(&mut rng).public_key(), - friend_pk.clone(), - sent_nonce, - [42; ::NonceSize::USIZE], - session_precomputed_key.clone() - ).await; - friend_connections.net_crypto.set_friend_udp_addr(friend_pk, saddr).await; + friend_connections + .net_crypto + .add_established_connection( + SecretKey::generate(&mut rng).public_key(), + friend_pk.clone(), + sent_nonce, + [42; ::NonceSize::USIZE], + session_precomputed_key.clone(), + ) + .await; + friend_connections + .net_crypto + .set_friend_udp_addr(friend_pk, saddr) + .await; tokio::time::pause(); tokio::time::advance(FRIEND_CONNECTION_TIMEOUT + Duration::from_secs(1)).await; @@ -737,18 +856,31 @@ mod tests { friend.ping_received_time = Some(now); friend.share_relays_time = Some(now); friend.connected = true; - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); - - let session_precomputed_key = SalsaBox::new(&SecretKey::generate(&mut rng).public_key(), &SecretKey::generate(&mut rng)); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); + + let session_precomputed_key = SalsaBox::new( + &SecretKey::generate(&mut rng).public_key(), + &SecretKey::generate(&mut rng), + ); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); - friend_connections.net_crypto.add_established_connection( - SecretKey::generate(&mut rng).public_key(), - friend_pk.clone(), - sent_nonce, - [42; ::NonceSize::USIZE], - session_precomputed_key.clone() - ).await; - friend_connections.net_crypto.set_friend_udp_addr(friend_pk.clone(), saddr).await; + friend_connections + .net_crypto + .add_established_connection( + SecretKey::generate(&mut rng).public_key(), + friend_pk.clone(), + sent_nonce, + [42; ::NonceSize::USIZE], + session_precomputed_key.clone(), + ) + .await; + friend_connections + .net_crypto + .set_friend_udp_addr(friend_pk.clone(), saddr) + .await; let delay = Duration::from_secs(1); tokio::time::advance(delay).await; @@ -787,18 +919,31 @@ mod tests { friend.ping_received_time = Some(now); friend.ping_sent_time = Some(now); friend.connected = true; - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); - - let session_precomputed_key = SalsaBox::new(&SecretKey::generate(&mut rng).public_key(), &SecretKey::generate(&mut rng)); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); + + let session_precomputed_key = SalsaBox::new( + &SecretKey::generate(&mut rng).public_key(), + &SecretKey::generate(&mut rng), + ); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); - friend_connections.net_crypto.add_established_connection( - SecretKey::generate(&mut rng).public_key(), - friend_pk.clone(), - sent_nonce, - [42; ::NonceSize::USIZE], - session_precomputed_key.clone() - ).await; - friend_connections.net_crypto.set_friend_udp_addr(friend_pk.clone(), saddr).await; + friend_connections + .net_crypto + .add_established_connection( + SecretKey::generate(&mut rng).public_key(), + friend_pk.clone(), + sent_nonce, + [42; ::NonceSize::USIZE], + session_precomputed_key.clone(), + ) + .await; + friend_connections + .net_crypto + .set_friend_udp_addr(friend_pk.clone(), saddr) + .await; let (_relay_incoming_rx, _relay_outgoing_rx, relay_pk) = friend_connections.tcp_connections.add_client().await; @@ -841,7 +986,11 @@ mod tests { friend.saddr_time = Some(now + delay); friend.ping_received_time = Some(now); friend.ping_sent_time = Some(now); - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); tokio::time::advance(delay).await; @@ -872,7 +1021,11 @@ mod tests { friend.saddr_time = Some(now); friend.ping_received_time = Some(now); friend.ping_sent_time = Some(now); - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); tokio::time::advance(delay).await; friend_connections.main_loop().await.unwrap(); @@ -894,7 +1047,11 @@ mod tests { let mut friend = Friend::new(friend_pk.clone()); friend.dht_pk = Some(friend_dht_pk.clone()); friend.connected = true; - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); let relay_pk = SecretKey::generate(&mut rng).public_key(); let relay_saddr = "127.0.0.1:12345".parse().unwrap(); @@ -902,7 +1059,10 @@ mod tests { relays: vec![PackedNode::new(relay_saddr, relay_pk.clone())], }; - friend_connections.handle_share_relays(friend_pk, share_relays).await.unwrap(); + friend_connections + .handle_share_relays(friend_pk, share_relays) + .await + .unwrap(); assert!(friend_connections.tcp_connections.has_relay(&relay_pk).await); assert!(friend_connections.tcp_connections.has_connection(&friend_dht_pk).await); @@ -921,7 +1081,11 @@ mod tests { friend.ping_received_time = Some(now); friend.ping_sent_time = Some(now); friend.connected = true; - friend_connections.friends.write().await.insert(friend_pk.clone(), friend); + friend_connections + .friends + .write() + .await + .insert(friend_pk.clone(), friend); let duration = Duration::from_secs(1); tokio::time::advance(duration).await; @@ -944,21 +1108,24 @@ mod tests { friend_connections.add_friend(friend_pk.clone()).await; let (connection_status_tx, mut connection_status_rx) = mpsc::unbounded(); - friend_connections.set_connection_status_sink(connection_status_tx).await; + friend_connections + .set_connection_status_sink(connection_status_tx) + .await; // the ordering is essential since `run` adds its handlers that should // be done before packets handling - let run_future = friend_connections.run() - .map(Result::unwrap); + let run_future = friend_connections.run().map(Result::unwrap); let precomputed_key = SalsaBox::new(friend_connections.net_crypto.real_pk(), &friend_sk); - let cookie = friend_connections.net_crypto.get_cookie(&mut rng, friend_pk.clone(), friend_dht_pk); + let cookie = friend_connections + .net_crypto + .get_cookie(&mut rng, friend_pk.clone(), friend_dht_pk); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); let friend_session_sk = SecretKey::generate(&mut rng); let friend_session_pk = friend_session_sk.public_key(); let our_cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; 88] + payload: vec![42; 88], }; let handshake_payload = CryptoHandshakePayload { base_nonce: sent_nonce, @@ -970,7 +1137,10 @@ mod tests { let net_crypto = friend_connections.net_crypto.clone(); let packets_future = async { - net_crypto.handle_udp_crypto_handshake(&handshake, friend_saddr).await.unwrap(); + net_crypto + .handle_udp_crypto_handshake(&handshake, friend_saddr) + .await + .unwrap(); let session_pk = net_crypto.get_session_pk(&friend_pk).await.unwrap(); let session_precomputed_key = SalsaBox::new(&session_pk, &friend_session_sk); @@ -982,7 +1152,10 @@ mod tests { }; let crypto_data = CryptoData::new(&session_precomputed_key, sent_nonce, &crypto_data_payload); - net_crypto.handle_udp_crypto_data(&crypto_data, friend_saddr).await.unwrap(); + net_crypto + .handle_udp_crypto_data(&crypto_data, friend_saddr) + .await + .unwrap(); let (received, _lossless_rx) = lossless_rx.into_future().await; let (received_pk, received_data) = received.unwrap(); diff --git a/tox_core/src/io_tokio.rs b/tox_core/src/io_tokio.rs index 09b160337..de8fcf577 100644 --- a/tox_core/src/io_tokio.rs +++ b/tox_core/src/io_tokio.rs @@ -5,21 +5,21 @@ use futures::sink::SinkExt; /// Sends a message into `Option>` pub async fn maybe_send_bounded( chan: Option>, - value: T + value: T, ) -> Result<(), futures::channel::mpsc::SendError> { match chan { Some(mut c) => c.send(value).await, - None => Ok(()) + None => Ok(()), } } /// Sends a message into `Option>` pub async fn maybe_send_unbounded( chan: Option>, - value: T + value: T, ) -> Result<(), futures::channel::mpsc::SendError> { match chan { Some(mut c) => c.send(value).await, - None => Ok(()) + None => Ok(()), } } diff --git a/tox_core/src/lib.rs b/tox_core/src/lib.rs index 398facc2c..8ceb948ea 100644 --- a/tox_core/src/lib.rs +++ b/tox_core/src/lib.rs @@ -5,7 +5,7 @@ Repo: https://github.com/tox-rs/tox */ -#![type_length_limit="2097152"] +#![type_length_limit = "2097152"] #![forbid(unsafe_code)] #![doc(html_logo_url = "https://raw.githubusercontent.com/tox-rs/logo/master/logo.png")] // Remove it when it will be fixed in nom parser @@ -16,14 +16,14 @@ extern crate log; #[macro_use] extern crate cookie_factory; -pub mod io_tokio; -pub mod time; -pub mod state_format; -pub mod relay; pub mod dht; -pub mod onion; -pub mod net_crypto; -pub mod utils; pub mod friend_connection; +pub mod io_tokio; +pub mod net_crypto; +pub mod onion; +pub mod relay; +pub mod state_format; pub mod stats; +pub mod time; pub mod udp; +pub mod utils; diff --git a/tox_core/src/net_crypto/crypto_connection.rs b/tox_core/src/net_crypto/crypto_connection.rs index e014c549a..dff5b11bf 100644 --- a/tox_core/src/net_crypto/crypto_connection.rs +++ b/tox_core/src/net_crypto/crypto_connection.rs @@ -1,18 +1,18 @@ //! Crypto connection implementation. +use crypto_box::{aead::AeadCore, SalsaBox}; +use rand::{thread_rng, Rng}; use std::convert::Into; use std::net::{SocketAddr, SocketAddrV4, SocketAddrV6}; use std::time::{Duration, Instant}; -use crypto_box::{SalsaBox, aead::AeadCore}; -use rand::{thread_rng, Rng}; use xsalsa20poly1305::XSalsa20Poly1305; use super::packets_array::*; use crate::dht::ip_port::IsGlobal; +use crate::time::*; use tox_crypto::*; use tox_packet::dht::*; -use crate::time::*; /// Interval in ms between sending cookie request/handshake packets. pub const CRYPTO_SEND_PACKET_INTERVAL_MS: u64 = 1000; @@ -85,7 +85,7 @@ pub struct StatusPacketWithTime { /// When packet was sent last time pub sent_time: Instant, /// How many times packet was sent - pub num_sent: u8 + pub num_sent: u8, } impl StatusPacketWithTime { @@ -94,7 +94,7 @@ impl StatusPacketWithTime { StatusPacketWithTime { packet: StatusPacket::CookieRequest(packet), sent_time: clock_now(), - num_sent: 0 + num_sent: 0, } } @@ -103,7 +103,7 @@ impl StatusPacketWithTime { StatusPacketWithTime { packet: StatusPacket::CryptoHandshake(packet), sent_time: clock_now(), - num_sent: 0 + num_sent: 0, } } @@ -197,7 +197,7 @@ pub struct SentPacket { pub sent_time: Instant, /// True if a request was received for this packet and rtt was elapsed at /// that moment - pub requested: bool + pub requested: bool, } impl SentPacket { @@ -206,7 +206,7 @@ impl SentPacket { SentPacket { data, sent_time: clock_now(), - requested: false + requested: false, } } } @@ -215,15 +215,13 @@ impl SentPacket { #[derive(Clone, Debug, Eq, PartialEq)] pub struct RecvPacket { /// Packet data - pub data: Vec + pub data: Vec, } impl RecvPacket { /// Create new `RecvPacket` pub fn new(data: Vec) -> RecvPacket { - RecvPacket { - data - } + RecvPacket { data } } } @@ -292,7 +290,6 @@ pub struct CryptoConnection { pub request_packet_sent_time: Option, // Stats for congestion control - /// Time since the last stats calculation. pub stats_calculation_time: Instant, /// Number of received lossless packets since the last rate calculation. @@ -323,7 +320,13 @@ pub struct CryptoConnection { impl CryptoConnection { /// Create new `CryptoConnection` with `CookieRequesting` status. This /// function is used when we initiate crypto connection with a friend. - pub fn new(dht_precomputed_key: &SalsaBox, dht_pk: PublicKey, real_pk: PublicKey, peer_real_pk: PublicKey, peer_dht_pk: PublicKey) -> CryptoConnection { + pub fn new( + dht_precomputed_key: &SalsaBox, + dht_pk: PublicKey, + real_pk: PublicKey, + peer_real_pk: PublicKey, + peer_dht_pk: PublicKey, + ) -> CryptoConnection { let mut rng = thread_rng(); let session_sk = SecretKey::generate(&mut rng); let session_pk = session_sk.public_key(); @@ -331,12 +334,12 @@ impl CryptoConnection { let cookie_request_id = rng.gen(); let cookie_request_payload = CookieRequestPayload { pk: real_pk, - id: cookie_request_id + id: cookie_request_id, }; let cookie_request = CookieRequest::new(dht_precomputed_key, dht_pk, &cookie_request_payload); let status = ConnectionStatus::CookieRequesting { cookie_request_id, - packet: StatusPacketWithTime::new_cookie_request(cookie_request) + packet: StatusPacketWithTime::new_cookie_request(cookie_request), }; CryptoConnection { @@ -397,7 +400,7 @@ impl CryptoConnection { sent_nonce: sent_nonce.into(), received_nonce, session_precomputed_key: SalsaBox::new(&peer_session_pk, &session_sk), - packet: StatusPacketWithTime::new_crypto_handshake(handshake) + packet: StatusPacketWithTime::new_crypto_handshake(handshake), }; CryptoConnection { @@ -442,7 +445,7 @@ impl CryptoConnection { } else { None } - }, + } ConnectionStatus::Established { .. } => None, } } @@ -520,8 +523,8 @@ impl CryptoConnection { /// Check if we received the last UDP packet not later than 8 seconds ago pub fn is_udp_alive(&self) -> bool { - self.udp_addr_v4.as_ref().map_or(false, |addr| addr.is_alive()) || - self.udp_addr_v6.as_ref().map_or(false, |addr| addr.is_alive()) + self.udp_addr_v4.as_ref().map_or(false, |addr| addr.is_alive()) + || self.udp_addr_v6.as_ref().map_or(false, |addr| addr.is_alive()) } /// Check if we should send UDP packet regardless of whether UDP is dead or @@ -535,7 +538,8 @@ impl CryptoConnection { /// Calculate packets receive rate. fn calculate_recv_rate(&mut self, now: Instant) { let dt = now - self.stats_calculation_time; - self.packet_recv_rate = f64::from(self.packets_received) / (dt.as_secs() as f64 + f64::from(dt.subsec_millis()) / 1000.0); + self.packet_recv_rate = + f64::from(self.packets_received) / (dt.as_secs() as f64 + f64::from(dt.subsec_millis()) / 1000.0); } /// Calculate packets send rate. @@ -560,9 +564,8 @@ impl CryptoConnection { // Based on rtt offset in number of positions for last_num_packets arrays (one position equals 50 ms) let delay = (( - self.rtt.as_secs() * 1000 + - u64::from(self.rtt.subsec_millis()) + - PACKET_COUNTER_AVERAGE_INTERVAL_MS / 2 // add half of the interval to make delay rounded + self.rtt.as_secs() * 1000 + u64::from(self.rtt.subsec_millis()) + PACKET_COUNTER_AVERAGE_INTERVAL_MS / 2 + // add half of the interval to make delay rounded ) / PACKET_COUNTER_AVERAGE_INTERVAL_MS) as usize; let delay = delay.min(CONGESTION_MAX_DELAY); @@ -571,7 +574,7 @@ impl CryptoConnection { // ...++++++++++++..x...... let mut total_sent = 0; let mut total_resent = 0; - for i in 0 .. CONGESTION_QUEUE_ARRAY_SIZE { + for i in 0..CONGESTION_QUEUE_ARRAY_SIZE { let i = (n_p_pos + (CONGESTION_MAX_DELAY - delay) + i) % CONGESTION_LAST_SENT_ARRAY_SIZE; total_sent += self.last_num_packets_sent[i] as i32; total_resent += self.last_num_packets_resent[i] as i32; @@ -596,17 +599,21 @@ impl CryptoConnection { let send_array_time = f64::from(send_array_len) / min_speed; // And, finally, estimated packets send rate - let packet_send_rate = if send_array_time > SEND_QUEUE_CLEARANCE_TIME && send_array_len > CRYPTO_MIN_QUEUE_LENGTH { - // It will take more than SEND_QUEUE_CLEARANCE_TIME seconds to send - // all packets from send queue. Reduce packets send rate in this case - min_speed / (send_array_time / SEND_QUEUE_CLEARANCE_TIME) - } else if self.last_congestion_event.map_or(true, |time| (now - time) > CONGESTION_EVENT_TIMEOUT) { - // Congestion event happened long ago so increase packets send rate - min_speed * 1.2 - } else { - // Congestion event happened recently so decrease packets send rate - min_speed * 0.9 - }; + let packet_send_rate = + if send_array_time > SEND_QUEUE_CLEARANCE_TIME && send_array_len > CRYPTO_MIN_QUEUE_LENGTH { + // It will take more than SEND_QUEUE_CLEARANCE_TIME seconds to send + // all packets from send queue. Reduce packets send rate in this case + min_speed / (send_array_time / SEND_QUEUE_CLEARANCE_TIME) + } else if self + .last_congestion_event + .map_or(true, |time| (now - time) > CONGESTION_EVENT_TIMEOUT) + { + // Congestion event happened long ago so increase packets send rate + min_speed * 1.2 + } else { + // Congestion event happened recently so decrease packets send rate + min_speed * 0.9 + }; let packet_send_rate = packet_send_rate.max(CRYPTO_PACKET_MIN_RATE); let packet_send_rate_requested = min_speed_request * 1.2; let packet_send_rate_requested = packet_send_rate_requested.max(packet_send_rate); @@ -633,9 +640,11 @@ impl CryptoConnection { /// Calculate the interval in ms for request packet. pub fn request_packet_interval(&self) -> Duration { - let request_packet_interval = REQUEST_PACKETS_COMPARE_CONSTANT / ((f64::from(self.recv_array.len()) + 1.0) / (self.packet_recv_rate + 1.0)); + let request_packet_interval = REQUEST_PACKETS_COMPARE_CONSTANT + / ((f64::from(self.recv_array.len()) + 1.0) / (self.packet_recv_rate + 1.0)); let request_packet_interval = request_packet_interval.min( - CRYPTO_PACKET_MIN_RATE / self.packet_recv_rate * CRYPTO_SEND_PACKET_INTERVAL_MS as f64 + PACKET_COUNTER_AVERAGE_INTERVAL_MS as f64 + CRYPTO_PACKET_MIN_RATE / self.packet_recv_rate * CRYPTO_SEND_PACKET_INTERVAL_MS as f64 + + PACKET_COUNTER_AVERAGE_INTERVAL_MS as f64, ); let request_packet_interval = (request_packet_interval.round() as u64) .max(PACKET_COUNTER_AVERAGE_INTERVAL_MS) // lower bound @@ -657,7 +666,10 @@ impl CryptoConnection { #[cfg(test)] mod tests { use super::*; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; #[tokio::test] async fn status_packet_should_be_sent() { @@ -666,7 +678,7 @@ mod tests { let mut packet = StatusPacketWithTime::new_cookie_request(CookieRequest { pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 88] + payload: vec![42; 88], }); assert!(packet.should_be_sent()); @@ -695,7 +707,7 @@ mod tests { let mut packet = StatusPacketWithTime::new_cookie_request(CookieRequest { pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 88] + payload: vec![42; 88], }); assert!(!packet.is_timed_out()); @@ -802,7 +814,10 @@ mod tests { connection.status = ConnectionStatus::Established { sent_nonce: [42; ::NonceSize::USIZE], received_nonce: [42; ::NonceSize::USIZE], - session_precomputed_key: SalsaBox::new(&SecretKey::generate(&mut rng).public_key(), &SecretKey::generate(&mut rng)), + session_precomputed_key: SalsaBox::new( + &SecretKey::generate(&mut rng).public_key(), + &SecretKey::generate(&mut rng), + ), }; assert!(!connection.is_not_confirmed()); @@ -823,16 +838,19 @@ mod tests { let crypto_handshake = CryptoHandshake { cookie: EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; 88] + payload: vec![42; 88], }, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 248] + payload: vec![42; 248], }; connection.status = ConnectionStatus::NotConfirmed { sent_nonce: [42; ::NonceSize::USIZE], received_nonce: [42; ::NonceSize::USIZE], - session_precomputed_key: SalsaBox::new(&SecretKey::generate(&mut rng).public_key(), &SecretKey::generate(&mut rng)), + session_precomputed_key: SalsaBox::new( + &SecretKey::generate(&mut rng).public_key(), + &SecretKey::generate(&mut rng), + ), packet: StatusPacketWithTime::new_crypto_handshake(crypto_handshake), }; diff --git a/tox_core/src/net_crypto/errors.rs b/tox_core/src/net_crypto/errors.rs index 444ef44a1..d6e19aec8 100644 --- a/tox_core/src/net_crypto/errors.rs +++ b/tox_core/src/net_crypto/errors.rs @@ -142,28 +142,19 @@ pub enum HandlePacketError { impl HandlePacketError { pub(crate) fn invalid_request_id(expect: u64, got: u64) -> HandlePacketError { - HandlePacketError::InvalidRequestId { - expect, - got, - } + HandlePacketError::InvalidRequestId { expect, got } } pub(crate) fn no_udp_connection(addr: SocketAddr) -> HandlePacketError { - HandlePacketError::NoUdpConnection { - addr, - } + HandlePacketError::NoUdpConnection { addr } } pub(crate) fn no_tcp_connection(pk: PublicKey) -> HandlePacketError { - HandlePacketError::NoTcpConnection { - pk, - } + HandlePacketError::NoTcpConnection { pk } } pub(crate) fn packet_id(id: u8) -> HandlePacketError { - HandlePacketError::PacketId { - id, - } + HandlePacketError::PacketId { id } } } diff --git a/tox_core/src/net_crypto/mod.rs b/tox_core/src/net_crypto/mod.rs index 5420b0bdf..25d93ff4b 100644 --- a/tox_core/src/net_crypto/mod.rs +++ b/tox_core/src/net_crypto/mod.rs @@ -11,34 +11,34 @@ TCP relays. */ mod crypto_connection; -mod packets_array; pub mod errors; +mod packets_array; pub use self::crypto_connection::*; -use self::packets_array::*; use self::errors::*; +use self::packets_array::*; use std::collections::{HashMap, HashSet}; -use std::net::{SocketAddr, IpAddr}; +use std::net::{IpAddr, SocketAddr}; use std::sync::Arc; use std::time::{Duration, Instant}; use std::u16; -use crypto_box::{SalsaBox, aead::AeadCore}; -use futures::{TryFutureExt, SinkExt}; -use futures::future; +use crypto_box::{aead::AeadCore, SalsaBox}; use futures::channel::mpsc; +use futures::future; +use futures::{SinkExt, TryFutureExt}; use rand::thread_rng; use tokio::sync::RwLock; +use crate::dht::precomputed_cache::*; +use crate::io_tokio::*; +use crate::time::*; use tox_binary_io::*; use tox_crypto::*; use tox_packet::dht::{Packet as DhtPacket, *}; -use xsalsa20poly1305::{XSalsa20Poly1305, KeyInit}; -use crate::dht::precomputed_cache::*; -use crate::io_tokio::*; use tox_packet::relay::DataPayload as TcpDataPayload; -use crate::time::*; +use xsalsa20poly1305::{KeyInit, XSalsa20Poly1305}; /// Maximum size of `Packet` when we try to send it to UDP address even if /// it's considered dead. @@ -257,7 +257,7 @@ impl NetCrypto { self.dht_pk.clone(), self.real_pk.clone(), peer_real_pk.clone(), - peer_dht_pk + peer_dht_pk, ); let connection = Arc::new(RwLock::new(connection)); connections.insert(peer_real_pk, connection); @@ -291,7 +291,8 @@ impl NetCrypto { async fn send_kill_packet(&self, connection: &mut CryptoConnection) -> Result<(), SendDataError> { if connection.is_established() || connection.is_not_confirmed() { let packet_number = connection.send_array.buffer_end; - self.send_data_packet(connection, vec![PACKET_ID_KILL], packet_number).await + self.send_data_packet(connection, vec![PACKET_ID_KILL], packet_number) + .await } else { Ok(()) } @@ -304,9 +305,11 @@ impl NetCrypto { let mut connection = connection.write().await; self.clear_keys_by_addr(&connection).await; - self.send_connection_status(&connection, false).await + self.send_connection_status(&connection, false) + .await .map_err(KillConnectionError::SendToConnectionStatus)?; - self.send_kill_packet(&mut connection).await + self.send_kill_packet(&mut connection) + .await .map_err(KillConnectionError::SendTo) } else { Err(KillConnectionError::NoConnection) @@ -319,11 +322,11 @@ impl NetCrypto { let mut connection = if let Some(connection) = connections.get(&real_pk) { connection.write().await } else { - return + return; }; if connection.get_udp_addr_v4() == Some(saddr) || connection.get_udp_addr_v6() == Some(saddr) { - return + return; } let mut keys_by_addr = self.keys_by_addr.write().await; @@ -341,7 +344,9 @@ impl NetCrypto { /// Send lossless packet to a friend via established connection. pub async fn send_lossless(&self, real_pk: PublicKey, packet: Vec) -> Result<(), SendLosslessPacketError> { - if packet.first().map_or(true, |&packet_id| packet_id <= PACKET_ID_CRYPTO_RANGE_END || packet_id >= PACKET_ID_LOSSY_RANGE_START) { + if packet.first().map_or(true, |&packet_id| { + packet_id <= PACKET_ID_CRYPTO_RANGE_END || packet_id >= PACKET_ID_LOSSY_RANGE_START + }) { return Err(SendLosslessPacketError::InvalidPacketId); } @@ -352,7 +357,8 @@ impl NetCrypto { Err(SendLosslessPacketError::FullSendArray(e)) } else { connection.packets_sent += 1; - self.send_data_packet(&mut connection, packet, packet_number).await + self.send_data_packet(&mut connection, packet, packet_number) + .await .map_err(SendLosslessPacketError::SendTo) } } else { @@ -397,7 +403,8 @@ impl NetCrypto { /// Create `CookieResponse` packet with `Cookie` requested by `CookieRequest` packet async fn handle_cookie_request(&self, packet: &CookieRequest) -> Result { - let payload = packet.get_payload(&self.precomputed_keys.get(packet.pk.clone()).await) + let payload = packet + .get_payload(&self.precomputed_keys.get(packet.pk.clone()).await) .map_err(HandlePacketError::GetPayload)?; let cookie = Cookie::new(payload.pk, packet.pk.clone()); @@ -414,20 +421,31 @@ impl NetCrypto { } /// Handle `CookieRequest` packet received from UDP socket - pub async fn handle_udp_cookie_request(&self, packet: &CookieRequest, addr: SocketAddr) -> Result<(), HandlePacketError> { + pub async fn handle_udp_cookie_request( + &self, + packet: &CookieRequest, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { match self.handle_cookie_request(packet).await { - Ok(response) => self.send_to_udp(addr, DhtPacket::CookieResponse(response)).await + Ok(response) => self + .send_to_udp(addr, DhtPacket::CookieResponse(response)) + .await .map_err(|e| HandlePacketError::SendTo(SendPacketError::Udp(e))), Err(e) => Err(e), } } /// Handle `CookieRequest` packet received from TCP socket - pub async fn handle_tcp_cookie_request(&self, packet: &CookieRequest, sender_pk: PublicKey) -> Result<(), HandlePacketError> { + pub async fn handle_tcp_cookie_request( + &self, + packet: &CookieRequest, + sender_pk: PublicKey, + ) -> Result<(), HandlePacketError> { match self.handle_cookie_request(packet).await { Ok(response) => { let msg = (TcpDataPayload::CookieResponse(response), sender_pk); - maybe_send_bounded(self.tcp_tx.read().await.clone(), msg).await + maybe_send_bounded(self.tcp_tx.read().await.clone(), msg) + .await .map_err(|e| HandlePacketError::SendTo(SendPacketError::Tcp(e))) } Err(e) => Err(e), @@ -435,12 +453,16 @@ impl NetCrypto { } /// Handle `CookieResponse` and if it's correct change connection status to `HandshakeSending`. - pub async fn handle_cookie_response(&self, connection: &mut CryptoConnection, packet: &CookieResponse) - -> Result<(), HandlePacketError> { - let cookie_request_id = if let ConnectionStatus::CookieRequesting { cookie_request_id, .. } = connection.status { + pub async fn handle_cookie_response( + &self, + connection: &mut CryptoConnection, + packet: &CookieResponse, + ) -> Result<(), HandlePacketError> { + let cookie_request_id = if let ConnectionStatus::CookieRequesting { cookie_request_id, .. } = connection.status + { cookie_request_id } else { - return Err(HandlePacketError::InvalidState) + return Err(HandlePacketError::InvalidState); }; let payload = match packet.get_payload(&self.precomputed_keys.get(connection.peer_dht_pk.clone()).await) { @@ -449,7 +471,7 @@ impl NetCrypto { }; if payload.id != cookie_request_id { - return Err(HandlePacketError::invalid_request_id(cookie_request_id, payload.id)) + return Err(HandlePacketError::invalid_request_id(cookie_request_id, payload.id)); } let mut rng = rand::thread_rng(); @@ -462,20 +484,28 @@ impl NetCrypto { cookie_hash: payload.cookie.hash(), cookie: our_encrypted_cookie, }; - let handshake = CryptoHandshake::new(&SalsaBox::new(&connection.peer_real_pk, &self.real_sk), &handshake_payload, payload.cookie); + let handshake = CryptoHandshake::new( + &SalsaBox::new(&connection.peer_real_pk, &self.real_sk), + &handshake_payload, + payload.cookie, + ); connection.status = ConnectionStatus::HandshakeSending { sent_nonce: sent_nonce.into(), - packet: StatusPacketWithTime::new_crypto_handshake(handshake) + packet: StatusPacketWithTime::new_crypto_handshake(handshake), }; self.send_status_packet(connection) - .map_err(HandlePacketError::SendTo).await + .map_err(HandlePacketError::SendTo) + .await } /// Handle `CookieResponse` packet received from UDP socket - pub async fn handle_udp_cookie_response(&self, packet: &CookieResponse, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_udp_cookie_response( + &self, + packet: &CookieResponse, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { if let Some(connection) = self.connection_by_addr(addr).await { let mut connection = connection.write().await; connection.set_udp_addr(addr); @@ -486,8 +516,11 @@ impl NetCrypto { } /// Handle `CookieResponse` packet received from TCP socket - pub async fn handle_tcp_cookie_response(&self, packet: &CookieResponse, sender_pk: PublicKey) - -> Result<(), HandlePacketError> { + pub async fn handle_tcp_cookie_response( + &self, + packet: &CookieResponse, + sender_pk: PublicKey, + ) -> Result<(), HandlePacketError> { let connection = self.connection_by_dht_key(sender_pk.clone()).await; if let Some(connection) = connection { let mut connection = connection.write().await; @@ -500,8 +533,10 @@ impl NetCrypto { /// Check that incoming `CryptoHandshake` request is valid: /// - cookie is not timed out /// - hash for the cookie inside the payload is correct - fn validate_crypto_handshake(&self, packet: &CryptoHandshake) - -> Result<(Cookie, CryptoHandshakePayload, SalsaBox), HandlePacketError> { + fn validate_crypto_handshake( + &self, + packet: &CryptoHandshake, + ) -> Result<(Cookie, CryptoHandshakePayload, SalsaBox), HandlePacketError> { let cookie = match packet.cookie.get_payload(&self.symmetric_key) { Ok(cookie) => cookie, Err(e) => return Err(HandlePacketError::GetPayload(e)), @@ -526,10 +561,13 @@ impl NetCrypto { } /// Handle `CryptoHandshake` and if it's correct change connection status to `NotConfirmed`. - pub async fn handle_crypto_handshake(&self, connection: &mut CryptoConnection, packet: &CryptoHandshake) - -> Result<(), HandlePacketError> { + pub async fn handle_crypto_handshake( + &self, + connection: &mut CryptoConnection, + packet: &CryptoHandshake, + ) -> Result<(), HandlePacketError> { if let ConnectionStatus::Established { .. } = connection.status { - return Err(HandlePacketError::InvalidState) + return Err(HandlePacketError::InvalidState); } let (cookie, payload, real_precomputed_key) = match self.validate_crypto_handshake(packet) { @@ -538,15 +576,17 @@ impl NetCrypto { }; if cookie.real_pk != connection.peer_real_pk { - return Err(HandlePacketError::InvalidRealPk) + return Err(HandlePacketError::InvalidRealPk); } if cookie.dht_pk != connection.peer_dht_pk { let msg = (connection.peer_real_pk.clone(), cookie.dht_pk); - let dht_pk_future = maybe_send_unbounded(self.dht_pk_tx.read().await.clone(), msg) - .map_err(HandlePacketError::SendToDhtpk); + let dht_pk_future = + maybe_send_unbounded(self.dht_pk_tx.read().await.clone(), msg).map_err(HandlePacketError::SendToDhtpk); - return dht_pk_future.and_then(|()| future::err(HandlePacketError::InvalidDhtPk)).await + return dht_pk_future + .and_then(|()| future::err(HandlePacketError::InvalidDhtPk)) + .await; } connection.status = match connection.status { @@ -566,27 +606,35 @@ impl NetCrypto { sent_nonce: sent_nonce.into(), received_nonce: payload.base_nonce, session_precomputed_key: SalsaBox::new(&payload.session_pk, &connection.session_sk), - packet: StatusPacketWithTime::new_crypto_handshake(handshake) + packet: StatusPacketWithTime::new_crypto_handshake(handshake), } - }, - ConnectionStatus::HandshakeSending { sent_nonce, ref packet, .. } - | ConnectionStatus::NotConfirmed { sent_nonce, ref packet, .. } => ConnectionStatus::NotConfirmed { + } + ConnectionStatus::HandshakeSending { + sent_nonce, ref packet, .. + } + | ConnectionStatus::NotConfirmed { + sent_nonce, ref packet, .. + } => ConnectionStatus::NotConfirmed { sent_nonce, received_nonce: payload.base_nonce, session_precomputed_key: SalsaBox::new(&payload.session_pk, &connection.session_sk), - packet: packet.clone() + packet: packet.clone(), }, ConnectionStatus::Established { .. } => unreachable!("Checked for Established status above"), }; - self.send_status_packet(connection).await + self.send_status_packet(connection) + .await .map_err(HandlePacketError::SendTo) } /// Handle incoming `CryptoHandshake` in case when we don't have associated /// with sender connection. - async fn handle_crypto_handshake_new_connection(&self, packet: &CryptoHandshake, addr: Option) - -> Result<(), HandlePacketError> { + async fn handle_crypto_handshake_new_connection( + &self, + packet: &CryptoHandshake, + addr: Option, + ) -> Result<(), HandlePacketError> { let (cookie, payload, _real_precomputed_key) = match self.validate_crypto_handshake(packet) { Ok(result) => result, Err(e) => return Err(e), @@ -607,9 +655,11 @@ impl NetCrypto { // a new one. self.clear_keys_by_addr(&connection).await; - self.send_connection_status(&connection, false).await + self.send_connection_status(&connection, false) + .await .map_err(HandlePacketError::SendToConnectionStatus)?; - self.send_kill_packet(&mut connection).await + self.send_kill_packet(&mut connection) + .await .map_err(HandlePacketError::SendDataTo)?; } else { // We received a handshake packet for an existent connection @@ -637,19 +687,26 @@ impl NetCrypto { ); if let Some(addr) = addr { connection.set_udp_addr(addr); - self.keys_by_addr.write().await.insert((addr.ip(), addr.port()), cookie.real_pk.clone()); + self.keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), cookie.real_pk.clone()); } let connection = Arc::new(RwLock::new(connection)); connections.insert(cookie.real_pk.clone(), connection); let msg = (cookie.real_pk, cookie.dht_pk); - maybe_send_unbounded(self.dht_pk_tx.read().await.clone(), msg).await + maybe_send_unbounded(self.dht_pk_tx.read().await.clone(), msg) + .await .map_err(HandlePacketError::SendToDhtpk) } /// Handle `CryptoHandshake` packet received from UDP socket - pub async fn handle_udp_crypto_handshake(&self, packet: &CryptoHandshake, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_udp_crypto_handshake( + &self, + packet: &CryptoHandshake, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { if let Some(connection) = self.connection_by_addr(addr).await { let mut connection = connection.write().await; connection.set_udp_addr(addr); @@ -660,8 +717,11 @@ impl NetCrypto { } /// Handle `CryptoHandshake` packet received from TCP socket - pub async fn handle_tcp_crypto_handshake(&self, packet: &CryptoHandshake, sender_pk: PublicKey) - -> Result<(), HandlePacketError> { + pub async fn handle_tcp_crypto_handshake( + &self, + packet: &CryptoHandshake, + sender_pk: PublicKey, + ) -> Result<(), HandlePacketError> { let connection = self.connection_by_dht_key(sender_pk).await; if let Some(connection) = connection { let mut connection = connection.write().await; @@ -680,27 +740,35 @@ impl NetCrypto { means that packets 2, 5 and 1023 were requested (if the first index is 0). */ - fn handle_request_packet(send_array: &mut PacketsArray, mut data: &[u8], rtt: Duration, last_sent_time: &mut Option) { + fn handle_request_packet( + send_array: &mut PacketsArray, + mut data: &[u8], + rtt: Duration, + last_sent_time: &mut Option, + ) { // n is a packet number corresponding to numbers from the request let mut n = 1; // Cycle over sent packets to mark them requested or to delete them if // they are not requested which means they are delivered - for i in send_array.buffer_start .. send_array.buffer_end { + for i in send_array.buffer_start..send_array.buffer_end { // Stop if there is no more request numbers to handle if data.is_empty() { - break + break; } - if n == data[0] { // packet is requested + if n == data[0] { + // packet is requested if let Some(packet) = send_array.get_mut(i) { - if clock_elapsed(packet.sent_time) > rtt { // mark it if it wasn't delivered in time + if clock_elapsed(packet.sent_time) > rtt { + // mark it if it wasn't delivered in time packet.requested = true; } } n = 0; data = &data[1..]; - } else if let Some(packet) = send_array.remove(i) { // packet is not requested, delete it + } else if let Some(packet) = send_array.remove(i) { + // packet is not requested, delete it if last_sent_time.map(|time| time < packet.sent_time).unwrap_or(true) { *last_sent_time = Some(packet.sent_time); } @@ -729,7 +797,7 @@ impl NetCrypto { let mut n = 1; // go through all received packets and put numbers of missing packets to the request - for i in recv_array.buffer_start .. recv_array.buffer_end { + for i in recv_array.buffer_start..recv_array.buffer_end { if !recv_array.contains(i) { data.push(n); n = 0; @@ -750,8 +818,11 @@ impl NetCrypto { /// Send received lossless packets from the beginning of the receiving /// buffer to lossless sink and delete them - async fn process_ready_lossless_packets(&self, recv_array: &mut PacketsArray, pk: PublicKey) - -> Result<(), mpsc::SendError> { + async fn process_ready_lossless_packets( + &self, + recv_array: &mut PacketsArray, + pk: PublicKey, + ) -> Result<(), mpsc::SendError> { let mut tx = self.lossless_tx.clone(); while let Some(packet) = recv_array.pop_front() { @@ -765,7 +836,7 @@ impl NetCrypto { /// used to update rtt fn last_sent_time(send_array: &PacketsArray, index: u32) -> Option { let mut last_sent_time = None; - for i in send_array.buffer_start .. index { + for i in send_array.buffer_start..index { if let Some(packet) = send_array.get(i) { if last_sent_time.map(|time| time < packet.sent_time).unwrap_or(true) { last_sent_time = Some(packet.sent_time); @@ -789,31 +860,26 @@ impl NetCrypto { packets from the beginning of this buffer - lossy type: just process the packet */ - async fn handle_crypto_data(&self, + async fn handle_crypto_data( + &self, connection: &mut CryptoConnection, packet: &CryptoData, - udp: bool + udp: bool, ) -> Result<(), HandlePacketError> { - let (sent_nonce, mut received_nonce, session_precomputed_key) = - match connection.status { - ConnectionStatus::NotConfirmed { - sent_nonce, - received_nonce, - ref session_precomputed_key, - .. - } - | ConnectionStatus::Established { - sent_nonce, - received_nonce, - ref session_precomputed_key - } => { - (sent_nonce, received_nonce, session_precomputed_key.clone()) - }, - _ => { - return Err(HandlePacketError::CannotHandleCryptoData) - - } - }; + let (sent_nonce, mut received_nonce, session_precomputed_key) = match connection.status { + ConnectionStatus::NotConfirmed { + sent_nonce, + received_nonce, + ref session_precomputed_key, + .. + } + | ConnectionStatus::Established { + sent_nonce, + received_nonce, + ref session_precomputed_key, + } => (sent_nonce, received_nonce, session_precomputed_key.clone()), + _ => return Err(HandlePacketError::CannotHandleCryptoData), + }; let cur_last_bytes = CryptoData::nonce_last_bytes(received_nonce); let (diff, _) = packet.nonce_last_bytes.overflowing_sub(cur_last_bytes); @@ -822,32 +888,31 @@ impl NetCrypto { let payload = match packet.get_payload(&session_precomputed_key, &packet_nonce) { Ok(payload) => payload, - Err(e) => return Err(HandlePacketError::GetPayload(e)) + Err(e) => return Err(HandlePacketError::GetPayload(e)), }; // Find the time when the last acknowledged packet was sent - let mut last_sent_time = NetCrypto::last_sent_time( - &connection.send_array, - payload.buffer_start - ); + let mut last_sent_time = NetCrypto::last_sent_time(&connection.send_array, payload.buffer_start); // Remove all acknowledged packets and set new start index to the send buffer if let Err(e) = connection.send_array.set_buffer_start(payload.buffer_start) { - return Err(HandlePacketError::PacketsArrayError(e)) + return Err(HandlePacketError::PacketsArrayError(e)); } // And get the ID of the packet let packet_id = match payload.data.first() { Some(&packet_id) => packet_id, - None => return Err(HandlePacketError::DataEmpty) + None => return Err(HandlePacketError::DataEmpty), }; if packet_id == PACKET_ID_KILL { // Kill the connection self.connections.write().await.remove(&connection.peer_real_pk); self.clear_keys_by_addr(connection).await; - return self.send_connection_status(connection, false) - .map_err(HandlePacketError::SendToConnectionStatus).await; + return self + .send_connection_status(connection, false) + .map_err(HandlePacketError::SendToConnectionStatus) + .await; } // Update nonce if diff is big enough @@ -855,32 +920,33 @@ impl NetCrypto { increment_nonce_number(&mut received_nonce, NONCE_DIFF_THRESHOLD); } - self.send_connection_status(connection, true).await + self.send_connection_status(connection, true) + .await .map_err(HandlePacketError::SendToConnectionStatus)?; connection.status = ConnectionStatus::Established { sent_nonce, received_nonce, - session_precomputed_key + session_precomputed_key, }; if packet_id == PACKET_ID_REQUEST { // Use const RTT in case of TCP connection let rtt = if udp { connection.rtt } else { TCP_RTT }; - NetCrypto::handle_request_packet( - &mut connection.send_array, - &payload.data[1..], - rtt, &mut last_sent_time - ); + NetCrypto::handle_request_packet(&mut connection.send_array, &payload.data[1..], rtt, &mut last_sent_time); // Update end index of received buffer ignoring the error - we still // want to handle this packet even if connection is too slow connection.recv_array.set_buffer_end(payload.packet_number).ok(); } else if packet_id > PACKET_ID_CRYPTO_RANGE_END && packet_id < PACKET_ID_LOSSY_RANGE_START { - if let Err(e) = connection.recv_array.insert(payload.packet_number, RecvPacket::new(payload.data)) { - return Err(HandlePacketError::PacketsArrayError(e)) + if let Err(e) = connection + .recv_array + .insert(payload.packet_number, RecvPacket::new(payload.data)) + { + return Err(HandlePacketError::PacketsArrayError(e)); } connection.packets_received += 1; - self.process_ready_lossless_packets(&mut connection.recv_array, connection.peer_real_pk.clone()).await + self.process_ready_lossless_packets(&mut connection.recv_array, connection.peer_real_pk.clone()) + .await .map_err(HandlePacketError::SendToLossless)?; } else if (PACKET_ID_LOSSY_RANGE_START..=PACKET_ID_LOSSY_RANGE_END).contains(&packet_id) { // Update end index of received buffer ignoring the error - we still @@ -890,10 +956,11 @@ impl NetCrypto { let peer_real_pk = connection.peer_real_pk.clone(); let data = payload.data.clone(); - tx.send((peer_real_pk, data)).await + tx.send((peer_real_pk, data)) + .await .map_err(HandlePacketError::SendToLossy)?; } else { - return Err(HandlePacketError::packet_id(packet_id)) + return Err(HandlePacketError::packet_id(packet_id)); }; // TODO: update rtt only when udp is true? @@ -920,7 +987,11 @@ impl NetCrypto { } /// Handle `CryptoData` packet received from TCP socket - pub async fn handle_tcp_crypto_data(&self, packet: &CryptoData, sender_pk: PublicKey) -> Result<(), HandlePacketError> { + pub async fn handle_tcp_crypto_data( + &self, + packet: &CryptoData, + sender_pk: PublicKey, + ) -> Result<(), HandlePacketError> { if let Some(connection) = self.connection_by_dht_key(sender_pk.clone()).await { let mut connection = connection.write().await; self.handle_crypto_data(&mut connection, packet, /* udp */ false).await @@ -936,8 +1007,10 @@ impl NetCrypto { // priority queue and just send packets there if let Some(addr) = connection.get_udp_addr() { if connection.is_udp_alive() { - return self.send_to_udp(addr, packet.into()).await - .map_err(SendPacketError::Udp) + return self + .send_to_udp(addr, packet.into()) + .await + .map_err(SendPacketError::Udp); } let dht_packet: DhtPacket = packet.clone().into(); @@ -949,13 +1022,13 @@ impl NetCrypto { if udp_attempt_should_be_made { connection.update_udp_send_attempt_time(); - self.send_to_udp(addr, dht_packet).await - .map_err(SendPacketError::Udp)?; + self.send_to_udp(addr, dht_packet).await.map_err(SendPacketError::Udp)?; } }; let tcp_tx = self.tcp_tx.read().await.clone(); - maybe_send_bounded(tcp_tx, (packet.into(), connection.peer_dht_pk.clone())).await + maybe_send_bounded(tcp_tx, (packet.into(), connection.peer_dht_pk.clone())) + .await .map_err(SendPacketError::Tcp) } @@ -969,11 +1042,23 @@ impl NetCrypto { } /// Send `CryptoData` packet if the connection is established. - async fn send_data_packet(&self, connection: &mut CryptoConnection, data: Vec, packet_number: u32) - -> Result<(), SendDataError> { + async fn send_data_packet( + &self, + connection: &mut CryptoConnection, + data: Vec, + packet_number: u32, + ) -> Result<(), SendDataError> { let packet = match connection.status { - ConnectionStatus::NotConfirmed { ref mut sent_nonce, ref session_precomputed_key, .. } - | ConnectionStatus::Established { ref mut sent_nonce, ref session_precomputed_key, .. } => { + ConnectionStatus::NotConfirmed { + ref mut sent_nonce, + ref session_precomputed_key, + .. + } + | ConnectionStatus::Established { + ref mut sent_nonce, + ref session_precomputed_key, + .. + } => { let payload = CryptoDataPayload { buffer_start: connection.recv_array.buffer_start, packet_number, @@ -982,10 +1067,11 @@ impl NetCrypto { let packet = CryptoData::new(session_precomputed_key, *sent_nonce, &payload); increment_nonce(sent_nonce); packet - }, + } _ => return Err(SendDataError::NoConnection), }; - self.send_packet(Packet::CryptoData(packet), connection).await + self.send_packet(Packet::CryptoData(packet), connection) + .await .map_err(SendDataError::SendTo) } @@ -1001,17 +1087,20 @@ impl NetCrypto { /// Send packets that were requested. async fn send_requested_packets(&self, connection: &mut CryptoConnection) -> Result<(), SendDataError> { let now = clock_now(); - let packets = connection.send_array.iter_mut() + let packets = connection + .send_array + .iter_mut() .filter(|(_, packet)| packet.requested) .map(|(i, packet)| { packet.requested = false; packet.sent_time = now; (i, packet.data.clone()) - }).collect::>(); + }) + .collect::>(); for (i, data) in packets { self.send_data_packet(connection, data, i).await?; - }; + } Ok(()) } @@ -1035,7 +1124,8 @@ impl NetCrypto { } if connection.is_established() { - self.send_connection_status(&connection, false).await + self.send_connection_status(&connection, false) + .await .map_err(SendDataError::SendToConnectionStatus)?; } @@ -1046,13 +1136,14 @@ impl NetCrypto { to_remove.push(pk.clone()); } - self.send_status_packet(&mut connection).await + self.send_status_packet(&mut connection) + .await .map_err(SendDataError::SendTo)?; if connection.is_not_confirmed() || connection.is_established() { - let should_send = connection.request_packet_sent_time.map_or(true, |time| - clock_elapsed(time) > CRYPTO_SEND_PACKET_INTERVAL - ); + let should_send = connection + .request_packet_sent_time + .map_or(true, |time| clock_elapsed(time) > CRYPTO_SEND_PACKET_INTERVAL); if should_send { self.send_request_packet(&mut connection).await?; } @@ -1061,9 +1152,9 @@ impl NetCrypto { if connection.is_established() { if connection.packet_recv_rate > CRYPTO_PACKET_MIN_RATE { let request_packet_interval = connection.request_packet_interval(); - let should_send = connection.request_packet_sent_time.map_or(true, |time| - clock_elapsed(time) > request_packet_interval - ); + let should_send = connection + .request_packet_sent_time + .map_or(true, |time| clock_elapsed(time) > request_packet_interval); if should_send { self.send_request_packet(&mut connection).await?; } @@ -1091,20 +1182,17 @@ impl NetCrypto { loop { wakeups.tick().await; - let fut = tokio::time::timeout( - PACKET_COUNTER_AVERAGE_INTERVAL, self.main_loop() - ); + let fut = tokio::time::timeout(PACKET_COUNTER_AVERAGE_INTERVAL, self.main_loop()); - let res = - match fut.await { - Err(e) => Err(RunError::Timeout(e)), - Ok(Err(e)) => Err(RunError::SendData(e)), - Ok(Ok(_)) => Ok(()), - }; + let res = match fut.await { + Err(e) => Err(RunError::Timeout(e)), + Ok(Err(e)) => Err(RunError::SendData(e)), + Ok(Ok(_)) => Ok(()), + }; if let Err(ref e) = res { warn!("Failed to send net crypto packets: {}", e); - return res + return res; } } } @@ -1129,10 +1217,13 @@ impl NetCrypto { #[cfg(test)] mod tests { // https://github.com/rust-lang/rust/issues/61520 - use super::{*, Packet}; + use super::{Packet, *}; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; use futures::{Future, StreamExt}; use rand::{CryptoRng, Rng}; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; impl NetCrypto { pub fn real_pk(&self) -> &PublicKey { @@ -1165,7 +1256,7 @@ mod tests { peer_real_pk: PublicKey, sent_nonce: Nonce, received_nonce: Nonce, - session_precomputed_key: SalsaBox + session_precomputed_key: SalsaBox, ) { let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &self.dht_sk); let mut connection = CryptoConnection::new( @@ -1180,10 +1271,18 @@ mod tests { received_nonce, session_precomputed_key, }; - self.connections.write().await.insert(peer_real_pk, Arc::new(RwLock::new(connection))); + self.connections + .write() + .await + .insert(peer_real_pk, Arc::new(RwLock::new(connection))); } - pub fn get_cookie(&self, rng: &mut R, real_pk: PublicKey, dht_pk: PublicKey) -> EncryptedCookie { + pub fn get_cookie( + &self, + rng: &mut R, + real_pk: PublicKey, + dht_pk: PublicKey, + ) -> EncryptedCookie { let cookie = Cookie::new(real_pk, dht_pk); EncryptedCookie::new(rng, &self.symmetric_key, &cookie) } @@ -1265,7 +1364,10 @@ mod tests { assert_eq!(cookie_response_payload.id, cookie_request_id); - let cookie = cookie_response_payload.cookie.get_payload(&net_crypto.symmetric_key).unwrap(); + let cookie = cookie_response_payload + .cookie + .get_payload(&net_crypto.symmetric_key) + .unwrap(); assert_eq!(cookie.dht_pk, peer_dht_pk); assert_eq!(cookie.real_pk, peer_real_pk); } @@ -1295,12 +1397,15 @@ mod tests { let cookie_request = CookieRequest { pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 88] + payload: vec![42; 88], }; let res = net_crypto.handle_cookie_request(&cookie_request).await; assert!(res.is_err()); - assert_eq!(res.err().unwrap(), HandlePacketError::GetPayload(GetPayloadError::Decrypt)); + assert_eq!( + res.err().unwrap(), + HandlePacketError::GetPayload(GetPayloadError::Decrypt) + ); } #[tokio::test] @@ -1338,7 +1443,10 @@ mod tests { let addr = "127.0.0.1:12345".parse().unwrap(); - net_crypto.handle_udp_cookie_request(&cookie_request, addr).await.unwrap(); + net_crypto + .handle_udp_cookie_request(&cookie_request, addr) + .await + .unwrap(); let (received, _udp_rx) = udp_rx.into_future().await; let (packet, addr_to_send) = received.unwrap(); @@ -1350,7 +1458,10 @@ mod tests { assert_eq!(cookie_response_payload.id, cookie_request_id); - let cookie = cookie_response_payload.cookie.get_payload(&net_crypto.symmetric_key).unwrap(); + let cookie = cookie_response_payload + .cookie + .get_payload(&net_crypto.symmetric_key) + .unwrap(); assert_eq!(cookie.dht_pk, peer_dht_pk); assert_eq!(cookie.real_pk, peer_real_pk); } @@ -1391,7 +1502,10 @@ mod tests { }; let cookie_request = CookieRequest::new(&precomputed_key, peer_dht_pk.clone(), &cookie_request_payload); - net_crypto.handle_tcp_cookie_request(&cookie_request, peer_dht_pk.clone()).await.unwrap(); + net_crypto + .handle_tcp_cookie_request(&cookie_request, peer_dht_pk.clone()) + .await + .unwrap(); let (received, _net_crypto_tcp_rx) = net_crypto_tcp_rx.into_future().await; let (packet, pk_to_send) = received.unwrap(); @@ -1403,7 +1517,10 @@ mod tests { assert_eq!(cookie_response_payload.id, cookie_request_id); - let cookie = cookie_response_payload.cookie.get_payload(&net_crypto.symmetric_key).unwrap(); + let cookie = cookie_response_payload + .cookie + .get_payload(&net_crypto.symmetric_key) + .unwrap(); assert_eq!(cookie.dht_pk, peer_dht_pk); assert_eq!(cookie.real_pk, peer_real_pk); } @@ -1433,14 +1550,17 @@ mod tests { let cookie_request = CookieRequest { pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 88] + payload: vec![42; 88], }; let addr = "127.0.0.1:12345".parse().unwrap(); let res = net_crypto.handle_udp_cookie_request(&cookie_request, addr).await; assert!(res.is_err()); - assert_eq!(res.err().unwrap(), HandlePacketError::GetPayload(GetPayloadError::Decrypt)); + assert_eq!( + res.err().unwrap(), + HandlePacketError::GetPayload(GetPayloadError::Decrypt) + ); } #[tokio::test] @@ -1469,21 +1589,25 @@ mod tests { let peer_real_sk = SecretKey::generate(&mut rng); let peer_real_pk = peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk, peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk, peer_dht_pk); let cookie_request_id = unpack!(connection.status, ConnectionStatus::CookieRequesting, cookie_request_id); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let cookie_response_payload = CookieResponsePayload { cookie: cookie.clone(), - id: cookie_request_id + id: cookie_request_id, }; let cookie_response = CookieResponse::new(&dht_precomputed_key, &cookie_response_payload); - net_crypto.handle_cookie_response(&mut connection, &cookie_response).await.unwrap(); + net_crypto + .handle_cookie_response(&mut connection, &cookie_response) + .await + .unwrap(); let packet = unpack!(connection.status, ConnectionStatus::HandshakeSending, packet); let packet = unpack!(packet.packet, StatusPacket::CryptoHandshake); @@ -1525,22 +1649,21 @@ mod tests { SecretKey::generate(&mut rng).public_key(), EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; 88] + payload: vec![42; 88], }, - &net_crypto.symmetric_key + &net_crypto.symmetric_key, ); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] - }; - let cookie_response_payload = CookieResponsePayload { - cookie, - id: 12345 + payload: vec![43; 88], }; + let cookie_response_payload = CookieResponsePayload { cookie, id: 12345 }; let cookie_response = CookieResponse::new(&SalsaBox::new(&peer_dht_pk, &dht_sk), &cookie_response_payload); - let res = net_crypto.handle_cookie_response(&mut connection, &cookie_response).await; + let res = net_crypto + .handle_cookie_response(&mut connection, &cookie_response) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::InvalidState); } @@ -1576,21 +1699,24 @@ mod tests { let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let cookie_response_payload = CookieResponsePayload { cookie, - id: cookie_request_id.overflowing_add(1).0 + id: cookie_request_id.overflowing_add(1).0, }; let cookie_response = CookieResponse::new(&dht_precomputed_key, &cookie_response_payload); - assert!(net_crypto.handle_cookie_response(&mut connection, &cookie_response).await.is_err()); + assert!(net_crypto + .handle_cookie_response(&mut connection, &cookie_response) + .await + .is_err()); } async fn handle_cookie_response_test<'a, R, F>(handle_function: F) where - R: Future, - F: Fn(NetCrypto, CookieResponse, SocketAddr, PublicKey) -> R + R: Future, + F: Fn(NetCrypto, CookieResponse, SocketAddr, PublicKey) -> R, { let mut rng = thread_rng(); let (udp_tx, _udp_rx) = mpsc::channel(1); @@ -1616,23 +1742,37 @@ mod tests { let peer_real_sk = SecretKey::generate(&mut rng); let peer_real_pk = peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let cookie_request_id = unpack!(connection.status, ConnectionStatus::CookieRequesting, cookie_request_id); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let cookie_response_payload = CookieResponsePayload { cookie: cookie.clone(), - id: cookie_request_id + id: cookie_request_id, }; let cookie_response = CookieResponse::new(&dht_precomputed_key, &cookie_response_payload); @@ -1651,7 +1791,12 @@ mod tests { #[tokio::test] async fn handle_udp_cookie_response() { - async fn test_me(net_crypto: NetCrypto, packet: CookieResponse, saddr: SocketAddr, _pk: PublicKey) -> NetCrypto { + async fn test_me( + net_crypto: NetCrypto, + packet: CookieResponse, + saddr: SocketAddr, + _pk: PublicKey, + ) -> NetCrypto { net_crypto.handle_udp_cookie_response(&packet, saddr).await.unwrap(); net_crypto } @@ -1661,7 +1806,12 @@ mod tests { #[tokio::test] async fn handle_tcp_cookie_response() { - async fn test_me(net_crypto: NetCrypto, packet: CookieResponse, _saddr: SocketAddr, pk: PublicKey) -> NetCrypto { + async fn test_me( + net_crypto: NetCrypto, + packet: CookieResponse, + _saddr: SocketAddr, + pk: PublicKey, + ) -> NetCrypto { net_crypto.handle_tcp_cookie_response(&packet, pk).await.unwrap(); net_crypto } @@ -1698,17 +1848,22 @@ mod tests { let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let cookie_response_payload = CookieResponsePayload { cookie: cookie.clone(), - id: 12345 + id: 12345, }; let cookie_response = CookieResponse::new(&dht_precomputed_key, &cookie_response_payload); let res = net_crypto.handle_udp_cookie_response(&cookie_response, addr).await; assert!(res.is_err()); - assert_eq!(res.err().unwrap(), HandlePacketError::NoUdpConnection { addr: "127.0.0.1:12345".parse().unwrap() }); + assert_eq!( + res.err().unwrap(), + HandlePacketError::NoUdpConnection { + addr: "127.0.0.1:12345".parse().unwrap() + } + ); } #[tokio::test] @@ -1737,7 +1892,13 @@ mod tests { let peer_real_sk = SecretKey::generate(&mut rng); let peer_real_pk = peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); let base_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -1746,17 +1907,21 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: cookie.clone() + cookie: cookie.clone(), }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); - net_crypto.handle_crypto_handshake(&mut connection, &crypto_handshake).await.unwrap(); + net_crypto + .handle_crypto_handshake(&mut connection, &crypto_handshake) + .await + .unwrap(); let received_nonce = unpack!(connection.status, ConnectionStatus::NotConfirmed, received_nonce); assert_eq!(received_nonce, base_nonce); @@ -1796,7 +1961,7 @@ mod tests { let peer_real_pk = peer_real_sk.public_key(); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; 88] + payload: vec![42; 88], }; let mut connection = CryptoConnection::new_not_confirmed( &real_sk, @@ -1805,7 +1970,7 @@ mod tests { [42; ::NonceSize::USIZE], SecretKey::generate(&mut rng).public_key(), cookie.clone(), - &net_crypto.symmetric_key + &net_crypto.symmetric_key, ); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); @@ -1815,17 +1980,21 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let other_cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: other_cookie + cookie: other_cookie, }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); - net_crypto.handle_crypto_handshake(&mut connection, &crypto_handshake).await.unwrap(); + net_crypto + .handle_crypto_handshake(&mut connection, &crypto_handshake) + .await + .unwrap(); // Nonce should be taken from the packet let received_nonce = unpack!(connection.status, ConnectionStatus::NotConfirmed, received_nonce); @@ -1865,7 +2034,13 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk, + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let peer_session_pk = SecretKey::generate(&mut rng).public_key(); let session_sk = SecretKey::generate(&mut rng); @@ -1882,17 +2057,20 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie + cookie, }; - let crypto_handshake = CryptoHandshake::new(&dht_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&dht_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); - let res = net_crypto.handle_crypto_handshake(&mut connection, &crypto_handshake).await; + let res = net_crypto + .handle_crypto_handshake(&mut connection, &crypto_handshake) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::InvalidState); } @@ -1923,7 +2101,13 @@ mod tests { let peer_real_sk = SecretKey::generate(&mut rng); let peer_real_pk = peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); let base_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -1932,17 +2116,20 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: cookie.hash(), - cookie + cookie, }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); - let res = net_crypto.handle_crypto_handshake(&mut connection, &crypto_handshake).await; + let res = net_crypto + .handle_crypto_handshake(&mut connection, &crypto_handshake) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::BadSha512); } @@ -1973,7 +2160,13 @@ mod tests { let peer_real_sk = SecretKey::generate(&mut rng); let peer_real_pk = peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); let base_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -1983,17 +2176,20 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie + cookie, }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); - let res = net_crypto.handle_crypto_handshake(&mut connection, &crypto_handshake).await; + let res = net_crypto + .handle_crypto_handshake(&mut connection, &crypto_handshake) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::CookieTimedOut); } @@ -2025,7 +2221,13 @@ mod tests { let another_peer_real_sk = SecretKey::generate(&mut rng); let another_peer_real_pk = another_peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk, peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk, + peer_dht_pk.clone(), + ); let real_precomputed_key = SalsaBox::new(&real_pk, &another_peer_real_sk); let base_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -2034,17 +2236,20 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie + cookie, }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); - let res = net_crypto.handle_crypto_handshake(&mut connection, &crypto_handshake).await; + let res = net_crypto + .handle_crypto_handshake(&mut connection, &crypto_handshake) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::InvalidRealPk); } @@ -2078,7 +2283,13 @@ mod tests { let peer_real_sk = SecretKey::generate(&mut rng); let peer_real_pk = peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk.clone(), real_pk.clone(), peer_real_pk.clone(), peer_dht_pk); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk.clone(), + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk, + ); let new_dht_pk = SecretKey::generate(&mut rng).public_key(); @@ -2089,17 +2300,20 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie + cookie, }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); - let res = net_crypto.handle_crypto_handshake(&mut connection, &crypto_handshake).await; + let res = net_crypto + .handle_crypto_handshake(&mut connection, &crypto_handshake) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::InvalidDhtPk); @@ -2112,8 +2326,8 @@ mod tests { async fn handle_crypto_handshake_test<'a, R, F>(handle_function: F) where - R: Future, - F: FnOnce(NetCrypto, CryptoHandshake, SocketAddr, PublicKey) -> R + R: Future, + F: FnOnce(NetCrypto, CryptoHandshake, SocketAddr, PublicKey) -> R, { let mut rng = thread_rng(); let (udp_tx, _udp_rx) = mpsc::channel(1); @@ -2139,13 +2353,27 @@ mod tests { let peer_real_sk = SecretKey::generate(&mut rng); let peer_real_pk = peer_real_sk.public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); let base_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -2154,15 +2382,16 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: cookie.clone() + cookie: cookie.clone(), }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); let net_crypto = handle_function(net_crypto, crypto_handshake, addr, peer_dht_pk).await; @@ -2182,7 +2411,12 @@ mod tests { #[tokio::test] async fn handle_udp_crypto_handshake() { - async fn test_me(net_crypto: NetCrypto, packet: CryptoHandshake, saddr: SocketAddr, _pk: PublicKey) -> NetCrypto { + async fn test_me( + net_crypto: NetCrypto, + packet: CryptoHandshake, + saddr: SocketAddr, + _pk: PublicKey, + ) -> NetCrypto { net_crypto.handle_udp_crypto_handshake(&packet, saddr).await.unwrap(); net_crypto } @@ -2192,7 +2426,12 @@ mod tests { #[tokio::test] async fn handle_tcp_crypto_handshake() { - async fn test_me(net_crypto: NetCrypto, packet: CryptoHandshake, _saddr: SocketAddr, pk: PublicKey) -> NetCrypto { + async fn test_me( + net_crypto: NetCrypto, + packet: CryptoHandshake, + _saddr: SocketAddr, + pk: PublicKey, + ) -> NetCrypto { net_crypto.handle_tcp_crypto_handshake(&packet, pk).await.unwrap(); net_crypto } @@ -2235,19 +2474,23 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: cookie.clone() + cookie: cookie.clone(), }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); let addr = "127.0.0.1:12345".parse().unwrap(); - net_crypto.handle_udp_crypto_handshake(&crypto_handshake, addr).await.unwrap(); + net_crypto + .handle_udp_crypto_handshake(&crypto_handshake, addr) + .await + .unwrap(); let connections = net_crypto.connections.read().await; let connection = connections.get(&peer_real_pk).unwrap().read().await.clone(); @@ -2294,7 +2537,13 @@ mod tests { net_crypto.add_friend(peer_real_pk.clone()).await; let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk, + ); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -2310,8 +2559,16 @@ mod tests { let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); let new_peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); @@ -2321,18 +2578,22 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: cookie.clone() + cookie: cookie.clone(), }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); let new_addr = "127.0.0.2:12345".parse().unwrap(); - net_crypto.handle_udp_crypto_handshake(&crypto_handshake, new_addr).await.unwrap(); + net_crypto + .handle_udp_crypto_handshake(&crypto_handshake, new_addr) + .await + .unwrap(); // the old connection should be replaced with the new one @@ -2352,8 +2613,16 @@ mod tests { let payload = packet.get_payload(&real_precomputed_key).unwrap(); assert_eq!(payload.cookie_hash, cookie.hash()); - assert!(!net_crypto.keys_by_addr.read().await.contains_key(&(addr.ip(), addr.port()))); - assert!(net_crypto.keys_by_addr.read().await.contains_key(&(new_addr.ip(), new_addr.port()))); + assert!(!net_crypto + .keys_by_addr + .read() + .await + .contains_key(&(addr.ip(), addr.port()))); + assert!(net_crypto + .keys_by_addr + .read() + .await + .contains_key(&(new_addr.ip(), new_addr.port()))); // the old connection should be killed @@ -2398,13 +2667,27 @@ mod tests { net_crypto.add_friend(peer_real_pk.clone()).await; let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); let base_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -2413,18 +2696,22 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: cookie.clone() + cookie: cookie.clone(), }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); let new_addr = "127.0.0.2:12345".parse().unwrap(); - net_crypto.handle_udp_crypto_handshake(&crypto_handshake, new_addr).await.unwrap(); + net_crypto + .handle_udp_crypto_handshake(&crypto_handshake, new_addr) + .await + .unwrap(); // the old connection should be updated with a new address @@ -2443,8 +2730,16 @@ mod tests { let payload = packet.get_payload(&real_precomputed_key).unwrap(); assert_eq!(payload.cookie_hash, cookie.hash()); - assert!(!net_crypto.keys_by_addr.read().await.contains_key(&(addr.ip(), addr.port()))); - assert!(net_crypto.keys_by_addr.read().await.contains_key(&(new_addr.ip(), new_addr.port()))); + assert!(!net_crypto + .keys_by_addr + .read() + .await + .contains_key(&(addr.ip(), addr.port()))); + assert!(net_crypto + .keys_by_addr + .read() + .await + .contains_key(&(new_addr.ip(), new_addr.port()))); } #[tokio::test] @@ -2476,7 +2771,13 @@ mod tests { net_crypto.add_friend(peer_real_pk.clone()).await; let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk, + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -2492,8 +2793,16 @@ mod tests { let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); let real_precomputed_key = SalsaBox::new(&real_pk, &peer_real_sk); let base_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -2502,18 +2811,23 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: cookie.clone() + cookie: cookie.clone(), }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); let new_addr = "127.0.0.2:12345".parse().unwrap(); - let error = net_crypto.handle_udp_crypto_handshake(&crypto_handshake, new_addr).await.err().unwrap(); + let error = net_crypto + .handle_udp_crypto_handshake(&crypto_handshake, new_addr) + .await + .err() + .unwrap(); assert_eq!(error, HandlePacketError::UnexpectedCryptoHandshake); } @@ -2550,19 +2864,24 @@ mod tests { let our_encrypted_cookie = EncryptedCookie::new(&mut rng, &net_crypto.symmetric_key, &our_cookie); let cookie = EncryptedCookie { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![43; 88] + payload: vec![43; 88], }; let crypto_handshake_payload = CryptoHandshakePayload { base_nonce, session_pk, cookie_hash: our_encrypted_cookie.hash(), - cookie: cookie.clone() + cookie: cookie.clone(), }; - let crypto_handshake = CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); + let crypto_handshake = + CryptoHandshake::new(&real_precomputed_key, &crypto_handshake_payload, our_encrypted_cookie); let addr = "127.0.0.1:12345".parse().unwrap(); - let error = net_crypto.handle_udp_crypto_handshake(&crypto_handshake, addr).await.err().unwrap(); + let error = net_crypto + .handle_udp_crypto_handshake(&crypto_handshake, addr) + .await + .err() + .unwrap(); assert_eq!(error, HandlePacketError::UnexpectedCryptoHandshake); } @@ -2592,7 +2911,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let peer_session_pk = SecretKey::generate(&mut rng).public_key(); @@ -2607,15 +2927,21 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3] + data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await.unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await + .unwrap(); // The diff between nonces is not bigger than the threshold so received // nonce shouldn't be changed - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -2653,7 +2979,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let peer_session_pk = SecretKey::generate(&mut rng).public_key(); @@ -2672,17 +2999,23 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3] + data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3], }; let crypto_data = CryptoData::new(&session_precomputed_key, packet_nonce, &crypto_data_payload); - net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await.unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await + .unwrap(); // The diff between nonces is bigger than the threshold so received // nonce should be changed increased let mut expected_nonce = received_nonce; increment_nonce_number(&mut expected_nonce, NONCE_DIFF_THRESHOLD); - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), expected_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + expected_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -2720,7 +3053,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); tokio::time::pause(); let now = clock_now(); @@ -2747,18 +3081,23 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 1, packet_number: 0, - data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3] + data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - tokio::time::advance(Duration::from_millis(250)).await; - net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await.unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await + .unwrap(); // The diff between nonces is not bigger than the threshold so received // nonce shouldn't be changed - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -2771,10 +3110,7 @@ mod tests { assert_eq!(received_data, vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3]); // avoid problems with floating point arithmetic - assert!( - connection.rtt > Duration::from_millis(249) - && connection.rtt < Duration::from_millis(251) - ); + assert!(connection.rtt > Duration::from_millis(249) && connection.rtt < Duration::from_millis(251)); } #[tokio::test] @@ -2817,15 +3153,23 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 7, // bigger than end index of sent packets buffer packet_number: 0, - data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3] + data: vec![PACKET_ID_LOSSY_RANGE_START, 1, 2, 3], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - let res = net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await; + let res = net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await; assert!(res.is_err()); - assert_eq!(res.err().unwrap(), HandlePacketError::PacketsArrayError(PacketsArrayError::OutsideIndex { index: 7 })); + assert_eq!( + res.err().unwrap(), + HandlePacketError::PacketsArrayError(PacketsArrayError::OutsideIndex { index: 7 }) + ); - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -2858,7 +3202,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let peer_session_pk = SecretKey::generate(&mut rng).public_key(); @@ -2873,32 +3218,44 @@ mod tests { let crypto_data_payload_1 = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 1, 2, 3] + data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 1, 2, 3], }; let crypto_data_1 = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload_1); let crypto_data_payload_2 = CryptoDataPayload { buffer_start: 0, packet_number: 1, - data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 4, 5, 6] + data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 4, 5, 6], }; let crypto_data_2 = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload_2); let crypto_data_payload_3 = CryptoDataPayload { buffer_start: 0, packet_number: 2, - data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 7, 8, 9] + data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 7, 8, 9], }; let crypto_data_3 = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload_3); // Send packets in random order - net_crypto.handle_crypto_data(&mut connection, &crypto_data_2, /* udp */ true).await.unwrap(); - net_crypto.handle_crypto_data(&mut connection, &crypto_data_3, /* udp */ true).await.unwrap(); - net_crypto.handle_crypto_data(&mut connection, &crypto_data_1, /* udp */ true).await.unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data_2, /* udp */ true) + .await + .unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data_3, /* udp */ true) + .await + .unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data_1, /* udp */ true) + .await + .unwrap(); // The diff between nonces is not bigger than the threshold so received // nonce shouldn't be changed - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 3); assert_eq!(connection.recv_array.buffer_end, 3); @@ -2963,15 +3320,23 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: CRYPTO_PACKET_BUFFER_SIZE, - data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 1, 2, 3] + data: vec![PACKET_ID_LOSSY_RANGE_START - 1, 1, 2, 3], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - let res = net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await; + let res = net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await; assert!(res.is_err()); - assert_eq!(res.err().unwrap(), HandlePacketError::PacketsArrayError(PacketsArrayError::TooBig { index: 32768 })); + assert_eq!( + res.err().unwrap(), + HandlePacketError::PacketsArrayError(PacketsArrayError::TooBig { index: 32768 }) + ); - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -3004,7 +3369,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); @@ -3020,17 +3386,28 @@ mod tests { }; let connection = Arc::new(RwLock::new(connection)); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), connection.clone()); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), connection.clone()); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk); let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![PACKET_ID_KILL] + data: vec![PACKET_ID_KILL], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - net_crypto.handle_crypto_data(&mut *connection.write().await, &crypto_data, /* udp */ true).await.unwrap(); + net_crypto + .handle_crypto_data(&mut *connection.write().await, &crypto_data, /* udp */ true) + .await + .unwrap(); assert!(net_crypto.connections.read().await.is_empty()); assert!(net_crypto.keys_by_addr.read().await.is_empty()); @@ -3083,7 +3460,10 @@ mod tests { }; assert!(connection.send_array.insert(5, packet_5).is_ok()); assert!(connection.send_array.insert(7, SentPacket::new(vec![45; 123])).is_ok()); - assert!(connection.send_array.insert(1024, SentPacket::new(vec![46; 123])).is_ok()); + assert!(connection + .send_array + .insert(1024, SentPacket::new(vec![46; 123])) + .is_ok()); connection.rtt = Duration::from_millis(500); @@ -3100,13 +3480,16 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![PACKET_ID_REQUEST, 1, 5, 0, 0, 0, 254] // request 0, 5 and 1024 packets + data: vec![PACKET_ID_REQUEST, 1, 5, 0, 0, 0, 254], // request 0, 5 and 1024 packets }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); tokio::time::advance(Duration::from_secs(1)).await; - net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await.unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await + .unwrap(); assert!(connection.send_array.get(0).unwrap().requested); assert!(connection.send_array.get(1).is_none()); @@ -3115,10 +3498,7 @@ mod tests { assert!(connection.send_array.get(1024).unwrap().requested); // avoid problems with floating point arithmetic - assert!( - connection.rtt > Duration::from_millis(249) - && connection.rtt < Duration::from_millis(251) - ); + assert!(connection.rtt > Duration::from_millis(249) && connection.rtt < Duration::from_millis(251)); } #[tokio::test] @@ -3152,7 +3532,10 @@ mod tests { assert!(connection.send_array.insert(1, SentPacket::new(vec![43; 123])).is_ok()); assert!(connection.send_array.insert(5, SentPacket::new(vec![44; 123])).is_ok()); assert!(connection.send_array.insert(7, SentPacket::new(vec![45; 123])).is_ok()); - assert!(connection.send_array.insert(1024, SentPacket::new(vec![46; 123])).is_ok()); + assert!(connection + .send_array + .insert(1024, SentPacket::new(vec![46; 123])) + .is_ok()); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let peer_session_pk = SecretKey::generate(&mut rng).public_key(); @@ -3167,11 +3550,14 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![PACKET_ID_REQUEST] + data: vec![PACKET_ID_REQUEST], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await.unwrap(); + net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await + .unwrap(); assert!(!connection.send_array.get(0).unwrap().requested); assert!(!connection.send_array.get(1).unwrap().requested); @@ -3220,15 +3606,20 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![255, 1, 2, 3] // only 255 is invalid id + data: vec![255, 1, 2, 3], // only 255 is invalid id }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - let res = net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await; + let res = net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::PacketId { id: 255 }); - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -3276,15 +3667,20 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: Vec::new() + data: Vec::new(), }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - let res = net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await; + let res = net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::DataEmpty); - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -3326,19 +3722,21 @@ mod tests { let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![0, 0, PACKET_ID_LOSSY_RANGE_START, 1, 2, 3] + data: vec![0, 0, PACKET_ID_LOSSY_RANGE_START, 1, 2, 3], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); - let res = net_crypto.handle_crypto_data(&mut connection, &crypto_data, /* udp */ true).await; + let res = net_crypto + .handle_crypto_data(&mut connection, &crypto_data, /* udp */ true) + .await; assert!(res.is_err()); assert_eq!(res.err().unwrap(), HandlePacketError::CannotHandleCryptoData); } async fn handle_crypto_data_lossy_test<'a, R, F>(handle_function: F) where - R: Future, - F: Fn(NetCrypto, CryptoData, SocketAddr, PublicKey) -> R + R: Future, + F: Fn(NetCrypto, CryptoData, SocketAddr, PublicKey) -> R, { let mut rng = thread_rng(); let (udp_tx, _udp_rx) = mpsc::channel(1); @@ -3363,7 +3761,13 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk.clone(), real_pk.clone(), peer_real_pk.clone(), peer_dht_pk.clone()); + let mut connection = CryptoConnection::new( + &dht_precomputed_key, + dht_pk.clone(), + real_pk.clone(), + peer_real_pk.clone(), + peer_dht_pk.clone(), + ); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let peer_session_pk = SecretKey::generate(&mut rng).public_key(); @@ -3378,13 +3782,21 @@ mod tests { let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); let crypto_data_payload = CryptoDataPayload { buffer_start: 0, packet_number: 0, - data: vec![0, 0, PACKET_ID_LOSSY_RANGE_START, 1, 2, 3] + data: vec![0, 0, PACKET_ID_LOSSY_RANGE_START, 1, 2, 3], }; let crypto_data = CryptoData::new(&session_precomputed_key, received_nonce, &crypto_data_payload); @@ -3395,7 +3807,10 @@ mod tests { // The diff between nonces is not bigger than the threshold so received // nonce shouldn't be changed - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); assert_eq!(connection.recv_array.buffer_start, 0); assert_eq!(connection.recv_array.buffer_end, 0); @@ -3512,10 +3927,13 @@ mod tests { let packet = CryptoData { nonce_last_bytes: 123, - payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH] + payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH], }; - net_crypto.send_packet(Packet::CryptoData(packet.clone()), &mut connection).await.unwrap(); + net_crypto + .send_packet(Packet::CryptoData(packet.clone()), &mut connection) + .await + .unwrap(); let (received, _udp_rx) = udp_rx.into_future().await; let (received, addr_to_send) = received.unwrap(); @@ -3552,20 +3970,24 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk, peer_dht_pk.clone()); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk, peer_dht_pk.clone()); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); let packet = CryptoData { nonce_last_bytes: 123, - payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH - 3] // 1 byte of packet kind and 2 bytes of nonce + payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH - 3], // 1 byte of packet kind and 2 bytes of nonce }; tokio::time::pause(); tokio::time::advance(UDP_DIRECT_TIMEOUT + Duration::from_secs(1)).await; - net_crypto.send_packet(Packet::CryptoData(packet.clone()), &mut connection).await.unwrap(); + net_crypto + .send_packet(Packet::CryptoData(packet.clone()), &mut connection) + .await + .unwrap(); let (received, _udp_rx) = udp_rx.into_future().await; let (received, addr_to_send) = received.unwrap(); @@ -3608,20 +4030,24 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk, peer_dht_pk.clone()); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk, peer_dht_pk.clone()); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); let packet = CryptoData { nonce_last_bytes: 123, - payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH] + payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH], }; tokio::time::pause(); tokio::time::advance(UDP_DIRECT_TIMEOUT + Duration::from_secs(1)).await; - net_crypto.send_packet(Packet::CryptoData(packet.clone()), &mut connection).await.unwrap(); + net_crypto + .send_packet(Packet::CryptoData(packet.clone()), &mut connection) + .await + .unwrap(); let (received, _tcp_rx) = tcp_rx.into_future().await; let (received, key_to_send) = received.unwrap(); @@ -3659,7 +4085,7 @@ mod tests { let packet = Packet::CryptoData(CryptoData { nonce_last_bytes: 123, - payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH] + payload: vec![42; DHT_ATTEMPT_MAX_PACKET_LENGTH], }); net_crypto.send_packet(packet.clone(), &mut connection).await.unwrap(); @@ -3692,14 +4118,19 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let packet = unpack!(connection.status.clone(), ConnectionStatus::CookieRequesting, packet); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk, Arc::new(RwLock::new(connection))); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk, Arc::new(RwLock::new(connection))); net_crypto.main_loop().await.unwrap(); @@ -3738,25 +4169,38 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); // make the connection timed out - let cookie_request_id = unpack!(connection.status.clone(), ConnectionStatus::CookieRequesting, cookie_request_id); + let cookie_request_id = unpack!( + connection.status.clone(), + ConnectionStatus::CookieRequesting, + cookie_request_id + ); let mut packet = unpack!(connection.status.clone(), ConnectionStatus::CookieRequesting, packet); packet.num_sent = MAX_NUM_SENDPACKET_TRIES; packet.sent_time -= CRYPTO_SEND_PACKET_INTERVAL + Duration::from_secs(1); connection.status = ConnectionStatus::CookieRequesting { cookie_request_id, - packet + packet, }; assert!(connection.is_timed_out()); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk); net_crypto.main_loop().await.unwrap(); @@ -3789,7 +4233,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); @@ -3805,8 +4250,16 @@ mod tests { session_precomputed_key: session_precomputed_key.clone(), }; - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk); net_crypto.main_loop().await.unwrap(); @@ -3847,7 +4300,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); @@ -3870,14 +4324,28 @@ mod tests { let data = vec![42; 123]; connection.packets_sent = 1; connection.send_array.buffer_end = 1; - assert!(connection.send_array.insert(0, SentPacket { - data: data.clone(), - sent_time: now, - requested: true, - }).is_ok()); - - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk); + assert!(connection + .send_array + .insert( + 0, + SentPacket { + data: data.clone(), + sent_time: now, + requested: true, + } + ) + .is_ok()); + + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk); net_crypto.main_loop().await.unwrap(); @@ -3984,7 +4452,10 @@ mod tests { connection.recv_array.buffer_end = 25; let data = vec![42; 123]; - net_crypto.send_data_packet(&mut connection, data.clone(), 7).await.unwrap(); + net_crypto + .send_data_packet(&mut connection, data.clone(), 7) + .await + .unwrap(); let (received, _udp_rx) = udp_rx.into_future().await; let (received, addr_to_send) = received.unwrap(); @@ -3998,8 +4469,14 @@ mod tests { assert_eq!(payload.data, data); increment_nonce(&mut sent_nonce); - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, sent_nonce), sent_nonce); - assert_eq!(unpack!(connection.status, ConnectionStatus::Established, received_nonce), received_nonce); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, sent_nonce), + sent_nonce + ); + assert_eq!( + unpack!(connection.status, ConnectionStatus::Established, received_nonce), + received_nonce + ); } #[tokio::test] @@ -4044,13 +4521,15 @@ mod tests { }; connection.recv_array.buffer_end = 270; - assert!(connection.recv_array.insert(2, RecvPacket { - data: vec![42; 123], - }).is_ok()); - for i in 5 .. 269 { - assert!(connection.recv_array.insert(i, RecvPacket { - data: vec![42; 123], - }).is_ok()); + assert!(connection + .recv_array + .insert(2, RecvPacket { data: vec![42; 123] }) + .is_ok()); + for i in 5..269 { + assert!(connection + .recv_array + .insert(i, RecvPacket { data: vec![42; 123] }) + .is_ok()); } tokio::time::pause(); @@ -4176,21 +4655,39 @@ mod tests { }; connection.send_array.buffer_end = 7; - assert!(connection.send_array.insert(2, SentPacket { - data: vec![42; 123], - sent_time: now, - requested: true, - }).is_ok()); - assert!(connection.send_array.insert(4, SentPacket { - data: vec![42; 123], - sent_time: now, - requested: false, - }).is_ok()); - assert!(connection.send_array.insert(5, SentPacket { - data: vec![42; 123], - sent_time: now, - requested: true, - }).is_ok()); + assert!(connection + .send_array + .insert( + 2, + SentPacket { + data: vec![42; 123], + sent_time: now, + requested: true, + } + ) + .is_ok()); + assert!(connection + .send_array + .insert( + 4, + SentPacket { + data: vec![42; 123], + sent_time: now, + requested: false, + } + ) + .is_ok()); + assert!(connection + .send_array + .insert( + 5, + SentPacket { + data: vec![42; 123], + sent_time: now, + requested: true, + } + ) + .is_ok()); let delay = Duration::from_secs(1); tokio::time::advance(delay).await; @@ -4235,7 +4732,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); @@ -4252,8 +4750,16 @@ mod tests { }; let connection = Arc::new(RwLock::new(connection)); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), connection.clone()); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), connection.clone()); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); let data = vec![16, 42]; @@ -4305,7 +4811,11 @@ mod tests { let peer_real_pk = SecretKey::generate(&mut rng).public_key(); - let error = net_crypto.send_lossless(peer_real_pk, vec![16, 42]).await.err().unwrap(); + let error = net_crypto + .send_lossless(peer_real_pk, vec![16, 42]) + .await + .err() + .unwrap(); assert_eq!(error, SendLosslessPacketError::NoConnection); } @@ -4333,7 +4843,11 @@ mod tests { let peer_real_pk = SecretKey::generate(&mut rng).public_key(); - let error = net_crypto.send_lossless(peer_real_pk, vec![10, 42]).await.err().unwrap(); + let error = net_crypto + .send_lossless(peer_real_pk, vec![10, 42]) + .await + .err() + .unwrap(); assert_eq!(error, SendLosslessPacketError::InvalidPacketId); } @@ -4362,7 +4876,9 @@ mod tests { let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let peer_dht_sk = SecretKey::generate(&mut rng); let peer_dht_pk = peer_dht_sk.public_key(); - net_crypto.add_connection(peer_real_pk.clone(), peer_dht_pk.clone()).await; + net_crypto + .add_connection(peer_real_pk.clone(), peer_dht_pk.clone()) + .await; let connections = net_crypto.connections.read().await; let connection = connections[&peer_real_pk].read().await; @@ -4372,7 +4888,9 @@ mod tests { let status_packet = unpack!(connection.status.clone(), ConnectionStatus::CookieRequesting, packet); let cookie_request = unpack!(status_packet.packet, StatusPacket::CookieRequest); - let cookie_request_payload = cookie_request.get_payload(&SalsaBox::new(&dht_pk, &peer_dht_sk)).unwrap(); + let cookie_request_payload = cookie_request + .get_payload(&SalsaBox::new(&dht_pk, &peer_dht_sk)) + .unwrap(); assert_eq!(cookie_request_payload.pk, real_pk); } @@ -4401,11 +4919,15 @@ mod tests { let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); - net_crypto.add_connection(peer_real_pk.clone(), peer_dht_pk.clone()).await; + net_crypto + .add_connection(peer_real_pk.clone(), peer_dht_pk.clone()) + .await; // adding a friend that already exists won't do anything let another_peer_dht_pk = SecretKey::generate(&mut rng).public_key(); - net_crypto.add_connection(peer_real_pk.clone(), another_peer_dht_pk).await; + net_crypto + .add_connection(peer_real_pk.clone(), another_peer_dht_pk) + .await; let connections = net_crypto.connections.read().await; let connection = connections[&peer_real_pk].read().await; @@ -4450,8 +4972,14 @@ mod tests { assert_eq!(connection.get_udp_addr_v4(), Some(addr_v4)); assert_eq!(connection.get_udp_addr_v6(), Some(addr_v6)); - assert_eq!(net_crypto.keys_by_addr.read().await[&(addr_v4.ip(), addr_v4.port())], peer_real_pk); - assert_eq!(net_crypto.keys_by_addr.read().await[&(addr_v6.ip(), addr_v6.port())], peer_real_pk); + assert_eq!( + net_crypto.keys_by_addr.read().await[&(addr_v4.ip(), addr_v4.port())], + peer_real_pk + ); + assert_eq!( + net_crypto.keys_by_addr.read().await[&(addr_v6.ip(), addr_v6.port())], + peer_real_pk + ); } #[tokio::test] @@ -4554,7 +5082,8 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let received_nonce = SalsaBox::generate_nonce(&mut rng).into(); let sent_nonce = SalsaBox::generate_nonce(&mut rng).into(); @@ -4570,13 +5099,25 @@ mod tests { let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); net_crypto.kill_connection(peer_real_pk.clone()).await.unwrap(); assert!(!net_crypto.connections.read().await.contains_key(&peer_real_pk)); - assert!(!net_crypto.keys_by_addr.read().await.contains_key(&(addr.ip(), addr.port()))); + assert!(!net_crypto + .keys_by_addr + .read() + .await + .contains_key(&(addr.ip(), addr.port()))); let (received, _udp_rx) = udp_rx.into_future().await; let (received, addr_to_send) = received.unwrap(); @@ -4643,18 +5184,31 @@ mod tests { let peer_dht_pk = SecretKey::generate(&mut rng).public_key(); let peer_real_pk = SecretKey::generate(&mut rng).public_key(); let dht_precomputed_key = SalsaBox::new(&peer_dht_pk, &dht_sk); - let mut connection = CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); + let mut connection = + CryptoConnection::new(&dht_precomputed_key, dht_pk, real_pk, peer_real_pk.clone(), peer_dht_pk); let addr = "127.0.0.1:12345".parse().unwrap(); connection.set_udp_addr(addr); - net_crypto.connections.write().await.insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); - net_crypto.keys_by_addr.write().await.insert((addr.ip(), addr.port()), peer_real_pk.clone()); + net_crypto + .connections + .write() + .await + .insert(peer_real_pk.clone(), Arc::new(RwLock::new(connection))); + net_crypto + .keys_by_addr + .write() + .await + .insert((addr.ip(), addr.port()), peer_real_pk.clone()); net_crypto.kill_connection(peer_real_pk.clone()).await.unwrap(); assert!(!net_crypto.connections.read().await.contains_key(&peer_real_pk)); - assert!(!net_crypto.keys_by_addr.read().await.contains_key(&(addr.ip(), addr.port()))); + assert!(!net_crypto + .keys_by_addr + .read() + .await + .contains_key(&(addr.ip(), addr.port()))); // Necessary to drop udp_tx so that udp_rx.collect() can be finished drop(net_crypto.udp_tx); diff --git a/tox_core/src/net_crypto/packets_array.rs b/tox_core/src/net_crypto/packets_array.rs index c20388ad6..2b9616efc 100644 --- a/tox_core/src/net_crypto/packets_array.rs +++ b/tox_core/src/net_crypto/packets_array.rs @@ -72,13 +72,13 @@ impl PacketsArray { /// packet with this index already exists pub fn insert(&mut self, index: u32, packet: T) -> Result<(), PacketsArrayError> { if index.overflowing_sub(self.buffer_start).0 >= CRYPTO_PACKET_BUFFER_SIZE { - return Err(PacketsArrayError::too_big(index)) + return Err(PacketsArrayError::too_big(index)); } let i = real_index(index); if self.buffer[i].is_some() { - return Err(PacketsArrayError::already_exist(index)) + return Err(PacketsArrayError::already_exist(index)); } self.buffer[i] = Some(Box::new(packet)); @@ -94,7 +94,7 @@ impl PacketsArray { /// Returns an error when the buffer is full pub fn push_back(&mut self, packet: T) -> Result<(), PacketsArrayError> { if self.len() == CRYPTO_PACKET_BUFFER_SIZE { - return Err(PacketsArrayError::ArrayFull) + return Err(PacketsArrayError::ArrayFull); } self.buffer[real_index(self.buffer_end)] = Some(Box::new(packet)); @@ -106,7 +106,7 @@ impl PacketsArray { /// Get packet at the start index and increment index if the packet exists pub fn pop_front(&mut self) -> Option { if self.buffer_start == self.buffer_end { - return None + return None; } let i = real_index(self.buffer_start); @@ -122,7 +122,7 @@ impl PacketsArray { let len = self.len(); if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len { - return false + return false; } self.buffer[real_index(index)].is_some() @@ -133,7 +133,7 @@ impl PacketsArray { let len = self.len(); if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len { - return None + return None; } self.buffer[real_index(index)].as_deref() @@ -144,7 +144,7 @@ impl PacketsArray { let len = self.len(); if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len { - return None + return None; } self.buffer[real_index(index)].as_deref_mut() @@ -156,7 +156,7 @@ impl PacketsArray { let len = self.len(); if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 >= len { - return None + return None; } self.buffer[real_index(index)].take().map(|packet| *packet) @@ -168,11 +168,11 @@ impl PacketsArray { /// index is lower then end index pub fn set_buffer_end(&mut self, index: u32) -> Result<(), PacketsArrayError> { if index.overflowing_sub(self.buffer_start).0 > CRYPTO_PACKET_BUFFER_SIZE { - return Err(PacketsArrayError::too_big(index)) + return Err(PacketsArrayError::too_big(index)); } if index.overflowing_sub(self.buffer_end).0 > CRYPTO_PACKET_BUFFER_SIZE { - return Err(PacketsArrayError::lower_index(index)) + return Err(PacketsArrayError::lower_index(index)); } self.buffer_end = index; @@ -187,10 +187,10 @@ impl PacketsArray { let len = self.len(); if self.buffer_end.overflowing_sub(index).0 > len || index.overflowing_sub(self.buffer_start).0 > len { - return Err(PacketsArrayError::outside_index(index)) + return Err(PacketsArrayError::outside_index(index)); } - for packet in &mut self.buffer[real_index(self.buffer_start) .. real_index(index)] { + for packet in &mut self.buffer[real_index(self.buffer_start)..real_index(index)] { *packet = None; } @@ -208,13 +208,13 @@ impl PacketsArray { let (first, second) = self.buffer.split_at_mut(start); second.iter_mut().chain(first.iter_mut().take(end)) } else { - [].iter_mut().chain(self.buffer[start ..].iter_mut().take(end - start)) + [].iter_mut().chain(self.buffer[start..].iter_mut().take(end - start)) }; - iter.enumerate().flat_map(move |(i, packet)| - packet.iter_mut().map(move |packet| - (buffer_start.overflowing_add(i as u32).0, &mut **packet) - ) - ) + iter.enumerate().flat_map(move |(i, packet)| { + packet + .iter_mut() + .map(move |packet| (buffer_start.overflowing_add(i as u32).0, &mut **packet)) + }) } } @@ -264,13 +264,23 @@ mod tests { let mut array = PacketsArray::<()>::new(); let res = array.insert(CRYPTO_PACKET_BUFFER_SIZE, ()); assert!(res.is_err()); - assert_eq!(res.err().unwrap(), PacketsArrayError::TooBig { index: CRYPTO_PACKET_BUFFER_SIZE }); + assert_eq!( + res.err().unwrap(), + PacketsArrayError::TooBig { + index: CRYPTO_PACKET_BUFFER_SIZE + } + ); assert_eq!(array.buffer_start, 0); assert_eq!(array.buffer_end, 0); array.buffer_start = u32::max_value(); let res = array.insert(CRYPTO_PACKET_BUFFER_SIZE - 1, ()); assert!(res.is_err()); - assert_eq!(res.err().unwrap(), PacketsArrayError::TooBig { index: CRYPTO_PACKET_BUFFER_SIZE - 1 }); + assert_eq!( + res.err().unwrap(), + PacketsArrayError::TooBig { + index: CRYPTO_PACKET_BUFFER_SIZE - 1 + } + ); assert_eq!(array.buffer_start, u32::max_value()); assert_eq!(array.buffer_end, 0); } @@ -389,7 +399,12 @@ mod tests { let mut array = PacketsArray::<()>::new(); let res = array.set_buffer_end(CRYPTO_PACKET_BUFFER_SIZE + 1); assert!(res.is_err()); - assert_eq!(res.err().unwrap(), PacketsArrayError::TooBig { index: CRYPTO_PACKET_BUFFER_SIZE + 1 }); + assert_eq!( + res.err().unwrap(), + PacketsArrayError::TooBig { + index: CRYPTO_PACKET_BUFFER_SIZE + 1 + } + ); assert_eq!(array.buffer_start, 0); assert_eq!(array.buffer_end, 0); } @@ -458,10 +473,7 @@ mod tests { assert!(array.insert(0, ()).is_ok()); assert!(array.insert(2, ()).is_ok()); assert!(array.insert(5, ()).is_ok()); - assert_eq!( - array.iter_mut().map(|(i, _)| i).collect::>(), - vec![0, 2, 5] - ); + assert_eq!(array.iter_mut().map(|(i, _)| i).collect::>(), vec![0, 2, 5]); } #[test] diff --git a/tox_core/src/onion/client/mod.rs b/tox_core/src/onion/client/mod.rs index e67ae5918..2eb4189dc 100644 --- a/tox_core/src/onion/client/mod.rs +++ b/tox_core/src/onion/client/mod.rs @@ -10,29 +10,29 @@ use std::net::SocketAddr; use std::sync::Arc; use std::time::{Duration, Instant}; -use crypto_box::{SalsaBox, aead::AeadCore}; -use futures::{StreamExt, SinkExt}; +use crypto_box::{aead::AeadCore, SalsaBox}; use futures::channel::mpsc; use futures::lock::Mutex; +use futures::{SinkExt, StreamExt}; use rand::{thread_rng, Rng}; -use tox_crypto::*; use crate::dht::ip_port::IsGlobal; -use tox_packet::dht::packed_node::PackedNode; -use tox_packet::dht::*; +use crate::dht::kbucket::*; use crate::dht::request_queue::RequestQueue; use crate::dht::server::Server as DhtServer; -use crate::dht::kbucket::*; -use tox_packet::ip_port::*; +use crate::io_tokio::*; use crate::onion::client::errors::*; use crate::onion::client::onion_path::*; use crate::onion::client::paths_pool::*; use crate::onion::onion_announce::INITIAL_PING_ID; -use tox_packet::onion::*; -use tox_packet::packed_node::*; use crate::relay::client::Connections as TcpConnections; use crate::time::*; -use crate::io_tokio::*; +use tox_crypto::*; +use tox_packet::dht::packed_node::PackedNode; +use tox_packet::dht::*; +use tox_packet::ip_port::*; +use tox_packet::onion::*; +use tox_packet::packed_node::*; /// Shorthand for the transmit half of the message channel for sending DHT /// `PublicKey` when it gets known. The first key is a long term key, the second @@ -85,8 +85,7 @@ const SEARCH_COUNT_FRIEND_ANNOUNCE_BEGINNING: u32 = 17; const ONION_FRIEND_BACKOFF_FACTOR: u32 = 4; /// Maximum interval for friends searching. -const ONION_FRIEND_MAX_PING_INTERVAL: Duration = - Duration::from_secs(MAX_ONION_FRIEND_NODES as u64 * 60 * 5); +const ONION_FRIEND_MAX_PING_INTERVAL: Duration = Duration::from_secs(MAX_ONION_FRIEND_NODES as u64 * 60 * 5); /// After this time since last unsuccessful ping (and when ping attempts are /// exhausted) node is considered timed out. @@ -235,8 +234,8 @@ impl OnionNode { /// Node is considered stable after `TIME_TO_STABLE` since it was /// added to a close list if it responses to our requests. pub fn is_stable(&self) -> bool { - clock_elapsed(self.added_time) >= TIME_TO_STABLE && - (self.unsuccessful_pings == 0 || clock_elapsed(self.ping_time) < ONION_NODE_TIMEOUT) + clock_elapsed(self.added_time) >= TIME_TO_STABLE + && (self.unsuccessful_pings == 0 || clock_elapsed(self.ping_time) < ONION_NODE_TIMEOUT) } } @@ -279,7 +278,7 @@ impl<'a> AnnouncePacketData<'a> { InnerOnionAnnounceRequest::new( &SalsaBox::new(node_pk, self.packet_sk), self.packet_pk.clone(), - &payload + &payload, ) } /// Create `InnerOnionAnnounceRequest` for a search request. @@ -347,12 +346,7 @@ pub struct OnionClient { impl OnionClient { /// Create new `OnionClient`. - pub fn new( - dht: DhtServer, - tcp_connections: TcpConnections, - real_sk: SecretKey, - real_pk: PublicKey - ) -> Self { + pub fn new(dht: DhtServer, tcp_connections: TcpConnections, real_sk: SecretKey, real_pk: PublicKey) -> Self { let data_sk = SecretKey::generate(&mut thread_rng()); let data_pk = data_sk.public_key(); OnionClient { @@ -377,7 +371,12 @@ impl OnionClient { } /// Check if a node was pinged recently. - fn is_pinged_recently(&self, pk: PublicKey, search_pk: PublicKey, request_queue: &RequestQueue) -> bool { + fn is_pinged_recently( + &self, + pk: PublicKey, + search_pk: PublicKey, + request_queue: &RequestQueue, + ) -> bool { let check_pks = |data: &AnnounceRequestData| -> bool { let request_search_pk = if let Some(ref friend_pk) = data.friend_pk { friend_pk @@ -386,44 +385,53 @@ impl OnionClient { }; data.pk == pk && &search_pk == request_search_pk }; - request_queue.get_values() - .any(|(ping_time, request_data)| check_pks(request_data) && - clock_elapsed(ping_time) < MIN_NODE_PING_TIME) + request_queue + .get_values() + .any(|(ping_time, request_data)| check_pks(request_data) && clock_elapsed(ping_time) < MIN_NODE_PING_TIME) } /// Send onion request via TCP or UDP depending on path. - async fn send_onion_request(&self, path: OnionPath, inner_onion_request: InnerOnionRequest, saddr: SocketAddr) - -> Result<(), mpsc::SendError> { + async fn send_onion_request( + &self, + path: OnionPath, + inner_onion_request: InnerOnionRequest, + saddr: SocketAddr, + ) -> Result<(), mpsc::SendError> { match path.path_type { OnionPathType::Tcp => { let onion_request = path.create_tcp_onion_request(saddr, inner_onion_request); // TODO: can we handle errors better? Right now we can try send a // request to a non-existent or suspended node which returns an error - self.tcp_connections.send_onion(path.nodes[0].public_key.clone(), onion_request).await.ok(); + self.tcp_connections + .send_onion(path.nodes[0].public_key.clone(), onion_request) + .await + .ok(); Ok(()) - }, + } OnionPathType::Udp => { - let onion_request = - path.create_udp_onion_request(saddr, inner_onion_request); + let onion_request = path.create_udp_onion_request(saddr, inner_onion_request); let mut tx = self.dht.tx.clone(); - tx.send(( - Packet::OnionRequest0(onion_request), - path.nodes[0].saddr - )).await - }, + tx.send((Packet::OnionRequest0(onion_request), path.nodes[0].saddr)) + .await + } } } /// Handle `OnionAnnounceResponse` packet. - pub async fn handle_announce_response(&self, packet: &OnionAnnounceResponse, is_global: bool) -> Result<(), HandleAnnounceResponseError> { + pub async fn handle_announce_response( + &self, + packet: &OnionAnnounceResponse, + is_global: bool, + ) -> Result<(), HandleAnnounceResponseError> { let state = &mut *self.state.lock().await; - let announce_data = if let Some(announce_data) = state.announce_requests.check_ping_id(packet.sendback_data, |_| true) { - announce_data - } else { - return Err(HandleAnnounceResponseError::InvalidRequestId); - }; + let announce_data = + if let Some(announce_data) = state.announce_requests.check_ping_id(packet.sendback_data, |_| true) { + announce_data + } else { + return Err(HandleAnnounceResponseError::InvalidRequestId); + }; // Assign variables depending on response type (was it announcing or searching request) let (nodes_list, last_seen, announce_packet_data) = if let Some(ref friend_pk) = announce_data.friend_pk { @@ -434,7 +442,11 @@ impl OnionClient { search_pk: friend.real_pk.clone(), data_pk: None, }; - (&mut friend.close_nodes, Some(&mut friend.last_seen), announce_packet_data) + ( + &mut friend.close_nodes, + Some(&mut friend.last_seen), + announce_packet_data, + ) } else { return Err(HandleAnnounceResponseError::NoFriendWithPk); } @@ -450,17 +462,24 @@ impl OnionClient { let payload = match packet.get_payload(&SalsaBox::new(&announce_data.pk, announce_packet_data.packet_sk)) { Ok(payload) => payload, - Err(e) => return Err(HandleAnnounceResponseError::InvalidPayload(e)) + Err(e) => return Err(HandleAnnounceResponseError::InvalidPayload(e)), }; - trace!("OnionAnnounceResponse status: {:?}, data: {:?}", payload.announce_status, announce_data); + trace!( + "OnionAnnounceResponse status: {:?}, data: {:?}", + payload.announce_status, + announce_data + ); - if announce_data.friend_pk.is_some() && payload.announce_status == AnnounceStatus::Announced || - announce_data.friend_pk.is_none() && payload.announce_status == AnnounceStatus::Found { + if announce_data.friend_pk.is_some() && payload.announce_status == AnnounceStatus::Announced + || announce_data.friend_pk.is_none() && payload.announce_status == AnnounceStatus::Found + { return Err(HandleAnnounceResponseError::InvalidAnnounceStatus); } - state.paths_pool.set_timeouts(announce_data.path_id.clone(), announce_data.friend_pk.is_some()); + state + .paths_pool + .set_timeouts(announce_data.path_id.clone(), announce_data.friend_pk.is_some()); if payload.announce_status == AnnounceStatus::Found { if let Some(last_seen) = last_seen { @@ -475,20 +494,27 @@ impl OnionClient { }; let now = clock_now(); - nodes_list.try_add(&announce_packet_data.search_pk, OnionNode { - pk: announce_data.pk.clone(), - saddr: announce_data.saddr, - path_id: announce_data.path_id, - ping_id, - data_pk, - unsuccessful_pings: 0, - added_time: now, - ping_time: now, - response_time: now, - announce_status: payload.announce_status, - }, /* evict */ true); + nodes_list.try_add( + &announce_packet_data.search_pk, + OnionNode { + pk: announce_data.pk.clone(), + saddr: announce_data.saddr, + path_id: announce_data.path_id, + ping_id, + data_pk, + unsuccessful_pings: 0, + added_time: now, + ping_time: now, + response_time: now, + announce_status: payload.announce_status, + }, + /* evict */ true, + ); - state.paths_pool.path_nodes.put(PackedNode::new(announce_data.saddr, announce_data.pk.clone())); + state + .paths_pool + .path_nodes + .put(PackedNode::new(announce_data.saddr, announce_data.pk.clone())); let mut rng = thread_rng(); for node in &payload.nodes { @@ -498,7 +524,11 @@ impl OnionClient { } // do not ping nodes that was pinged recently - if self.is_pinged_recently(node.pk.clone(), announce_packet_data.search_pk.clone(), &state.announce_requests) { + if self.is_pinged_recently( + node.pk.clone(), + announce_packet_data.search_pk.clone(), + &state.announce_requests, + ) { continue; } @@ -506,39 +536,54 @@ impl OnionClient { continue; } - let path = if let Some(path) = state.paths_pool.random_path(&self.dht, &self.tcp_connections, announce_data.friend_pk.is_some()).await { + let path = if let Some(path) = state + .paths_pool + .random_path(&self.dht, &self.tcp_connections, announce_data.friend_pk.is_some()) + .await + { path } else { - continue + continue; }; - let request_id = state.announce_requests.new_ping_id(&mut rng, AnnounceRequestData { - pk: node.pk.clone(), - saddr: node.saddr, - path_id: path.id(), - friend_pk: announce_data.friend_pk.clone(), - }); + let request_id = state.announce_requests.new_ping_id( + &mut rng, + AnnounceRequestData { + pk: node.pk.clone(), + saddr: node.saddr, + path_id: path.id(), + friend_pk: announce_data.friend_pk.clone(), + }, + ); let inner_announce_request = announce_packet_data.search_request(&node.pk, request_id); - self.send_onion_request(path, InnerOnionRequest::InnerOnionAnnounceRequest(inner_announce_request), node.saddr) - .await - .map_err(HandleAnnounceResponseError::SendTo)?; + self.send_onion_request( + path, + InnerOnionRequest::InnerOnionAnnounceRequest(inner_announce_request), + node.saddr, + ) + .await + .map_err(HandleAnnounceResponseError::SendTo)?; } Ok(()) } /// Handle DHT `PublicKey` announce from both onion and DHT. - pub async fn handle_dht_pk_announce(&self, friend_pk: PublicKey, dht_pk_announce: DhtPkAnnouncePayload) -> Result<(), HandleDhtPkAnnounceError> { + pub async fn handle_dht_pk_announce( + &self, + friend_pk: PublicKey, + dht_pk_announce: DhtPkAnnouncePayload, + ) -> Result<(), HandleDhtPkAnnounceError> { let mut state = self.state.lock().await; let friend = match state.friends.get_mut(&friend_pk) { Some(friend) => friend, - None => return Err(HandleDhtPkAnnounceError::NoFriendWithPk) + None => return Err(HandleDhtPkAnnounceError::NoFriendWithPk), }; if dht_pk_announce.no_reply <= friend.last_no_reply { - return Err(HandleDhtPkAnnounceError::InvalidNoReply) + return Err(HandleDhtPkAnnounceError::InvalidNoReply); } friend.last_no_reply = dht_pk_announce.no_reply; @@ -547,18 +592,23 @@ impl OnionClient { let tx = state.dht_pk_tx.clone(); let dht_pk = dht_pk_announce.dht_pk.clone(); - maybe_send_unbounded(tx, (friend_pk, dht_pk)).await + maybe_send_unbounded(tx, (friend_pk, dht_pk)) + .await .map_err(HandleDhtPkAnnounceError::SendTo)?; for node in dht_pk_announce.nodes.into_iter() { match node.ip_port.protocol { ProtocolType::Udp => { let packed_node = PackedNode::new(node.ip_port.to_saddr(), node.pk.clone()); - self.dht.ping_node(packed_node).await + self.dht + .ping_node(packed_node) + .await .map_err(HandleDhtPkAnnounceError::PingNode)?; - }, + } ProtocolType::Tcp => { - self.tcp_connections.add_relay_connection(node.ip_port.to_saddr(), node.pk, dht_pk_announce.dht_pk.clone()).await + self.tcp_connections + .add_relay_connection(node.ip_port.to_saddr(), node.pk, dht_pk_announce.dht_pk.clone()) + .await .map_err(HandleDhtPkAnnounceError::AddRelay)?; } } @@ -571,19 +621,21 @@ impl OnionClient { pub async fn handle_data_response(&self, packet: &OnionDataResponse) -> Result<(), HandleDataResponseError> { let payload = match packet.get_payload(&SalsaBox::new(&packet.temporary_pk, &self.data_sk)) { Ok(payload) => payload, - Err(e) => return Err(HandleDataResponseError::InvalidPayload(e)) + Err(e) => return Err(HandleDataResponseError::InvalidPayload(e)), }; let iner_payload = match payload.get_payload(&packet.nonce, &SalsaBox::new(&payload.real_pk, &self.real_sk)) { Ok(payload) => payload, - Err(e) => return Err(HandleDataResponseError::InvalidInnerPayload(e)) + Err(e) => return Err(HandleDataResponseError::InvalidInnerPayload(e)), }; match iner_payload { - OnionDataResponseInnerPayload::DhtPkAnnounce(dht_pk_announce) => - self.handle_dht_pk_announce(payload.real_pk, dht_pk_announce).await - .map_err(HandleDataResponseError::DhtPkAnnounce), + OnionDataResponseInnerPayload::DhtPkAnnounce(dht_pk_announce) => self + .handle_dht_pk_announce(payload.real_pk, dht_pk_announce) + .await + .map_err(HandleDataResponseError::DhtPkAnnounce), OnionDataResponseInnerPayload::FriendRequest(friend_request) => { let tx = self.state.lock().await.friend_request_tx.clone(); - maybe_send_unbounded(tx, (payload.real_pk, friend_request)).await + maybe_send_unbounded(tx, (payload.real_pk, friend_request)) + .await .map_err(HandleDataResponseError::FriendRequest) } } @@ -644,14 +696,14 @@ impl OnionClient { announce_requests: &mut RequestQueue, announce_packet_data: AnnouncePacketData<'_>, friend_pk: Option, - interval: Option + interval: Option, ) -> Result { let capacity = close_nodes.capacity(); - let ping_random = close_nodes.iter().all(|node| + let ping_random = close_nodes.iter().all(|node| { clock_elapsed(node.ping_time) >= ONION_NODE_PING_INTERVAL && // ensure we get a response from some node roughly once per interval / capacity interval.map_or(true, |interval| clock_elapsed(node.response_time) >= interval / capacity as u32) - ); + }); let mut packets_sent = false; let mut good_nodes_count = 0; let mut rng = thread_rng(); @@ -680,62 +732,88 @@ impl OnionClient { ANNOUNCE_INTERVAL_NOT_ANNOUNCED }; - if clock_elapsed(node.ping_time) >= interval || ping_random && thread_rng().gen_range(0 .. capacity) == 0 { + if clock_elapsed(node.ping_time) >= interval || ping_random && thread_rng().gen_range(0..capacity) == 0 { // Last chance for a long-lived node let path = if node.is_last_ping_attempt() && node.is_stable() { - paths_pool.random_path(&self.dht, &self.tcp_connections, friend_pk.is_some()).await + paths_pool + .random_path(&self.dht, &self.tcp_connections, friend_pk.is_some()) + .await } else { - paths_pool.get_or_random_path(&self.dht, &self.tcp_connections, node.path_id.clone(), friend_pk.is_some()).await + paths_pool + .get_or_random_path( + &self.dht, + &self.tcp_connections, + node.path_id.clone(), + friend_pk.is_some(), + ) + .await }; - let path = if let Some(path) = path { - path - } else { - continue - }; + let path = if let Some(path) = path { path } else { continue }; node.unsuccessful_pings += 1; node.ping_time = clock_now(); - let request_id = announce_requests.new_ping_id(&mut rng, AnnounceRequestData { - pk: node.pk.clone(), - saddr: node.saddr, - path_id: path.id(), - friend_pk: friend_pk.clone(), - }); + let request_id = announce_requests.new_ping_id( + &mut rng, + AnnounceRequestData { + pk: node.pk.clone(), + saddr: node.saddr, + path_id: path.id(), + friend_pk: friend_pk.clone(), + }, + ); let inner_announce_request = match node.ping_id { - Some(ping_id) if friend_pk.is_none() => announce_packet_data.announce_request(&node.pk, ping_id, request_id), - _ => announce_packet_data.search_request(&node.pk, request_id) + Some(ping_id) if friend_pk.is_none() => { + announce_packet_data.announce_request(&node.pk, ping_id, request_id) + } + _ => announce_packet_data.search_request(&node.pk, request_id), }; - self.send_onion_request(path, InnerOnionRequest::InnerOnionAnnounceRequest(inner_announce_request), node.saddr).await?; + self.send_onion_request( + path, + InnerOnionRequest::InnerOnionAnnounceRequest(inner_announce_request), + node.saddr, + ) + .await?; packets_sent = true; } } - if good_nodes_count <= thread_rng().gen_range(0 .. close_nodes.capacity()) { - for _ in 0 .. close_nodes.capacity() / 2 { + if good_nodes_count <= thread_rng().gen_range(0..close_nodes.capacity()) { + for _ in 0..close_nodes.capacity() / 2 { let node = if let Some(node) = paths_pool.path_nodes.rand() { node } else { - break + break; }; - let path = if let Some(path) = paths_pool.random_path(&self.dht, &self.tcp_connections, friend_pk.is_some()).await { + let path = if let Some(path) = paths_pool + .random_path(&self.dht, &self.tcp_connections, friend_pk.is_some()) + .await + { path } else { - break + break; }; - let request_id = announce_requests.new_ping_id(&mut rng, AnnounceRequestData { - pk: node.pk.clone(), - saddr: node.saddr, - path_id: path.id(), - friend_pk: friend_pk.clone(), - }); + let request_id = announce_requests.new_ping_id( + &mut rng, + AnnounceRequestData { + pk: node.pk.clone(), + saddr: node.saddr, + path_id: path.id(), + friend_pk: friend_pk.clone(), + }, + ); let inner_announce_request = announce_packet_data.request(&node.pk, None, request_id); - self.send_onion_request(path, InnerOnionRequest::InnerOnionAnnounceRequest(inner_announce_request), node.saddr).await?; + self.send_onion_request( + path, + InnerOnionRequest::InnerOnionAnnounceRequest(inner_announce_request), + node.saddr, + ) + .await?; packets_sent = true; } } @@ -759,24 +837,39 @@ impl OnionClient { announce_packet_data, None, None, - ).await.map(drop).map_err(RunError::SendTo) + ) + .await + .map(drop) + .map_err(RunError::SendTo) } /// Get nodes to include to DHT `PublicKey` announcement packet. async fn dht_pk_nodes(&self) -> Vec { let relays = self.tcp_connections.get_random_relays(2).await; - let close_nodes: Vec = self.dht.get_closest(&self.dht.pk, 4 - relays.len() as u8, false).await.into(); - relays.into_iter().map(|node| TcpUdpPackedNode { - pk: node.pk, - ip_port: IpPort::from_tcp_saddr(node.saddr), - }).chain(close_nodes.into_iter().map(|node| TcpUdpPackedNode { - pk: node.pk, - ip_port: IpPort::from_udp_saddr(node.saddr), - })).collect() + let close_nodes: Vec = self + .dht + .get_closest(&self.dht.pk, 4 - relays.len() as u8, false) + .await + .into(); + relays + .into_iter() + .map(|node| TcpUdpPackedNode { + pk: node.pk, + ip_port: IpPort::from_tcp_saddr(node.saddr), + }) + .chain(close_nodes.into_iter().map(|node| TcpUdpPackedNode { + pk: node.pk, + ip_port: IpPort::from_udp_saddr(node.saddr), + })) + .collect() } /// Announce our DHT `PublicKey` to a friend via onion. - async fn send_dht_pk_onion(&self, friend: &mut OnionFriend, paths_pool: &mut PathsPool) -> Result<(), mpsc::SendError> { + async fn send_dht_pk_onion( + &self, + friend: &mut OnionFriend, + paths_pool: &mut PathsPool, + ) -> Result<(), mpsc::SendError> { let mut rng = thread_rng(); let dht_pk_announce = DhtPkAnnouncePayload::new(self.dht.pk.clone(), self.dht_pk_nodes().await); let inner_payload = OnionDataResponseInnerPayload::DhtPkAnnounce(dht_pk_announce); @@ -798,20 +891,34 @@ impl OnionClient { let data_pk = if let Some(ref data_pk) = node.data_pk { data_pk.clone() } else { - continue + continue; }; - let path = if let Some(path) = paths_pool.get_or_random_path(&self.dht, &self.tcp_connections, node.path_id.clone(), true).await { + let path = if let Some(path) = paths_pool + .get_or_random_path(&self.dht, &self.tcp_connections, node.path_id.clone(), true) + .await + { path } else { - continue + continue; }; let temporary_sk = SecretKey::generate(&mut rng); let temporary_pk = temporary_sk.public_key(); - let inner_data_request = InnerOnionDataRequest::new(&SalsaBox::new(&data_pk, &temporary_sk), friend.real_pk.clone(), temporary_pk, nonce, &payload); - - self.send_onion_request(path, InnerOnionRequest::InnerOnionDataRequest(inner_data_request), node.saddr).await?; + let inner_data_request = InnerOnionDataRequest::new( + &SalsaBox::new(&data_pk, &temporary_sk), + friend.real_pk.clone(), + temporary_pk, + nonce, + &payload, + ); + + self.send_onion_request( + path, + InnerOnionRequest::InnerOnionDataRequest(inner_data_request), + node.saddr, + ) + .await?; packets_sent = true; } @@ -834,14 +941,14 @@ impl OnionClient { let dht_pk_announce = DhtPkAnnounce::new( &SalsaBox::new(&friend.real_pk, &self.real_sk), self.real_pk.clone(), - &dht_pk_announce_payload + &dht_pk_announce_payload, ); let payload = DhtRequestPayload::DhtPkAnnounce(dht_pk_announce); let packet = DhtRequest::new( &SalsaBox::new(&friend_dht_pk, &self.dht.sk), friend_dht_pk.clone(), self.dht.pk.clone(), - &payload + &payload, ); let packet = Packet::DhtRequest(packet); @@ -851,7 +958,8 @@ impl OnionClient { friend.last_dht_pk_dht_sent = Some(clock_now()); } - let packets = nodes.iter() + let packets = nodes + .iter() .map(|node| (packet.clone(), node.saddr)) .collect::>(); @@ -879,31 +987,42 @@ impl OnionClient { } else { let backoff_interval = friend.last_seen.map_or_else( || ONION_FRIEND_MAX_PING_INTERVAL, - |last_seen| clock_elapsed(last_seen) / ONION_FRIEND_BACKOFF_FACTOR + |last_seen| clock_elapsed(last_seen) / ONION_FRIEND_BACKOFF_FACTOR, ); backoff_interval .min(ONION_FRIEND_MAX_PING_INTERVAL) .max(ANNOUNCE_FRIEND) }; - let packets_sent = self.ping_close_nodes( - &mut friend.close_nodes, - &mut state.paths_pool, - &mut state.announce_requests, - announce_packet_data, - Some(friend.real_pk.clone()), - Some(interval), - ).await.map_err(RunError::SendTo)?; + let packets_sent = self + .ping_close_nodes( + &mut friend.close_nodes, + &mut state.paths_pool, + &mut state.announce_requests, + announce_packet_data, + Some(friend.real_pk.clone()), + Some(interval), + ) + .await + .map_err(RunError::SendTo)?; if packets_sent { friend.search_count = friend.search_count.saturating_add(1); } - if friend.last_dht_pk_onion_sent.map_or(true, |time| clock_elapsed(time) > ONION_DHTPK_SEND_INTERVAL) { - self.send_dht_pk_onion(friend, &mut state.paths_pool).await.map_err(RunError::SendTo)?; + if friend + .last_dht_pk_onion_sent + .map_or(true, |time| clock_elapsed(time) > ONION_DHTPK_SEND_INTERVAL) + { + self.send_dht_pk_onion(friend, &mut state.paths_pool) + .await + .map_err(RunError::SendTo)?; } - if friend.last_dht_pk_dht_sent.map_or(true, |time| clock_elapsed(time) > DHT_DHTPK_SEND_INTERVAL) { + if friend + .last_dht_pk_dht_sent + .map_or(true, |time| clock_elapsed(time) > DHT_DHTPK_SEND_INTERVAL) + { self.send_dht_pk_dht_request(friend).await.map_err(RunError::SendTo)?; } } @@ -940,8 +1059,11 @@ impl OnionClient { #[cfg(test)] mod tests { use super::*; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; use tox_binary_io::*; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; impl OnionClient { pub async fn has_friend(&self, pk: &PublicKey) -> bool { @@ -949,16 +1071,32 @@ mod tests { } pub async fn friend_dht_pk(&self, pk: &PublicKey) -> Option { - self.state.lock().await.friends.get(pk).and_then(|friend| friend.dht_pk.clone()) + self.state + .lock() + .await + .friends + .get(pk) + .and_then(|friend| friend.dht_pk.clone()) } pub async fn is_friend_connected(&self, pk: &PublicKey) -> bool { - self.state.lock().await.friends.get(pk).map_or(false, |friend| friend.connected) + self.state + .lock() + .await + .friends + .get(pk) + .map_or(false, |friend| friend.connected) } } - fn unpack_onion_packet(packet: OnionRequest0, saddr: SocketAddr, key_by_addr: &HashMap) -> OnionRequest2Payload { - let payload = packet.get_payload(&SalsaBox::new(&packet.temporary_pk, &key_by_addr[&saddr])).unwrap(); + fn unpack_onion_packet( + packet: OnionRequest0, + saddr: SocketAddr, + key_by_addr: &HashMap, + ) -> OnionRequest2Payload { + let payload = packet + .get_payload(&SalsaBox::new(&packet.temporary_pk, &key_by_addr[&saddr])) + .unwrap(); let packet = OnionRequest1 { nonce: packet.nonce, temporary_pk: payload.temporary_pk, @@ -966,9 +1104,14 @@ mod tests { onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], payload: vec![42; 123], - } + }, }; - let payload = packet.get_payload(&SalsaBox::new(&packet.temporary_pk, &key_by_addr[&payload.ip_port.to_saddr()])).unwrap(); + let payload = packet + .get_payload(&SalsaBox::new( + &packet.temporary_pk, + &key_by_addr[&payload.ip_port.to_saddr()], + )) + .unwrap(); let packet = OnionRequest2 { nonce: packet.nonce, temporary_pk: payload.temporary_pk, @@ -976,9 +1119,14 @@ mod tests { onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], payload: vec![42; 123], - } + }, }; - packet.get_payload(&SalsaBox::new(&packet.temporary_pk, &key_by_addr[&payload.ip_port.to_saddr()])).unwrap() + packet + .get_payload(&SalsaBox::new( + &packet.temporary_pk, + &key_by_addr[&payload.ip_port.to_saddr()], + )) + .unwrap() } #[test] @@ -1041,10 +1189,10 @@ mod tests { let saddr = "127.0.0.1:12346".parse().unwrap(); let path_id = OnionPathId { keys: [ - SecretKey::generate(&mut rng).public_key(), - SecretKey::generate(&mut rng).public_key(), - SecretKey::generate(&mut rng).public_key(), - ], + SecretKey::generate(&mut rng).public_key(), + SecretKey::generate(&mut rng).public_key(), + SecretKey::generate(&mut rng).public_key(), + ], path_type: OnionPathType::Udp, }; let ping_id = [42; 32]; @@ -1126,7 +1274,10 @@ mod tests { let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let onion_client = OnionClient::new(dht, tcp_connections, real_sk, real_pk); - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); onion_client.add_path_node(node.clone()).await; let state = onion_client.state.lock().await; @@ -1206,7 +1357,9 @@ mod tests { onion_client.add_friend(friend_pk.clone()).await; let friend_dht_pk = SecretKey::generate(&mut rng).public_key(); - onion_client.set_friend_dht_pk(friend_pk.clone(), friend_dht_pk.clone()).await; + onion_client + .set_friend_dht_pk(friend_pk.clone(), friend_dht_pk.clone()) + .await; let state = onion_client.state.lock().await; assert_eq!(state.friends[&friend_pk].dht_pk, Some(friend_dht_pk)); @@ -1223,7 +1376,11 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let onion_client = OnionClient::new(dht, tcp_connections, real_sk, real_pk.clone()); @@ -1232,7 +1389,7 @@ mod tests { // map needed to decrypt onion packets later let mut key_by_addr = HashMap::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -1266,7 +1423,7 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Announced, ping_id_or_pk: ping_id, - nodes: vec![node] + nodes: vec![node], }; let packet = OnionAnnounceResponse::new(&SalsaBox::new(&real_pk, &sender_sk), request_id, &payload); @@ -1315,7 +1472,7 @@ mod tests { state.friends.insert(friend_pk.clone(), friend); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let pk = SecretKey::generate(&mut rng).public_key(); let node = PackedNode::new(saddr, pk); @@ -1342,11 +1499,15 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Announced, ping_id_or_pk: [42; 32], - nodes: vec![node] + nodes: vec![node], }; let packet = OnionAnnounceResponse::new(&SalsaBox::new(&friend_temporary_pk, &sender_sk), request_id, &payload); - let error = onion_client.handle_announce_response(&packet, true).await.err().unwrap(); + let error = onion_client + .handle_announce_response(&packet, true) + .await + .err() + .unwrap(); assert_eq!(error, HandleAnnounceResponseError::InvalidAnnounceStatus); } @@ -1366,7 +1527,7 @@ mod tests { let mut state = onion_client.state.lock().await; let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let pk = SecretKey::generate(&mut rng).public_key(); let node = PackedNode::new(saddr, pk); @@ -1402,7 +1563,7 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Announced, ping_id_or_pk: [42; 32], - nodes: vec![node] + nodes: vec![node], }; let packet = OnionAnnounceResponse::new(&SalsaBox::new(&real_pk, &sender_sk), request_id, &payload); @@ -1425,7 +1586,11 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let onion_client = OnionClient::new(dht, tcp_connections, real_sk.clone(), real_pk.clone()); @@ -1439,7 +1604,7 @@ mod tests { // map needed to decrypt onion packets later let mut key_by_addr = HashMap::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -1473,7 +1638,7 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Found, ping_id_or_pk: *friend_data_pk.as_bytes(), - nodes: vec![node] + nodes: vec![node], }; let packet = OnionAnnounceResponse::new(&SalsaBox::new(&friend_temporary_pk, &sender_sk), request_id, &payload); @@ -1482,7 +1647,10 @@ mod tests { let state = onion_client.state.lock().await; // The sender should be added to close nodes - let onion_node = state.friends[&friend_pk].close_nodes.get_node(&real_pk, &sender_pk).unwrap(); + let onion_node = state.friends[&friend_pk] + .close_nodes + .get_node(&real_pk, &sender_pk) + .unwrap(); assert_eq!(onion_node.path_id, path.id()); assert_eq!(onion_node.ping_id, None); assert_eq!(onion_node.data_pk, Some(friend_data_pk)); @@ -1495,7 +1663,9 @@ mod tests { let packet = unpack!(packet, Packet::OnionRequest0); let payload = unpack_onion_packet(packet, addr_to_send, &key_by_addr); let packet = unpack!(payload.inner, InnerOnionRequest::InnerOnionAnnounceRequest); - let payload = packet.get_payload(&SalsaBox::new(&friend_temporary_pk, &node_sk)).unwrap(); + let payload = packet + .get_payload(&SalsaBox::new(&friend_temporary_pk, &node_sk)) + .unwrap(); assert_eq!(payload.ping_id, INITIAL_PING_ID); assert_eq!(payload.search_pk, friend_pk); assert_eq!(payload.data_pk, PublicKey::from([0; 32])); @@ -1517,7 +1687,7 @@ mod tests { let mut state = onion_client.state.lock().await; let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let pk = SecretKey::generate(&mut rng).public_key(); let node = PackedNode::new(saddr, pk); @@ -1545,11 +1715,15 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Found, ping_id_or_pk: *friend_data_pk.as_bytes(), - nodes: vec![node] + nodes: vec![node], }; let packet = OnionAnnounceResponse::new(&SalsaBox::new(&real_pk, &sender_sk), request_id, &payload); - let error = onion_client.handle_announce_response(&packet, true).await.err().unwrap(); + let error = onion_client + .handle_announce_response(&packet, true) + .await + .err() + .unwrap(); assert_eq!(error, HandleAnnounceResponseError::InvalidAnnounceStatus); } @@ -1595,11 +1769,15 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Found, ping_id_or_pk: *friend_data_pk.as_bytes(), - nodes: vec![] + nodes: vec![], }; let packet = OnionAnnounceResponse::new(&SalsaBox::new(&friend_temporary_pk, &sender_sk), request_id, &payload); - let error = onion_client.handle_announce_response(&packet, true).await.err().unwrap(); + let error = onion_client + .handle_announce_response(&packet, true) + .await + .err() + .unwrap(); assert_eq!(error, HandleAnnounceResponseError::NoFriendWithPk); } @@ -1648,8 +1826,15 @@ mod tests { payload: vec![42; 123], }; - let error = onion_client.handle_announce_response(&packet, true).await.err().unwrap(); - assert_eq!(error, HandleAnnounceResponseError::InvalidPayload(GetPayloadError::Decrypt)); + let error = onion_client + .handle_announce_response(&packet, true) + .await + .err() + .unwrap(); + assert_eq!( + error, + HandleAnnounceResponseError::InvalidPayload(GetPayloadError::Decrypt) + ); } #[tokio::test] @@ -1673,7 +1858,7 @@ mod tests { state.friends.insert(friend_pk.clone(), friend); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let pk = SecretKey::generate(&mut rng).public_key(); let node = PackedNode::new(saddr, pk); @@ -1711,7 +1896,7 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Found, ping_id_or_pk: *friend_data_pk.as_bytes(), - nodes: vec![node] + nodes: vec![node], }; let packet = OnionAnnounceResponse::new(&SalsaBox::new(&friend_temporary_pk, &sender_sk), request_id, &payload); @@ -1748,23 +1933,34 @@ mod tests { let saddr: SocketAddr = "127.0.0.1:12345".parse().unwrap(); let node_sk = SecretKey::generate(&mut rng); let node_pk = node_sk.public_key(); - let dht_pk_announce_payload = DhtPkAnnouncePayload::new(friend_dht_pk.clone(), vec![ - TcpUdpPackedNode { + let dht_pk_announce_payload = DhtPkAnnouncePayload::new( + friend_dht_pk.clone(), + vec![TcpUdpPackedNode { ip_port: IpPort { protocol: ProtocolType::Udp, ip_addr: saddr.ip(), port: saddr.port(), }, pk: node_pk, - }, - ]); + }], + ); let no_reply = dht_pk_announce_payload.no_reply; let onion_data_response_inner_payload = OnionDataResponseInnerPayload::DhtPkAnnounce(dht_pk_announce_payload); let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()).into(); - let onion_data_response_payload = OnionDataResponsePayload::new(&SalsaBox::new(&real_pk, &friend_real_sk), friend_real_pk.clone(), &nonce, &onion_data_response_inner_payload); + let onion_data_response_payload = OnionDataResponsePayload::new( + &SalsaBox::new(&real_pk, &friend_real_sk), + friend_real_pk.clone(), + &nonce, + &onion_data_response_inner_payload, + ); let temporary_sk = SecretKey::generate(&mut rng); let temporary_pk = temporary_sk.public_key(); - let onion_data_response = OnionDataResponse::new(&SalsaBox::new(&onion_client.data_pk, &temporary_sk), temporary_pk, nonce, &onion_data_response_payload); + let onion_data_response = OnionDataResponse::new( + &SalsaBox::new(&onion_client.data_pk, &temporary_sk), + temporary_pk, + nonce, + &onion_data_response_payload, + ); onion_client.handle_data_response(&onion_data_response).await.unwrap(); @@ -1815,23 +2011,34 @@ mod tests { onion_client.add_friend(friend_real_pk.clone()).await; let node_pk = SecretKey::generate(&mut rng).public_key(); - let dht_pk_announce_payload = DhtPkAnnouncePayload::new(friend_dht_pk.clone(), vec![ - TcpUdpPackedNode { + let dht_pk_announce_payload = DhtPkAnnouncePayload::new( + friend_dht_pk.clone(), + vec![TcpUdpPackedNode { ip_port: IpPort { protocol: ProtocolType::Tcp, ip_addr: "127.0.0.2".parse().unwrap(), port: 12346, }, pk: node_pk.clone(), - }, - ]); + }], + ); let no_reply = dht_pk_announce_payload.no_reply; let onion_data_response_inner_payload = OnionDataResponseInnerPayload::DhtPkAnnounce(dht_pk_announce_payload); let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()).into(); - let onion_data_response_payload = OnionDataResponsePayload::new(&SalsaBox::new(&real_pk, &friend_real_sk), friend_real_pk.clone(), &nonce, &onion_data_response_inner_payload); + let onion_data_response_payload = OnionDataResponsePayload::new( + &SalsaBox::new(&real_pk, &friend_real_sk), + friend_real_pk.clone(), + &nonce, + &onion_data_response_inner_payload, + ); let temporary_sk = SecretKey::generate(&mut rng); let temporary_pk = temporary_sk.public_key(); - let onion_data_response = OnionDataResponse::new(&SalsaBox::new(&onion_client.data_pk, &temporary_sk), temporary_pk, nonce, &onion_data_response_payload); + let onion_data_response = OnionDataResponse::new( + &SalsaBox::new(&onion_client.data_pk, &temporary_sk), + temporary_pk, + nonce, + &onion_data_response_payload, + ); onion_client.handle_data_response(&onion_data_response).await.unwrap(); @@ -1866,13 +2073,28 @@ mod tests { let dht_pk_announce_payload = DhtPkAnnouncePayload::new(friend_dht_pk, vec![]); let onion_data_response_inner_payload = OnionDataResponseInnerPayload::DhtPkAnnounce(dht_pk_announce_payload); let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()).into(); - let onion_data_response_payload = OnionDataResponsePayload::new(&SalsaBox::new(&real_pk, &friend_real_sk), friend_real_pk, &nonce, &onion_data_response_inner_payload); + let onion_data_response_payload = OnionDataResponsePayload::new( + &SalsaBox::new(&real_pk, &friend_real_sk), + friend_real_pk, + &nonce, + &onion_data_response_inner_payload, + ); let temporary_sk = SecretKey::generate(&mut rng); let temporary_pk = temporary_sk.public_key(); - let onion_data_response = OnionDataResponse::new(&SalsaBox::new(&onion_client.data_pk, &temporary_sk), temporary_pk, nonce, &onion_data_response_payload); + let onion_data_response = OnionDataResponse::new( + &SalsaBox::new(&onion_client.data_pk, &temporary_sk), + temporary_pk, + nonce, + &onion_data_response_payload, + ); let res = onion_client.handle_data_response(&onion_data_response).await; - assert!(matches!(res, Err(HandleDataResponseError::DhtPkAnnounce(HandleDhtPkAnnounceError::NoFriendWithPk)))); + assert!(matches!( + res, + Err(HandleDataResponseError::DhtPkAnnounce( + HandleDhtPkAnnounceError::NoFriendWithPk + )) + )); } #[tokio::test] @@ -1897,7 +2119,12 @@ mod tests { let dht_pk_announce_payload = DhtPkAnnouncePayload::new(friend_dht_pk, vec![]); let onion_data_response_inner_payload = OnionDataResponseInnerPayload::DhtPkAnnounce(dht_pk_announce_payload); let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()).into(); - let onion_data_response_payload = OnionDataResponsePayload::new(&SalsaBox::new(&real_pk, &friend_real_sk), friend_real_pk, &nonce, &onion_data_response_inner_payload); + let onion_data_response_payload = OnionDataResponsePayload::new( + &SalsaBox::new(&real_pk, &friend_real_sk), + friend_real_pk, + &nonce, + &onion_data_response_inner_payload, + ); let temporary_sk = SecretKey::generate(&mut rng); let temporary_pk = temporary_sk.public_key(); let onion_data_response = OnionDataResponse::new( @@ -1911,7 +2138,12 @@ mod tests { // second announce with the same no_reply should be rejected let res = onion_client.handle_data_response(&onion_data_response).await; - assert!(matches!(res, Err(HandleDataResponseError::DhtPkAnnounce(HandleDhtPkAnnounceError::InvalidNoReply)))); + assert!(matches!( + res, + Err(HandleDataResponseError::DhtPkAnnounce( + HandleDhtPkAnnounceError::InvalidNoReply + )) + )); } #[tokio::test] @@ -1934,7 +2166,10 @@ mod tests { }; let res = onion_client.handle_data_response(&onion_data_response).await; - assert!(matches!(res, Err(HandleDataResponseError::InvalidPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandleDataResponseError::InvalidPayload(GetPayloadError::Decrypt)) + )); } #[tokio::test] @@ -1964,7 +2199,10 @@ mod tests { ); let res = onion_client.handle_data_response(&onion_data_response).await; - assert!(matches!(res, Err(HandleDataResponseError::InvalidInnerPayload(GetPayloadError::Decrypt)))); + assert!(matches!( + res, + Err(HandleDataResponseError::InvalidInnerPayload(GetPayloadError::Decrypt)) + )); } #[tokio::test] @@ -1978,7 +2216,11 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let onion_client = OnionClient::new(dht, tcp_connections, real_sk.clone(), real_pk.clone()); @@ -1987,7 +2229,7 @@ mod tests { // map needed to decrypt onion packets later let mut key_by_addr = HashMap::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -2012,7 +2254,9 @@ mod tests { let packet = unpack!(packet, Packet::OnionRequest0); let payload = unpack_onion_packet(packet, addr_to_send, &key_by_addr); let packet = unpack!(payload.inner, InnerOnionRequest::InnerOnionAnnounceRequest); - let payload = packet.get_payload(&SalsaBox::new(&real_pk, &key_by_addr[&payload.ip_port.to_saddr()])).unwrap(); + let payload = packet + .get_payload(&SalsaBox::new(&real_pk, &key_by_addr[&payload.ip_port.to_saddr()])) + .unwrap(); assert_eq!(payload.ping_id, INITIAL_PING_ID); assert_eq!(payload.search_pk, real_pk); assert_eq!(payload.data_pk, data_pk); @@ -2030,7 +2274,11 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let onion_client = OnionClient::new(dht, tcp_connections, real_sk.clone(), real_pk.clone()); @@ -2039,7 +2287,7 @@ mod tests { // map needed to decrypt onion packets later let mut key_by_addr = HashMap::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -2052,7 +2300,7 @@ mod tests { let now = Instant::now(); let mut nodes_key_by_addr = HashMap::new(); - for i in 0 .. MAX_ONION_ANNOUNCE_NODES { + for i in 0..MAX_ONION_ANNOUNCE_NODES { let saddr = SocketAddr::new(addr, 23456 + u16::from(i)); let path = state.paths_pool.path_nodes.udp_path().unwrap(); let node_sk = SecretKey::generate(&mut rng); @@ -2093,7 +2341,12 @@ mod tests { let packet = unpack!(packet, Packet::OnionRequest0); let payload = unpack_onion_packet(packet, addr_to_send, &key_by_addr); let packet = unpack!(payload.inner, InnerOnionRequest::InnerOnionAnnounceRequest); - let payload = packet.get_payload(&SalsaBox::new(&real_pk, &nodes_key_by_addr[&payload.ip_port.to_saddr()])).unwrap(); + let payload = packet + .get_payload(&SalsaBox::new( + &real_pk, + &nodes_key_by_addr[&payload.ip_port.to_saddr()], + )) + .unwrap(); assert_eq!(payload.ping_id, ping_id); assert_eq!(payload.search_pk, real_pk); assert_eq!(payload.data_pk, data_pk); @@ -2111,7 +2364,11 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let onion_client = OnionClient::new(dht, tcp_connections, real_sk.clone(), real_pk); @@ -2125,7 +2382,7 @@ mod tests { // map needed to decrypt onion packets later let mut key_by_addr = HashMap::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -2148,7 +2405,12 @@ mod tests { let packet = unpack!(packet, Packet::OnionRequest0); let payload = unpack_onion_packet(packet, addr_to_send, &key_by_addr); let packet = unpack!(payload.inner, InnerOnionRequest::InnerOnionAnnounceRequest); - let payload = packet.get_payload(&SalsaBox::new(&friend_temporary_pk, &key_by_addr[&payload.ip_port.to_saddr()])).unwrap(); + let payload = packet + .get_payload(&SalsaBox::new( + &friend_temporary_pk, + &key_by_addr[&payload.ip_port.to_saddr()], + )) + .unwrap(); assert_eq!(payload.ping_id, INITIAL_PING_ID); assert_eq!(&payload.search_pk, &friend_pk); assert_eq!(payload.data_pk, PublicKey::from([0; 32])); @@ -2166,7 +2428,11 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let onion_client = OnionClient::new(dht, tcp_connections, real_sk.clone(), real_pk.clone()); @@ -2179,7 +2445,7 @@ mod tests { // map needed to decrypt onion packets later let mut key_by_addr = HashMap::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -2191,7 +2457,7 @@ mod tests { let now = Instant::now(); let mut nodes_key_by_addr = HashMap::new(); - for i in 0 .. MAX_ONION_FRIEND_NODES { + for i in 0..MAX_ONION_FRIEND_NODES { let saddr = SocketAddr::new(addr, 23456 + u16::from(i)); let path = state.paths_pool.path_nodes.udp_path().unwrap(); let node_sk = SecretKey::generate(&mut rng); @@ -2233,7 +2499,12 @@ mod tests { let packet = unpack!(packet, Packet::OnionRequest0); let payload = unpack_onion_packet(packet, addr_to_send, &key_by_addr); let packet = unpack!(payload.inner, InnerOnionRequest::InnerOnionAnnounceRequest); - let payload = packet.get_payload(&SalsaBox::new(&friend_temporary_pk, &nodes_key_by_addr[&payload.ip_port.to_saddr()])).unwrap(); + let payload = packet + .get_payload(&SalsaBox::new( + &friend_temporary_pk, + &nodes_key_by_addr[&payload.ip_port.to_saddr()], + )) + .unwrap(); assert_eq!(payload.ping_id, INITIAL_PING_ID); assert_eq!(&payload.search_pk, &friend_pk); assert_eq!(payload.data_pk, PublicKey::from([0; 32])); @@ -2260,7 +2531,7 @@ mod tests { friend.connected = true; let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let pk = SecretKey::generate(&mut rng).public_key(); let node = PackedNode::new(saddr, pk); @@ -2269,7 +2540,7 @@ mod tests { let now = Instant::now(); - for i in 0 .. MAX_ONION_FRIEND_NODES { + for i in 0..MAX_ONION_FRIEND_NODES { let saddr = SocketAddr::new(addr, 23456 + u16::from(i)); let path = state.paths_pool.path_nodes.udp_path().unwrap(); let node_pk = SecretKey::generate(&mut rng).public_key(); @@ -2325,7 +2596,7 @@ mod tests { // map needed to decrypt onion packets later let mut key_by_addr = HashMap::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 3 { + for i in 0..3 { let saddr = SocketAddr::new(addr, 12346 + i); let sk = SecretKey::generate(&mut rng); let pk = sk.public_key(); @@ -2339,7 +2610,7 @@ mod tests { let data_sk = SecretKey::generate(&mut rng); let data_pk = data_sk.public_key(); let mut nodes_key_by_addr = HashMap::new(); - for i in 0 .. MAX_ONION_FRIEND_NODES { + for i in 0..MAX_ONION_FRIEND_NODES { let saddr = SocketAddr::new(addr, 23456 + u16::from(i)); let path = state.paths_pool.path_nodes.udp_path().unwrap(); let node_sk = SecretKey::generate(&mut rng); @@ -2362,7 +2633,7 @@ mod tests { state.friends.insert(friend_pk.clone(), friend); - for i in 0 .. 4 { + for i in 0..4 { let saddr = SocketAddr::new(addr, 23456 + i); let node_pk = SecretKey::generate(&mut rng).public_key(); let node = PackedNode::new(saddr, node_pk); @@ -2384,9 +2655,13 @@ mod tests { let payload = unpack_onion_packet(packet, addr_to_send, &key_by_addr); let packet = unpack!(payload.inner, InnerOnionRequest::InnerOnionDataRequest); assert_eq!(&packet.destination_pk, &friend_pk); - let payload = packet.get_payload(&SalsaBox::new(&packet.temporary_pk, &data_sk)).unwrap(); + let payload = packet + .get_payload(&SalsaBox::new(&packet.temporary_pk, &data_sk)) + .unwrap(); assert_eq!(payload.real_pk, real_pk); - let payload = payload.get_payload(&packet.nonce, &SalsaBox::new(&real_pk, &friend_sk)).unwrap(); + let payload = payload + .get_payload(&packet.nonce, &SalsaBox::new(&real_pk, &friend_sk)) + .unwrap(); let payload = unpack!(payload, OnionDataResponseInnerPayload::DhtPkAnnounce); assert_eq!(&payload.dht_pk, &dht_pk); assert_eq!(payload.nodes.len(), 4); @@ -2417,7 +2692,7 @@ mod tests { state.friends.insert(friend_pk, friend); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. 8 { + for i in 0..8 { let saddr = SocketAddr::new(addr, 23456 + i); let node_pk = SecretKey::generate(&mut rng).public_key(); let node = PackedNode::new(saddr, node_pk); @@ -2476,7 +2751,11 @@ mod tests { id: request_payload.id, }; let response_packet = NodesResponse::new(&shared_secret, node_pk, &response_payload); - onion_client.dht.handle_nodes_resp(response_packet, node.saddr).await.unwrap(); + onion_client + .dht + .handle_nodes_resp(response_packet, node.saddr) + .await + .unwrap(); let mut state = onion_client.state.lock().await; @@ -2504,13 +2783,28 @@ mod tests { payload: vec![42; 123], }); - let path = OnionPath::new([ - PackedNode::new("127.0.0.1:12346".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("127.0.0.1:12347".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("127.0.0.1:12348".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - ], OnionPathType::Udp); + let path = OnionPath::new( + [ + PackedNode::new( + "127.0.0.1:12346".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "127.0.0.1:12347".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "127.0.0.1:12348".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + ], + OnionPathType::Udp, + ); let saddr = "127.0.0.1:12345".parse().unwrap(); - onion_client.send_onion_request(path, inner_onion_request, saddr).await.unwrap(); + onion_client + .send_onion_request(path, inner_onion_request, saddr) + .await + .unwrap(); let (_received, _udp_rx) = udp_rx.into_future().await; } @@ -2535,13 +2829,25 @@ mod tests { payload: vec![42; 123], }); - let path = OnionPath::new([ - PackedNode::new("127.0.0.1:12346".parse().unwrap(), relay_pk), - PackedNode::new("127.0.0.1:12347".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - PackedNode::new("127.0.0.1:12348".parse().unwrap(), SecretKey::generate(&mut rng).public_key()), - ], OnionPathType::Tcp); + let path = OnionPath::new( + [ + PackedNode::new("127.0.0.1:12346".parse().unwrap(), relay_pk), + PackedNode::new( + "127.0.0.1:12347".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + PackedNode::new( + "127.0.0.1:12348".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ), + ], + OnionPathType::Tcp, + ); let saddr = "127.0.0.1:12345".parse().unwrap(); - onion_client.send_onion_request(path, inner_onion_request, saddr).await.unwrap(); + onion_client + .send_onion_request(path, inner_onion_request, saddr) + .await + .unwrap(); let (_received, _relay_outgoing_rx) = relay_outgoing_rx.into_future().await; diff --git a/tox_core/src/onion/client/nodes_pool.rs b/tox_core/src/onion/client/nodes_pool.rs index 777d35d01..307a83dbf 100644 --- a/tox_core/src/onion/client/nodes_pool.rs +++ b/tox_core/src/onion/client/nodes_pool.rs @@ -1,10 +1,10 @@ //! Nodes pool. -use std::collections::VecDeque; use rand::{thread_rng, Rng}; +use std::collections::VecDeque; -use tox_packet::dht::packed_node::PackedNode; use crate::onion::client::onion_path::{OnionPath, OnionPathType}; +use tox_packet::dht::packed_node::PackedNode; /// Maximum number of nodes that onion can store for building random paths. const MAX_PATH_NODES: usize = 32; @@ -46,7 +46,7 @@ impl NodesPool { pub fn rand(&self) -> Option { let len = self.nodes.len(); if len > 0 { - Some(self.nodes[thread_rng().gen_range(0 .. len)].clone()) + Some(self.nodes[thread_rng().gen_range(0..len)].clone()) } else { None } @@ -128,7 +128,10 @@ mod tests { #[test] fn put() { let mut nodes_pool = NodesPool::new(); - let node = PackedNode::new("127.0.0.1:33445".parse().unwrap(), SecretKey::generate(&mut thread_rng()).public_key()); + let node = PackedNode::new( + "127.0.0.1:33445".parse().unwrap(), + SecretKey::generate(&mut thread_rng()).public_key(), + ); nodes_pool.put(node.clone()); assert_eq!(nodes_pool.nodes[0], node); } @@ -136,7 +139,10 @@ mod tests { #[test] fn put_already_exists() { let mut nodes_pool = NodesPool::new(); - let node = PackedNode::new("127.0.0.1:33445".parse().unwrap(), SecretKey::generate(&mut thread_rng()).public_key()); + let node = PackedNode::new( + "127.0.0.1:33445".parse().unwrap(), + SecretKey::generate(&mut thread_rng()).public_key(), + ); nodes_pool.put(node.clone()); nodes_pool.put(node); assert_eq!(nodes_pool.len(), 1); @@ -147,14 +153,17 @@ mod tests { let mut rng = thread_rng(); let mut nodes_pool = NodesPool::new(); let addr = "127.0.0.1".parse().unwrap(); - for i in 0 .. MAX_PATH_NODES { + for i in 0..MAX_PATH_NODES { let saddr = SocketAddr::new(addr, 33446 + i as u16); let node = PackedNode::new(saddr, SecretKey::generate(&mut rng).public_key()); nodes_pool.put(node); } assert_eq!(nodes_pool.nodes.len(), MAX_PATH_NODES); // adding one more node should evict the oldest node - let node = PackedNode::new("127.0.0.1:33445".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node = PackedNode::new( + "127.0.0.1:33445".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); nodes_pool.put(node); assert_eq!(nodes_pool.nodes.len(), MAX_PATH_NODES); } @@ -163,9 +172,15 @@ mod tests { fn rand() { let mut rng = thread_rng(); let mut nodes_pool = NodesPool::new(); - let node = PackedNode::new("127.0.0.1:33445".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node = PackedNode::new( + "127.0.0.1:33445".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); nodes_pool.put(node); - let node = PackedNode::new("127.0.0.1:33446".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node = PackedNode::new( + "127.0.0.1:33446".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); nodes_pool.put(node); assert!(nodes_pool.rand().is_some()); } diff --git a/tox_core/src/onion/client/onion_path.rs b/tox_core/src/onion/client/onion_path.rs index 606fa2122..1f4daed43 100644 --- a/tox_core/src/onion/client/onion_path.rs +++ b/tox_core/src/onion/client/onion_path.rs @@ -2,7 +2,10 @@ use std::net::SocketAddr; -use crypto_box::{SalsaBox, aead::{Aead, AeadCore}}; +use crypto_box::{ + aead::{Aead, AeadCore}, + SalsaBox, +}; use rand::thread_rng; use tox_binary_io::*; use tox_crypto::*; @@ -17,7 +20,7 @@ pub enum OnionPathType { /// The first node of onion path is a TCP relay. Tcp, /// The first node of onion path is a DHT node. - Udp + Udp, } /// Onion path is identified by 3 public keys of nodes it consists of. @@ -97,7 +100,11 @@ impl OnionPath { /// Create `OnionRequest0` packet from `InnerOnionRequest` that should be /// sent through this path. - pub fn create_udp_onion_request(&self, destination: SocketAddr, inner_onion_request: InnerOnionRequest) -> OnionRequest0 { + pub fn create_udp_onion_request( + &self, + destination: SocketAddr, + inner_onion_request: InnerOnionRequest, + ) -> OnionRequest0 { let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()); let mut buf = [0; ONION_MAX_PACKET_SIZE]; @@ -106,7 +113,10 @@ impl OnionPath { inner: inner_onion_request, }; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); - let encrypted = self.nodes[2].temporary_precomputed_key.encrypt(&nonce, &buf[..size]).unwrap(); + let encrypted = self.nodes[2] + .temporary_precomputed_key + .encrypt(&nonce, &buf[..size]) + .unwrap(); let payload = OnionRequest1Payload { ip_port: IpPort::from_udp_saddr(self.nodes[2].saddr), @@ -114,7 +124,10 @@ impl OnionPath { inner: encrypted, }; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); - let encrypted = self.nodes[1].temporary_precomputed_key.encrypt(&nonce, &buf[..size]).unwrap(); + let encrypted = self.nodes[1] + .temporary_precomputed_key + .encrypt(&nonce, &buf[..size]) + .unwrap(); let payload = OnionRequest0Payload { ip_port: IpPort::from_udp_saddr(self.nodes[1].saddr), @@ -122,18 +135,25 @@ impl OnionPath { inner: encrypted, }; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); - let encrypted = self.nodes[0].temporary_precomputed_key.encrypt(&nonce, &buf[..size]).unwrap(); + let encrypted = self.nodes[0] + .temporary_precomputed_key + .encrypt(&nonce, &buf[..size]) + .unwrap(); OnionRequest0 { nonce: nonce.into(), temporary_pk: self.nodes[0].temporary_public_key.clone(), - payload: encrypted + payload: encrypted, } } /// Create `OnionRequest` packet from `InnerOnionRequest` that should be /// sent through this path. - pub fn create_tcp_onion_request(&self, destination: SocketAddr, inner_onion_request: InnerOnionRequest) -> OnionRequest { + pub fn create_tcp_onion_request( + &self, + destination: SocketAddr, + inner_onion_request: InnerOnionRequest, + ) -> OnionRequest { let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()); let mut buf = [0; ONION_MAX_PACKET_SIZE]; @@ -142,7 +162,10 @@ impl OnionPath { inner: inner_onion_request, }; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); - let encrypted = self.nodes[2].temporary_precomputed_key.encrypt(&nonce, &buf[..size]).unwrap(); + let encrypted = self.nodes[2] + .temporary_precomputed_key + .encrypt(&nonce, &buf[..size]) + .unwrap(); let payload = OnionRequest1Payload { ip_port: IpPort::from_udp_saddr(self.nodes[2].saddr), @@ -150,7 +173,10 @@ impl OnionPath { inner: encrypted, }; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); - let encrypted = self.nodes[1].temporary_precomputed_key.encrypt(&nonce, &buf[..size]).unwrap(); + let encrypted = self.nodes[1] + .temporary_precomputed_key + .encrypt(&nonce, &buf[..size]) + .unwrap(); OnionRequest { nonce: nonce.into(), @@ -164,7 +190,10 @@ impl OnionPath { #[cfg(test)] mod tests { use super::*; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; #[test] fn onion_path_node_new() { @@ -184,15 +213,21 @@ mod tests { let pk_1 = SecretKey::generate(&mut rng).public_key(); let pk_2 = SecretKey::generate(&mut rng).public_key(); let pk_3 = SecretKey::generate(&mut rng).public_key(); - let path = OnionPath::new([ - PackedNode::new(saddr_1, pk_1.clone()), - PackedNode::new(saddr_2, pk_2.clone()), - PackedNode::new(saddr_3, pk_3.clone()), - ], OnionPathType::Udp); - assert_eq!(path.id(), OnionPathId { - keys: [pk_1, pk_2, pk_3], - path_type: OnionPathType::Udp, - }); + let path = OnionPath::new( + [ + PackedNode::new(saddr_1, pk_1.clone()), + PackedNode::new(saddr_2, pk_2.clone()), + PackedNode::new(saddr_3, pk_3.clone()), + ], + OnionPathType::Udp, + ); + assert_eq!( + path.id(), + OnionPathId { + keys: [pk_1, pk_2, pk_3], + path_type: OnionPathType::Udp, + } + ); } #[test] @@ -204,11 +239,14 @@ mod tests { let pk_1 = SecretKey::generate(&mut rng).public_key(); let pk_2 = SecretKey::generate(&mut rng).public_key(); let pk_3 = SecretKey::generate(&mut rng).public_key(); - let path = OnionPath::new([ - PackedNode::new(saddr_1, pk_1), - PackedNode::new(saddr_2, pk_2), - PackedNode::new(saddr_3, pk_3), - ], OnionPathType::Udp); + let path = OnionPath::new( + [ + PackedNode::new(saddr_1, pk_1), + PackedNode::new(saddr_2, pk_2), + PackedNode::new(saddr_3, pk_3), + ], + OnionPathType::Udp, + ); let inner_onion_request = InnerOnionRequest::InnerOnionAnnounceRequest(InnerOnionAnnounceRequest { nonce: [42; ::NonceSize::USIZE], pk: SecretKey::generate(&mut rng).public_key(), @@ -218,14 +256,22 @@ mod tests { let onion_request = path.create_udp_onion_request(destination, inner_onion_request.clone()); assert_eq!(onion_request.temporary_pk, path.nodes[0].temporary_public_key); - let payload = onion_request.get_payload(&path.nodes[0].temporary_precomputed_key).unwrap(); + let payload = onion_request + .get_payload(&path.nodes[0].temporary_precomputed_key) + .unwrap(); assert_eq!(payload.ip_port, IpPort::from_udp_saddr(saddr_2)); assert_eq!(payload.temporary_pk, path.nodes[1].temporary_public_key); - let payload = path.nodes[1].temporary_precomputed_key.decrypt((&onion_request.nonce).into(), payload.inner.as_slice()).unwrap(); + let payload = path.nodes[1] + .temporary_precomputed_key + .decrypt((&onion_request.nonce).into(), payload.inner.as_slice()) + .unwrap(); let payload = OnionRequest1Payload::from_bytes(&payload).unwrap().1; assert_eq!(payload.ip_port, IpPort::from_udp_saddr(saddr_3)); assert_eq!(payload.temporary_pk, path.nodes[2].temporary_public_key); - let payload = path.nodes[2].temporary_precomputed_key.decrypt((&onion_request.nonce).into(), payload.inner.as_slice()).unwrap(); + let payload = path.nodes[2] + .temporary_precomputed_key + .decrypt((&onion_request.nonce).into(), payload.inner.as_slice()) + .unwrap(); let payload = OnionRequest2Payload::from_bytes(&payload).unwrap().1; assert_eq!(payload.ip_port, IpPort::from_udp_saddr(destination)); assert_eq!(payload.inner, inner_onion_request); @@ -240,11 +286,14 @@ mod tests { let pk_1 = SecretKey::generate(&mut rng).public_key(); let pk_2 = SecretKey::generate(&mut rng).public_key(); let pk_3 = SecretKey::generate(&mut rng).public_key(); - let path = OnionPath::new([ - PackedNode::new(saddr_1, pk_1), - PackedNode::new(saddr_2, pk_2), - PackedNode::new(saddr_3, pk_3), - ], OnionPathType::Udp); + let path = OnionPath::new( + [ + PackedNode::new(saddr_1, pk_1), + PackedNode::new(saddr_2, pk_2), + PackedNode::new(saddr_3, pk_3), + ], + OnionPathType::Udp, + ); let inner_onion_request = InnerOnionRequest::InnerOnionAnnounceRequest(InnerOnionAnnounceRequest { nonce: [42; ::NonceSize::USIZE], pk: SecretKey::generate(&mut rng).public_key(), @@ -255,11 +304,17 @@ mod tests { assert_eq!(onion_request.temporary_pk, path.nodes[1].temporary_public_key); assert_eq!(onion_request.ip_port, IpPort::from_udp_saddr(saddr_2)); - let payload = path.nodes[1].temporary_precomputed_key.decrypt((&onion_request.nonce).into(), onion_request.payload.as_slice()).unwrap(); + let payload = path.nodes[1] + .temporary_precomputed_key + .decrypt((&onion_request.nonce).into(), onion_request.payload.as_slice()) + .unwrap(); let payload = OnionRequest1Payload::from_bytes(&payload).unwrap().1; assert_eq!(payload.ip_port, IpPort::from_udp_saddr(saddr_3)); assert_eq!(payload.temporary_pk, path.nodes[2].temporary_public_key); - let payload = path.nodes[2].temporary_precomputed_key.decrypt((&onion_request.nonce).into(), payload.inner.as_slice()).unwrap(); + let payload = path.nodes[2] + .temporary_precomputed_key + .decrypt((&onion_request.nonce).into(), payload.inner.as_slice()) + .unwrap(); let payload = OnionRequest2Payload::from_bytes(&payload).unwrap().1; assert_eq!(payload.ip_port, IpPort::from_udp_saddr(destination)); assert_eq!(payload.inner, inner_onion_request); diff --git a/tox_core/src/onion/client/paths_pool.rs b/tox_core/src/onion/client/paths_pool.rs index 63d793808..9ad1e8300 100644 --- a/tox_core/src/onion/client/paths_pool.rs +++ b/tox_core/src/onion/client/paths_pool.rs @@ -1,13 +1,13 @@ use std::time::{Duration, Instant}; -use rand::{thread_rng, Rng}; -use tox_packet::dht::packed_node::PackedNode; use crate::dht::server::Server as DhtServer; use crate::onion::client::nodes_pool::*; use crate::onion::client::onion_path::*; -use crate::time::*; use crate::onion::client::TIME_TO_STABLE; use crate::relay::client::Connections as TcpConnections; +use crate::time::*; +use rand::{thread_rng, Rng}; +use tox_packet::dht::packed_node::PackedNode; /// Onion path is considered invalid after this number of unsuccessful attempts /// to use it. @@ -74,16 +74,15 @@ impl StoredOnionPath { ONION_PATH_TIMEOUT }; - self.attempts >= ONION_PATH_MAX_NO_RESPONSE_USES && clock_elapsed(self.last_used) >= timeout || - clock_elapsed(self.creation_time) >= ONION_PATH_MAX_LIFETIME + self.attempts >= ONION_PATH_MAX_NO_RESPONSE_USES && clock_elapsed(self.last_used) >= timeout + || clock_elapsed(self.creation_time) >= ONION_PATH_MAX_LIFETIME } /// Path is considered stable after `TIME_TO_STABLE` since it was /// added to a close list if we receive responses from it. pub fn is_stable(&self) -> bool { - clock_elapsed(self.creation_time) >= TIME_TO_STABLE && - (self.attempts == 0 || - clock_elapsed(self.last_used) < ONION_PATH_TIMEOUT) + clock_elapsed(self.creation_time) >= TIME_TO_STABLE + && (self.attempts == 0 || clock_elapsed(self.last_used) < ONION_PATH_TIMEOUT) } /// Mark this path each time it was used to send request. @@ -117,7 +116,12 @@ impl PathsPool { /// Get a random onion path. Can be either one of existent paths or newly /// generated. If we are not connected to DHT the first node from this path /// will be a TCP node. - pub async fn random_path(&mut self, dht: &DhtServer, tcp_connections: &TcpConnections, friend: bool) -> Option { + pub async fn random_path( + &mut self, + dht: &DhtServer, + tcp_connections: &TcpConnections, + friend: bool, + ) -> Option { let paths = if friend { &mut self.friend_paths } else { @@ -126,7 +130,7 @@ impl PathsPool { paths.retain(|stored_path| !stored_path.is_timed_out()); - let path_number = thread_rng().gen_range(0 .. NUMBER_ONION_PATHS); + let path_number = thread_rng().gen_range(0..NUMBER_ONION_PATHS); if let Some(stored_path) = paths.get_mut(path_number) { stored_path.use_path(); return Some(stored_path.path.clone()); @@ -156,7 +160,13 @@ impl PathsPool { /// Get path by its `OnionPathId`. If there is no path with such id a new /// path will be generated. - pub async fn get_or_random_path(&mut self, dht: &DhtServer, tcp_connections: &TcpConnections, path_id: OnionPathId, friend: bool) -> Option { + pub async fn get_or_random_path( + &mut self, + dht: &DhtServer, + tcp_connections: &TcpConnections, + path_id: OnionPathId, + friend: bool, + ) -> Option { let paths = if friend { &mut self.friend_paths } else { @@ -178,11 +188,7 @@ impl PathsPool { /// Get `StoredOnionPath` by its `OnionPathId`. pub fn get_stored_path(&self, path_id: OnionPathId, friend: bool) -> Option<&StoredOnionPath> { - let paths = if friend { - &self.friend_paths - } else { - &self.self_paths - }; + let paths = if friend { &self.friend_paths } else { &self.self_paths }; paths .iter() @@ -202,7 +208,8 @@ impl PathsPool { path.update_success(); // re-add path nodes to the cache as they are still valid for node in &path.path.nodes { - self.path_nodes.put(PackedNode::new(node.saddr, node.public_key.clone())); + self.path_nodes + .put(PackedNode::new(node.saddr, node.public_key.clone())); } } } @@ -236,11 +243,23 @@ mod tests { let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let mut paths_pool = PathsPool::new(); - for _ in 0 .. NUMBER_ONION_PATHS { - let node_1 = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - let node_2 = PackedNode::new("127.0.0.1:12346".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - let node_3 = PackedNode::new("127.0.0.1:12347".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - let path = OnionPath::new([node_1.clone(), node_2.clone(), node_3.clone()], OnionPathType::Udp); + for _ in 0..NUMBER_ONION_PATHS { + let node_1 = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + let node_2 = PackedNode::new( + "127.0.0.1:12346".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + let node_3 = PackedNode::new( + "127.0.0.1:12347".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + let path = OnionPath::new( + [node_1.clone(), node_2.clone(), node_3.clone()], + OnionPathType::Udp, + ); paths_pool.path_nodes.put(node_1); paths_pool.path_nodes.put(node_2); paths_pool.path_nodes.put(node_3); @@ -248,9 +267,15 @@ mod tests { } assert_eq!(paths_pool.$paths.len(), NUMBER_ONION_PATHS); - let path = paths_pool.random_path(&dht, &tcp_connections, $friends).await.unwrap(); + let path = paths_pool + .random_path(&dht, &tcp_connections, $friends) + .await + .unwrap(); assert_eq!(paths_pool.$paths.len(), NUMBER_ONION_PATHS); - assert!(paths_pool.$paths.iter().any(|stored_path| stored_path.path.id() == path.id())); + assert!(paths_pool + .$paths + .iter() + .any(|stored_path| stored_path.path.id() == path.id())); } #[tokio::test] @@ -262,17 +287,30 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let mut paths_pool = PathsPool::new(); - for _ in 0 .. MIN_NODES_POOL_SIZE { - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + for _ in 0..MIN_NODES_POOL_SIZE { + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); paths_pool.path_nodes.put(node); } - let path = paths_pool.random_path(&dht, &tcp_connections, $friends).await.unwrap(); - for i in 0 .. 3 { - assert_eq!(path.nodes[i].public_key, paths_pool.$paths[0].path.nodes[i].public_key); + let path = paths_pool + .random_path(&dht, &tcp_connections, $friends) + .await + .unwrap(); + for i in 0..3 { + assert_eq!( + path.nodes[i].public_key, + paths_pool.$paths[0].path.nodes[i].public_key + ); } assert_eq!(path.path_type, OnionPathType::Udp); } @@ -289,14 +327,23 @@ mod tests { // add a relay that will be used as first node for onion path let (_relay_incoming_rx, _relay_outgoing_rx, relay_pk) = tcp_connections.add_client().await; let mut paths_pool = PathsPool::new(); - for _ in 0 .. MIN_NODES_POOL_SIZE { - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + for _ in 0..MIN_NODES_POOL_SIZE { + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); paths_pool.path_nodes.put(node); } - let path = paths_pool.random_path(&dht, &tcp_connections, $friends).await.unwrap(); - for i in 0 .. 3 { - assert_eq!(path.nodes[i].public_key, paths_pool.$paths[0].path.nodes[i].public_key); + let path = paths_pool + .random_path(&dht, &tcp_connections, $friends) + .await + .unwrap(); + for i in 0..3 { + assert_eq!( + path.nodes[i].public_key, + paths_pool.$paths[0].path.nodes[i].public_key + ); } assert_eq!(path.nodes[0].public_key, relay_pk); assert_eq!(path.path_type, OnionPathType::Tcp); @@ -312,17 +359,32 @@ mod tests { let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let mut paths_pool = PathsPool::new(); - let node_1 = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - let node_2 = PackedNode::new("127.0.0.1:12346".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - let node_3 = PackedNode::new("127.0.0.1:12347".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node_1 = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + let node_2 = PackedNode::new( + "127.0.0.1:12346".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + let node_3 = PackedNode::new( + "127.0.0.1:12347".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); let path = OnionPath::new([node_1, node_2, node_3], OnionPathType::Udp); paths_pool.$paths.push(StoredOnionPath::new(path.clone())); - let result_path = paths_pool.get_or_random_path(&dht, &tcp_connections, path.id(), $friends).await.unwrap(); - for i in 0 .. 3 { + let result_path = paths_pool + .get_or_random_path(&dht, &tcp_connections, path.id(), $friends) + .await + .unwrap(); + for i in 0..3 { assert_eq!(result_path.nodes[i].public_key, path.nodes[i].public_key); } - assert_eq!(paths_pool.$paths[0].attempts, ONION_PATH_MAX_NO_RESPONSE_USES / 2 + 1); + assert_eq!( + paths_pool.$paths[0].attempts, + ONION_PATH_MAX_NO_RESPONSE_USES / 2 + 1 + ); } #[tokio::test] @@ -334,11 +396,18 @@ mod tests { let (tcp_incoming_tx, _tcp_incoming_rx) = mpsc::unbounded(); let dht = DhtServer::new(udp_tx, dht_pk.clone(), dht_sk.clone()); // make DHT connected so that we will build UDP onion paths - dht.add_node(PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key())).await; + dht.add_node(PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + )) + .await; let tcp_connections = TcpConnections::new(dht_pk, dht_sk, tcp_incoming_tx); let mut paths_pool = PathsPool::new(); - for _ in 0 .. MIN_NODES_POOL_SIZE { - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + for _ in 0..MIN_NODES_POOL_SIZE { + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); paths_pool.path_nodes.put(node); } @@ -350,10 +419,16 @@ mod tests { ], path_type: OnionPathType::Udp, }; - let path = paths_pool.get_or_random_path(&dht, &tcp_connections, path_id.clone(), $friends).await.unwrap(); + let path = paths_pool + .get_or_random_path(&dht, &tcp_connections, path_id.clone(), $friends) + .await + .unwrap(); assert_ne!(path.id(), path_id); - for i in 0 .. 3 { - assert_eq!(path.nodes[i].public_key, paths_pool.$paths[0].path.nodes[i].public_key); + for i in 0..3 { + assert_eq!( + path.nodes[i].public_key, + paths_pool.$paths[0].path.nodes[i].public_key + ); } assert_eq!(path.path_type, OnionPathType::Udp); } @@ -370,8 +445,11 @@ mod tests { // add a relay that will be used as first node for onion path let (_relay_incoming_rx, _relay_outgoing_rx, relay_pk) = tcp_connections.add_client().await; let mut paths_pool = PathsPool::new(); - for _ in 0 .. MIN_NODES_POOL_SIZE { - let node = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + for _ in 0..MIN_NODES_POOL_SIZE { + let node = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); paths_pool.path_nodes.put(node); } @@ -383,10 +461,16 @@ mod tests { ], path_type: OnionPathType::Tcp, }; - let path = paths_pool.get_or_random_path(&dht, &tcp_connections, path_id.clone(), $friends).await.unwrap(); + let path = paths_pool + .get_or_random_path(&dht, &tcp_connections, path_id.clone(), $friends) + .await + .unwrap(); assert_ne!(path.id(), path_id); - for i in 0 .. 3 { - assert_eq!(path.nodes[i].public_key, paths_pool.$paths[0].path.nodes[i].public_key); + for i in 0..3 { + assert_eq!( + path.nodes[i].public_key, + paths_pool.$paths[0].path.nodes[i].public_key + ); } assert_eq!(path.nodes[0].public_key, relay_pk); assert_eq!(path.path_type, OnionPathType::Tcp); @@ -396,21 +480,33 @@ mod tests { fn get_stored_path() { let mut rng = thread_rng(); let mut paths_pool = PathsPool::new(); - let node_1 = PackedNode::new("127.0.0.1:12345".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - let node_2 = PackedNode::new("127.0.0.1:12346".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); - let node_3 = PackedNode::new("127.0.0.1:12347".parse().unwrap(), SecretKey::generate(&mut rng).public_key()); + let node_1 = PackedNode::new( + "127.0.0.1:12345".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + let node_2 = PackedNode::new( + "127.0.0.1:12346".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); + let node_3 = PackedNode::new( + "127.0.0.1:12347".parse().unwrap(), + SecretKey::generate(&mut rng).public_key(), + ); let path = OnionPath::new([node_1, node_2, node_3], OnionPathType::Udp); let path_id = path.id(); let stored_path = StoredOnionPath::new(path); paths_pool.$paths.push(stored_path.clone()); let result_path = paths_pool.get_stored_path(path_id, $friends).unwrap(); - for i in 0 .. 3 { - assert_eq!(result_path.path.nodes[i].public_key, stored_path.path.nodes[i].public_key); + for i in 0..3 { + assert_eq!( + result_path.path.nodes[i].public_key, + stored_path.path.nodes[i].public_key + ); } assert_eq!(result_path.creation_time, stored_path.creation_time); } } - } + }; } paths_pool_tests!(self_tests, false, self_paths); diff --git a/tox_core/src/onion/onion_announce.rs b/tox_core/src/onion/onion_announce.rs index 27cf61660..1a7ece06b 100644 --- a/tox_core/src/onion/onion_announce.rs +++ b/tox_core/src/onion/onion_announce.rs @@ -1,19 +1,19 @@ /*! The implementation of onion announce */ -use std::net::{IpAddr, SocketAddr}; -use std::time::{Duration, Instant, SystemTime}; -use sha2::{Digest, Sha256}; +use rand::{CryptoRng, Rng}; use sha2::digest::typenum::Unsigned; use sha2::digest::OutputSizeUser; -use rand::{CryptoRng, Rng}; +use sha2::{Digest, Sha256}; +use std::net::{IpAddr, SocketAddr}; +use std::time::{Duration, Instant, SystemTime}; use thiserror::Error; +use crate::dht::kbucket::Distance; +use crate::time::*; use tox_binary_io::*; use tox_crypto::*; -use crate::time::*; use tox_packet::onion::*; -use crate::dht::kbucket::Distance; /// Number of secret random bytes to make onion ping id unique for each node. pub const SECRET_BYTES_SIZE: usize = 32; @@ -39,9 +39,7 @@ pub const INITIAL_PING_ID: PingId = [0; ::OutputSize:: pub enum HandleDataRequestError { /// No announced node with public key. #[error("No announced node with public key")] - NoAnnouncedNode { - pk: PublicKey, - } + NoAnnouncedNode { pk: PublicKey }, } /** Entry that corresponds to announced onion node. @@ -63,19 +61,25 @@ struct OnionAnnounceEntry { /// PublicKey that should be used to encrypt data packets for announced node pub data_pk: PublicKey, /// Time when this entry was added to the list of announced nodes - pub time: Instant + pub time: Instant, } impl OnionAnnounceEntry { /// Create new `OnionAnnounceEntry` object using current unix time. - pub fn new(pk: PublicKey, ip_addr: IpAddr, port: u16, onion_return: OnionReturn, data_pk: PublicKey) -> OnionAnnounceEntry { + pub fn new( + pk: PublicKey, + ip_addr: IpAddr, + port: u16, + onion_return: OnionReturn, + data_pk: PublicKey, + ) -> OnionAnnounceEntry { OnionAnnounceEntry { pk, ip_addr, port, onion_return, data_pk, - time: clock_now() + time: clock_now(), } } @@ -91,8 +95,7 @@ impl OnionAnnounceEntry { } /// Size of serialized `OnionPingData` struct. -const ONION_PING_DATA_SIZE: usize = - SECRET_BYTES_SIZE + +const ONION_PING_DATA_SIZE: usize = SECRET_BYTES_SIZE + /* time */ 8 + crypto_box::KEY_SIZE + /* ip_type */ 1 + @@ -128,10 +131,11 @@ struct OnionPingData { /// `IpAddr` of sender pub ip_addr: IpAddr, /// Port of sender - pub port: u16 + pub port: u16, } impl ToBytes for OnionPingData { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(&self.secret_bytes) >> @@ -168,7 +172,7 @@ pub struct OnionAnnounce { /// List of announced onion nodes entries: Vec, /// Short term DHT `PublicKey` - dht_pk: PublicKey + dht_pk: PublicKey, } impl OnionAnnounce { @@ -177,7 +181,7 @@ impl OnionAnnounce { OnionAnnounce { secret_bytes: rng.gen(), entries: Vec::with_capacity(ONION_ANNOUNCE_MAX_ENTRIES), - dht_pk + dht_pk, } } @@ -194,7 +198,7 @@ impl OnionAnnounce { time, pk, ip_addr, - port + port, }; data.ping_id() } @@ -203,8 +207,14 @@ impl OnionAnnounce { fn find_in_entries(&self, pk: PublicKey) -> Option<&OnionAnnounceEntry> { match self.entries.binary_search_by(|e| self.dht_pk.distance(&e.pk, &pk)) { //TODO: use Option::filter when it's stabilized - Ok(idx) => if self.entries[idx].is_timed_out() { None } else { self.entries.get(idx) }, - Err(_) => None + Ok(idx) => { + if self.entries[idx].is_timed_out() { + None + } else { + self.entries.get(idx) + } + } + Err(_) => None, } } @@ -225,12 +235,15 @@ impl OnionAnnounce { fn add_to_entries(&mut self, entry: OnionAnnounceEntry) -> Option<&OnionAnnounceEntry> { //TODO: remove timed out entries by timer? self.entries.retain(|e| !e.is_timed_out()); - match self.entries.binary_search_by(|e| self.dht_pk.distance(&e.pk, &entry.pk)) { + match self + .entries + .binary_search_by(|e| self.dht_pk.distance(&e.pk, &entry.pk)) + { Ok(idx) => { // node with such pk already announced - just update the entry self.entries[idx].clone_from(&entry); self.entries.get(idx) - }, + } Err(idx) => { if self.entries.len() < ONION_ANNOUNCE_MAX_ENTRIES { // adding new entry does not exceed the limit - just add it @@ -270,24 +283,20 @@ impl OnionAnnounce { payload: &OnionAnnounceRequestPayload, request_pk: PublicKey, onion_return: OnionReturn, - addr: SocketAddr + addr: SocketAddr, ) -> (AnnounceStatus, [u8; 32]) { let time = SystemTime::now(); - let ping_id_1 = self.ping_id( - time, - request_pk.clone(), - addr.ip(), - addr.port() - ); - let ping_id_2 = self.ping_id( - time + PING_ID_TIMEOUT, - request_pk.clone(), - addr.ip(), - addr.port() - ); + let ping_id_1 = self.ping_id(time, request_pk.clone(), addr.ip(), addr.port()); + let ping_id_2 = self.ping_id(time + PING_ID_TIMEOUT, request_pk.clone(), addr.ip(), addr.port()); let entry_opt = if payload.ping_id == ping_id_1 || payload.ping_id == ping_id_2 { - let entry = OnionAnnounceEntry::new(request_pk.clone(), addr.ip(), addr.port(), onion_return, payload.data_pk.clone()); + let entry = OnionAnnounceEntry::new( + request_pk.clone(), + addr.ip(), + addr.port(), + onion_return, + payload.data_pk.clone(), + ); self.add_to_entries(entry) } else { self.find_in_entries(payload.search_pk.clone()) @@ -321,16 +330,19 @@ impl OnionAnnounce { to this node through its onion path. */ - pub fn handle_data_request(&self, request: OnionDataRequest) -> Result<(OnionResponse3, SocketAddr), HandleDataRequestError> { + pub fn handle_data_request( + &self, + request: OnionDataRequest, + ) -> Result<(OnionResponse3, SocketAddr), HandleDataRequestError> { if let Some(entry) = self.find_in_entries(request.inner.destination_pk.clone()) { let response_payload = OnionDataResponse { nonce: request.inner.nonce, temporary_pk: request.inner.temporary_pk, - payload: request.inner.payload + payload: request.inner.payload, }; let response = OnionResponse3 { onion_return: entry.onion_return.clone(), - payload: InnerOnionResponse::OnionDataResponse(response_payload) + payload: InnerOnionResponse::OnionDataResponse(response_payload), }; let saddr = SocketAddr::new(entry.ip_addr, entry.port); Ok((response, saddr)) @@ -344,8 +356,11 @@ impl OnionAnnounce { #[cfg(test)] mod tests { + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; use rand::thread_rng; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; use super::*; @@ -359,9 +374,9 @@ mod tests { 12345, OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; 42] + payload: vec![42; 42], }, - SecretKey::generate(&mut thread_rng()).public_key() + SecretKey::generate(&mut thread_rng()).public_key(), ); assert!(!entry.is_timed_out()); } @@ -374,9 +389,9 @@ mod tests { 12345, OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; 42] + payload: vec![42; 42], }, - SecretKey::generate(&mut thread_rng()).public_key() + SecretKey::generate(&mut thread_rng()).public_key(), ); tokio::time::pause(); @@ -445,9 +460,9 @@ mod tests { saddr.port(), OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; 42] + payload: vec![42; 42], }, - SecretKey::generate(&mut rng).public_key() + SecretKey::generate(&mut rng).public_key(), ) } @@ -528,7 +543,10 @@ mod tests { // update entry assert!(onion_announce.add_to_entries(entry_to_update.clone()).is_some()); - assert_eq!(onion_announce.find_in_entries(entry_to_update.pk.clone()), Some(&entry_to_update)); + assert_eq!( + onion_announce.find_in_entries(entry_to_update.pk.clone()), + Some(&entry_to_update) + ); // check that announce list contains all added entries for pk in pks { @@ -668,21 +686,17 @@ mod tests { ping_id: INITIAL_PING_ID, search_pk, data_pk, - sendback_data: 42 + sendback_data: 42, }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let addr = "127.0.0.1:12345".parse().unwrap(); - let (announce_status, _ping_id_or_pk) = onion_announce.handle_onion_announce_request( - &payload, - packet_pk, - onion_return, - addr - ); + let (announce_status, _ping_id_or_pk) = + onion_announce.handle_onion_announce_request(&payload, packet_pk, onion_return, addr); assert_eq!(announce_status, AnnounceStatus::Failed); } @@ -707,21 +721,17 @@ mod tests { ping_id: INITIAL_PING_ID, search_pk, data_pk, - sendback_data: 42 + sendback_data: 42, }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let addr = "127.0.0.1:12345".parse().unwrap(); - let (announce_status, ping_id_or_pk) = onion_announce.handle_onion_announce_request( - &payload, - packet_pk, - onion_return, - addr - ); + let (announce_status, ping_id_or_pk) = + onion_announce.handle_onion_announce_request(&payload, packet_pk, onion_return, addr); assert_eq!(announce_status, AnnounceStatus::Found); assert_eq!(ping_id_or_pk, *entry_data_pk.as_bytes()); @@ -750,26 +760,23 @@ mod tests { ping_id, search_pk, data_pk, - sendback_data: 42 + sendback_data: 42, }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; - let (announce_status, _ping_id_or_pk) = onion_announce.handle_onion_announce_request( - &payload, - packet_pk.clone(), - onion_return, - addr - ); + let (announce_status, _ping_id_or_pk) = + onion_announce.handle_onion_announce_request(&payload, packet_pk.clone(), onion_return, addr); assert_eq!(announce_status, AnnounceStatus::Announced); assert!(onion_announce.find_in_entries(packet_pk).is_some()); } #[test] - fn handle_announce_failed_to_find_ourselves_with_different_data_pk() { // weird case, should we remove it? + fn handle_announce_failed_to_find_ourselves_with_different_data_pk() { + // weird case, should we remove it? let mut rng = thread_rng(); let dht_pk = SecretKey::generate(&mut rng).public_key(); let data_pk = SecretKey::generate(&mut rng).public_key(); @@ -788,21 +795,17 @@ mod tests { ping_id: INITIAL_PING_ID, search_pk: packet_pk.clone(), data_pk, - sendback_data + sendback_data, }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let addr = "127.0.0.1:12345".parse().unwrap(); - let (announce_status, _ping_id_or_pk) = onion_announce.handle_onion_announce_request( - &payload, - packet_pk, - onion_return, - addr - ); + let (announce_status, _ping_id_or_pk) = + onion_announce.handle_onion_announce_request(&payload, packet_pk, onion_return, addr); assert_eq!(announce_status, AnnounceStatus::Failed); } @@ -829,29 +832,29 @@ mod tests { let payload = vec![42; 123]; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let inner = InnerOnionDataRequest { destination_pk: entry_pk, nonce, temporary_pk: temporary_pk.clone(), - payload: payload.clone() - }; - let request = OnionDataRequest { - inner, - onion_return + payload: payload.clone(), }; + let request = OnionDataRequest { inner, onion_return }; let (response, saddr) = onion_announce.handle_data_request(request).unwrap(); assert_eq!(saddr.ip(), entry_addr); assert_eq!(saddr.port(), entry_port); assert_eq!(response.onion_return, entry_onion_return); - assert_eq!(response.payload, InnerOnionResponse::OnionDataResponse(OnionDataResponse { - nonce, - temporary_pk, - payload - })); + assert_eq!( + response.payload, + InnerOnionResponse::OnionDataResponse(OnionDataResponse { + nonce, + temporary_pk, + payload + }) + ); } #[test] @@ -863,18 +866,15 @@ mod tests { let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_3_PAYLOAD_SIZE], }; let inner = InnerOnionDataRequest { destination_pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] - }; - let request = OnionDataRequest { - inner, - onion_return + payload: vec![42; 123], }; + let request = OnionDataRequest { inner, onion_return }; assert!(onion_announce.handle_data_request(request).is_err()); } diff --git a/tox_core/src/relay/client/client.rs b/tox_core/src/relay/client/client.rs index 67e6232bb..3c6d2b201 100644 --- a/tox_core/src/relay/client/client.rs +++ b/tox_core/src/relay/client/client.rs @@ -3,22 +3,22 @@ use std::net::SocketAddr; use std::sync::Arc; use std::time::Instant; -use futures::{FutureExt, TryFutureExt, StreamExt, SinkExt}; use futures::channel::mpsc; -use tokio_util::codec::Framed; +use futures::{FutureExt, SinkExt, StreamExt, TryFutureExt}; use tokio::net::TcpStream; use tokio::sync::RwLock; +use tokio_util::codec::Framed; -use tox_crypto::*; -use tox_packet::onion::InnerOnionResponse; -use crate::stats::Stats; +use crate::relay::client::errors::*; use crate::relay::codec::Codec; -use tox_packet::relay::connection_id::ConnectionId; use crate::relay::handshake::make_client_handshake; use crate::relay::links::*; -use tox_packet::relay::*; +use crate::stats::Stats; use crate::time::*; -use crate::relay::client::errors::*; +use tox_crypto::*; +use tox_packet::onion::InnerOnionResponse; +use tox_packet::relay::connection_id::ConnectionId; +use tox_packet::relay::*; /// Buffer size (in packets) for outgoing packets. This number shouldn't be high /// to minimize latency. If some relay can't take more packets we can use @@ -84,7 +84,11 @@ pub struct Client { impl Client { /// Create new `Client` object. - pub fn new(pk: PublicKey, addr: SocketAddr, incoming_tx: mpsc::UnboundedSender<(PublicKey, IncomingPacket)>) -> Client { + pub fn new( + pk: PublicKey, + addr: SocketAddr, + incoming_tx: mpsc::UnboundedSender<(PublicKey, IncomingPacket)>, + ) -> Client { Client { pk, addr, @@ -119,8 +123,7 @@ impl Client { async fn send_packet(&self, packet: Packet) -> Result<(), SendPacketError> { if let ClientStatus::Connected(ref tx) = *self.status.read().await { let mut tx = tx.clone(); - tx.send(packet).await - .map_err(SendPacketError::SendTo) + tx.send(packet).await.map_err(SendPacketError::SendTo) } else { // Attempt to send packet to TCP relay with wrong status. For // instance it can happen when we received ping request from the @@ -138,7 +141,7 @@ impl Client { let index = if let Some(index) = packet.connection_id.index() { index } else { - return Err(HandlePacketError::InvalidConnectionId) + return Err(HandlePacketError::InvalidConnectionId); }; if self.connections.read().await.contains(&packet.pk) { @@ -159,7 +162,7 @@ impl Client { let index = if let Some(index) = packet.connection_id.index() { index } else { - return Err(HandlePacketError::InvalidConnectionId) + return Err(HandlePacketError::InvalidConnectionId); }; if self.links.write().await.upgrade(index) { @@ -173,7 +176,7 @@ impl Client { let index = if let Some(index) = packet.connection_id.index() { index } else { - return Err(HandlePacketError::InvalidConnectionId) + return Err(HandlePacketError::InvalidConnectionId); }; if (*self.links.write().await).downgrade(index) { @@ -184,9 +187,11 @@ impl Client { } async fn handle_ping_request(&self, packet: &PingRequest) -> Result<(), HandlePacketError> { - self.send_packet(Packet::PongResponse( - PongResponse { ping_id: packet.ping_id } - )).await.map_err(HandlePacketError::SendPacket) + self.send_packet(Packet::PongResponse(PongResponse { + ping_id: packet.ping_id, + })) + .await + .map_err(HandlePacketError::SendPacket) } async fn handle_pong_response(&self, _packet: &PongResponse) -> Result<(), HandlePacketError> { @@ -200,32 +205,24 @@ impl Client { async fn handle_oob_receive(&self, packet: OobReceive) -> Result<(), HandlePacketError> { let mut tx = self.incoming_tx.clone(); - let msg = ( - self.pk.clone(), - IncomingPacket::Oob(packet.sender_pk, packet.data) - ); + let msg = (self.pk.clone(), IncomingPacket::Oob(packet.sender_pk, packet.data)); - tx.send(msg).await - .map_err(HandlePacketError::SendTo) + tx.send(msg).await.map_err(HandlePacketError::SendTo) } async fn handle_data(&self, packet: Data) -> Result<(), HandlePacketError> { let index = if let Some(index) = packet.connection_id.index() { index } else { - return Err(HandlePacketError::InvalidConnectionId) + return Err(HandlePacketError::InvalidConnectionId); }; let links = self.links.read().await; if let Some(link) = links.by_id(index) { let mut tx = self.incoming_tx.clone(); - let msg = ( - self.pk.clone(), - IncomingPacket::Data(link.pk.clone(), packet.data) - ); + let msg = (self.pk.clone(), IncomingPacket::Data(link.pk.clone(), packet.data)); - tx.send(msg).await - .map_err(HandlePacketError::SendTo) + tx.send(msg).await.map_err(HandlePacketError::SendTo) } else { Err(HandlePacketError::AlreadyLinked) } @@ -237,65 +234,52 @@ impl Client { async fn handle_onion_response(&self, packet: OnionResponse) -> Result<(), HandlePacketError> { let mut tx = self.incoming_tx.clone(); - let msg = ( - self.pk.clone(), - IncomingPacket::Onion(packet.payload) - ); + let msg = (self.pk.clone(), IncomingPacket::Onion(packet.payload)); - tx.send(msg).await - .map_err(HandlePacketError::SendTo) + tx.send(msg).await.map_err(HandlePacketError::SendTo) } /// Spawn a connection to this TCP relay if it is not connected already. The /// connection is spawned via `tokio::spawn` so the result future will be /// completed after first poll. - async fn spawn_inner(&self, dht_sk: SecretKey, dht_pk: PublicKey) -> Result<(), SpawnError> { // TODO: send pings periodically + async fn spawn_inner(&self, dht_sk: SecretKey, dht_pk: PublicKey) -> Result<(), SpawnError> { + // TODO: send pings periodically let relay_pk = self.pk.clone(); match *self.status.write().await { - ref mut status @ ClientStatus::Disconnected - | ref mut status @ ClientStatus::Sleeping => - *status = ClientStatus::Connecting, + ref mut status @ ClientStatus::Disconnected | ref mut status @ ClientStatus::Sleeping => { + *status = ClientStatus::Connecting + } _ => return Ok(()), } - let socket = TcpStream::connect(&self.addr).await - .map_err(SpawnError::Io)?; + let socket = TcpStream::connect(&self.addr).await.map_err(SpawnError::Io)?; - let (socket, channel) = - make_client_handshake(socket, &dht_pk, &dht_sk, &relay_pk).await - .map_err(SpawnError::Io)?; + let (socket, channel) = make_client_handshake(socket, &dht_pk, &dht_sk, &relay_pk) + .await + .map_err(SpawnError::Io)?; let stats = Stats::new(); - let secure_socket = - Framed::new(socket, Codec::new(channel, stats)); - let (mut to_server, mut from_server) = - secure_socket.split(); - let (to_server_tx, to_server_rx) = - mpsc::channel(CLIENT_CHANNEL_SIZE); + let secure_socket = Framed::new(socket, Codec::new(channel, stats)); + let (mut to_server, mut from_server) = secure_socket.split(); + let (to_server_tx, to_server_rx) = mpsc::channel(CLIENT_CHANNEL_SIZE); match *self.status.write().await { - ref mut status @ ClientStatus::Connecting => - *status = ClientStatus::Connected(to_server_tx), + ref mut status @ ClientStatus::Connecting => *status = ClientStatus::Connected(to_server_tx), _ => return Ok(()), } *self.connection_attempts.write().await = 0; *self.connected_time.write().await = Some(clock_now()); - self.send_route_requests().await - .map_err(SpawnError::SendTo)?; + self.send_route_requests().await.map_err(SpawnError::SendTo)?; let mut to_server_rx = to_server_rx.map(Ok); - let writer = to_server - .send_all(&mut to_server_rx) - .map_err(SpawnError::Encode); + let writer = to_server.send_all(&mut to_server_rx).map_err(SpawnError::Encode); let reader = async { while let Some(packet) = from_server.next().await { - let packet = packet - .map_err(SpawnError::ReadSocket)?; - self.handle_packet(packet).await - .map_err(SpawnError::HandlePacket)?; + let packet = packet.map_err(SpawnError::ReadSocket)?; + self.handle_packet(packet).await.map_err(SpawnError::HandlePacket)?; } Result::<(), SpawnError>::Ok(()) @@ -311,7 +295,7 @@ impl Client { let result = self.spawn_inner(dht_sk, dht_pk).await; match *self.status.write().await { - ClientStatus::Sleeping => { }, + ClientStatus::Sleeping => {} ref mut status => *status = ClientStatus::Disconnected, } if let Err(ref e) = result { @@ -328,18 +312,15 @@ impl Client { /// Spawn a connection to this TCP relay if it is not connected already. The /// connection is spawned via `tokio::spawn` so the result future will be /// completed after first poll. - pub async fn spawn(self, dht_sk: SecretKey, dht_pk: PublicKey) -> Result<(), SpawnError> { // TODO: send pings periodically - tokio::spawn(async move { - self.run(dht_sk, dht_pk).await - }); + pub async fn spawn(self, dht_sk: SecretKey, dht_pk: PublicKey) -> Result<(), SpawnError> { + // TODO: send pings periodically + tokio::spawn(async move { self.run(dht_sk, dht_pk).await }); Ok(()) } /// Send `RouteRequest` packet with specified `PublicKey`. async fn send_route_request(&self, pk: PublicKey) -> Result<(), SendPacketError> { - self.send_packet(Packet::RouteRequest(RouteRequest { - pk - })).await + self.send_packet(Packet::RouteRequest(RouteRequest { pk })).await } /// Send `RouteRequest` packets for all nodes we should be connected to via @@ -363,7 +344,8 @@ impl Client { self.send_packet(Packet::Data(Data { connection_id: ConnectionId::from_index(index), data, - })).await + })) + .await } else { Err(SendPacketError::NotOnline) } @@ -374,10 +356,8 @@ impl Client { /// Send `OobSend` packet to a node via relay. pub async fn send_oob(&self, destination_pk: PublicKey, data: Vec) -> Result<(), SendPacketError> { - self.send_packet(Packet::OobSend(OobSend { - destination_pk, - data, - })).await + self.send_packet(Packet::OobSend(OobSend { destination_pk, data })) + .await } /// Send `OnionRequest` packet to the relay. @@ -406,7 +386,9 @@ impl Client { links.take(index); self.send_packet(Packet::DisconnectNotification(DisconnectNotification { connection_id: ConnectionId::from_index(index), - })).await.ok(); + })) + .await + .ok(); } Ok(()) @@ -486,18 +468,25 @@ pub mod tests { use rand::thread_rng; use tox_binary_io::*; - use std::time::{Duration, Instant}; use std::io::{Error, ErrorKind}; + use std::time::{Duration, Instant}; use tokio::net::TcpListener; + use crate::relay::server::{tcp_run, tcp_run_connection, Server}; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; use tox_packet::dht::CryptoData; use tox_packet::ip_port::*; use tox_packet::onion::*; - use crate::relay::server::{Server, tcp_run, tcp_run_connection}; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; - pub async fn create_client() -> (mpsc::UnboundedReceiver<(PublicKey, IncomingPacket)>, mpsc::Receiver, Client) { + pub async fn create_client() -> ( + mpsc::UnboundedReceiver<(PublicKey, IncomingPacket)>, + mpsc::Receiver, + Client, + ) { let mut rng = thread_rng(); let relay_addr = "127.0.0.1:12345".parse().unwrap(); let relay_pk = SecretKey::generate(&mut rng).public_key(); @@ -709,9 +698,7 @@ pub mod tests { let (_incoming_rx, outgoing_rx, client) = create_client().await; let ping_id = 42; - let ping_request = Packet::PingRequest(PingRequest { - ping_id - }); + let ping_request = Packet::PingRequest(PingRequest { ping_id }); client.handle_packet(ping_request).await.unwrap(); @@ -725,9 +712,7 @@ pub mod tests { let (_incoming_rx, _outgoing_rx, client) = create_client().await; let ping_id = 42; - let pong_response = Packet::PongResponse(PongResponse { - ping_id - }); + let pong_response = Packet::PongResponse(PongResponse { ping_id }); client.handle_packet(pong_response).await.unwrap(); } @@ -868,7 +853,7 @@ pub mod tests { let payload = InnerOnionResponse::OnionDataResponse(OnionDataResponse { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] + payload: vec![42; 123], }); let onion_response = Packet::OnionResponse(OnionResponse { payload: payload.clone(), @@ -938,7 +923,11 @@ pub mod tests { }); let connection_id = 42; - client.links.write().await.insert_by_id(destination_pk.clone(), connection_id - 16); + client + .links + .write() + .await + .insert_by_id(destination_pk.clone(), connection_id - 16); let error = client.send_data(destination_pk, data.clone()).await.err().unwrap(); assert_eq!(error, SendPacketError::NotOnline); @@ -1024,7 +1013,10 @@ pub mod tests { client.remove_connection(connection_pk).await.unwrap(); - let packet = unpack!(outgoing_rx.into_future().await.0.unwrap(), Packet::DisconnectNotification); + let packet = unpack!( + outgoing_rx.into_future().await.0.unwrap(), + Packet::DisconnectNotification + ); assert_eq!(packet.connection_id, ConnectionId::from_index(index)); } @@ -1095,7 +1087,11 @@ pub mod tests { let connection_pk = SecretKey::generate(&mut rng).public_key(); let connection_id = 42; - client.links.write().await.insert_by_id(connection_pk.clone(), connection_id - 16); + client + .links + .write() + .await + .insert_by_id(connection_pk.clone(), connection_id - 16); assert!(!client.is_connection_online(connection_pk.clone()).await); @@ -1155,7 +1151,9 @@ pub mod tests { let links = client.links.read().await; if let Some(index) = links.id_by_pk(&pk) { let status = links.by_id(index).map(|link| link.status); - if status == Some(LinkStatus::Online) { return Ok(()) } + if status == Some(LinkStatus::Online) { + return Ok(()); + } } } } @@ -1171,7 +1169,8 @@ pub mod tests { let stats = Stats::new(); let server_future = async { - tcp_run(&Server::new(), listener, server_sk, stats, 2).await + tcp_run(&Server::new(), listener, server_sk, stats, 2) + .await .map_err(|e| Error::new(ErrorKind::Other, e)) }; tokio::spawn(server_future); @@ -1183,7 +1182,11 @@ pub mod tests { let client_1 = Client::new(server_pk.clone(), addr, incoming_tx_1); // connection attempts should be set to 0 after successful connection set_connection_attempts(&client_1, 3).await; - client_1.clone().spawn(client_sk_1.clone(), client_pk_1.clone()).await.unwrap(); + client_1 + .clone() + .spawn(client_sk_1.clone(), client_pk_1.clone()) + .await + .unwrap(); // run second client let client_sk_2 = SecretKey::generate(&mut rng); @@ -1258,7 +1261,8 @@ pub mod tests { let server_future = async { let (connection, _) = listener.accept().await.unwrap(); tcp_run_connection(&server, connection, server_sk, stats) - .map_err(|e| Error::new(ErrorKind::Other, e)).await + .map_err(|e| Error::new(ErrorKind::Other, e)) + .await }; // run a client with invalid server's pk @@ -1267,7 +1271,8 @@ pub mod tests { let invalid_server_pk = SecretKey::generate(&mut rng).public_key(); let (incoming_tx_1, _incoming_rx_1) = mpsc::unbounded(); let client = Client::new(invalid_server_pk, addr, incoming_tx_1); - let client_future = client.run(client_sk_1, client_pk_1) + let client_future = client + .run(client_sk_1, client_pk_1) .map_err(|e| Error::new(ErrorKind::Other, e)); let (server_res, client_res) = futures::join!(server_future, client_future); diff --git a/tox_core/src/relay/client/connections.rs b/tox_core/src/relay/client/connections.rs index 3d5a3872f..237606978 100644 --- a/tox_core/src/relay/client/connections.rs +++ b/tox_core/src/relay/client/connections.rs @@ -18,23 +18,23 @@ use std::net::SocketAddr; use std::sync::Arc; use std::time::Duration; -use futures::TryFutureExt; use futures::channel::mpsc; -use rand::{Rng, prelude::SliceRandom, thread_rng}; +use futures::TryFutureExt; +use rand::{prelude::SliceRandom, thread_rng, Rng}; +use crate::relay::client::client::*; +use crate::relay::client::errors::*; +use crate::time::*; use tox_crypto::*; use tox_packet::dht::packed_node::PackedNode; -use crate::relay::client::client::*; use tox_packet::relay::*; -use crate::time::*; -use crate::relay::client::errors::*; /// The amount of maximum connections for each friend. -const MAX_FRIEND_TCP_CONNECTIONS: usize = 6; +const MAX_FRIEND_TCP_CONNECTIONS: usize = 6; /// The amount of recommended connections for each friend. /// NOTE: Must be at most (MAX_FRIEND_TCP_CONNECTIONS / 2). -const RECOMMENDED_FRIEND_TCP_CONNECTIONS: usize = MAX_FRIEND_TCP_CONNECTIONS / 2; +const RECOMMENDED_FRIEND_TCP_CONNECTIONS: usize = MAX_FRIEND_TCP_CONNECTIONS / 2; /// How many attempts to reconnect to the relay we should make before we /// consider this relay unreachable and drop it. @@ -75,7 +75,10 @@ impl NodeConnection { } /// Get an iterator over connected relays. - fn clients<'c, 'a: 'c, 'b: 'c>(&'a self, clients: &'b HashMap) -> impl Iterator + 'c { + fn clients<'c, 'a: 'c, 'b: 'c>( + &'a self, + clients: &'b HashMap, + ) -> impl Iterator + 'c { self.connections .iter() .flat_map(move |relay_pk| clients.get(relay_pk).into_iter()) @@ -103,7 +106,11 @@ pub struct Connections { impl Connections { /// Create new TCP connections object. - pub fn new(dht_pk: PublicKey, dht_sk: SecretKey, incoming_tx: mpsc::UnboundedSender<(PublicKey, IncomingPacket)>) -> Self { + pub fn new( + dht_pk: PublicKey, + dht_sk: SecretKey, + incoming_tx: mpsc::UnboundedSender<(PublicKey, IncomingPacket)>, + ) -> Self { Connections { dht_pk, dht_sk, @@ -121,8 +128,10 @@ impl Connections { if let hash_map::Entry::Vacant(vacant) = self.clients.write().await.entry(relay_pk.clone()) { let client = Client::new(relay_pk, relay_addr, self.incoming_tx.clone()); vacant.insert(client.clone()); - client.spawn(self.dht_sk.clone(), self.dht_pk.clone()) - .map_err(ConnectionError::Spawn).await + client + .spawn(self.dht_sk.clone(), self.dht_pk.clone()) + .map_err(ConnectionError::Spawn) + .await } else { trace!("Attempt to add relay that already exists: {}", relay_addr); Ok(()) @@ -133,7 +142,12 @@ impl Connections { /// we already connected to this friend via at least /// `RECOMMENDED_FRIEND_TCP_CONNECTIONS` relays. Connection to our friend /// via this relay will be added as well. - pub async fn add_relay_connection(&self, relay_addr: SocketAddr, relay_pk: PublicKey, node_pk: PublicKey) -> Result<(), ConnectionError> { + pub async fn add_relay_connection( + &self, + relay_addr: SocketAddr, + relay_pk: PublicKey, + node_pk: PublicKey, + ) -> Result<(), ConnectionError> { let mut clients = self.clients.write().await; if let Some(client) = clients.get(&relay_pk) { self.add_connection_inner(client, node_pk).await @@ -151,12 +165,16 @@ impl Connections { } } - if online_connections_count < RECOMMENDED_FRIEND_TCP_CONNECTIONS && connections_count < MAX_FRIEND_TCP_CONNECTIONS { + if online_connections_count < RECOMMENDED_FRIEND_TCP_CONNECTIONS + && connections_count < MAX_FRIEND_TCP_CONNECTIONS + { let client = Client::new(relay_pk.clone(), relay_addr, self.incoming_tx.clone()); clients.insert(relay_pk.clone(), client.clone()); connection.connections.insert(relay_pk); client.add_connection(node_pk).await; - client.spawn(self.dht_sk.clone(), self.dht_pk.clone()).await + client + .spawn(self.dht_sk.clone(), self.dht_pk.clone()) + .await .map_err(ConnectionError::Spawn) } else { Ok(()) @@ -198,7 +216,10 @@ impl Connections { if connection.status == NodeConnectionStatus::Tcp && client.is_sleeping().await { // unsleep relay - client.clone().spawn(self.dht_sk.clone(), self.dht_pk.clone()).await + client + .clone() + .spawn(self.dht_sk.clone(), self.dht_pk.clone()) + .await .map_err(ConnectionError::Spawn)?; }; @@ -220,7 +241,9 @@ impl Connections { for c in connection.clients(&clients) { let res = c.send_data(node_pk.clone(), data.clone()).await; - if res.is_ok() { break } + if res.is_ok() { + break; + } } } @@ -229,11 +252,15 @@ impl Connections { } /// Send `OobSend` packet to a node via relay with specified `PublicKey`. - pub async fn send_oob(&self, relay_pk: PublicKey, node_pk: PublicKey, data: Vec) -> Result<(), ConnectionError> { + pub async fn send_oob( + &self, + relay_pk: PublicKey, + node_pk: PublicKey, + data: Vec, + ) -> Result<(), ConnectionError> { let clients = self.clients.read().await; if let Some(client) = clients.get(&relay_pk) { - client.send_oob(node_pk, data).await - .map_err(ConnectionError::SendTo) + client.send_oob(node_pk, data).await.map_err(ConnectionError::SendTo) } else { Err(ConnectionError::NotConnected) } @@ -243,8 +270,7 @@ impl Connections { pub async fn send_onion(&self, relay_pk: PublicKey, onion_request: OnionRequest) -> Result<(), ConnectionError> { let clients = self.clients.read().await; if let Some(client) = clients.get(&relay_pk) { - client.send_onion(onion_request).await - .map_err(ConnectionError::SendTo) + client.send_onion(onion_request).await.map_err(ConnectionError::SendTo) } else { Err(ConnectionError::NotConnected) } @@ -252,13 +278,20 @@ impl Connections { /// Change status of connection to the node. Connections module need to know /// whether connection is used to be able to put to sleep relay connections. - pub async fn set_connection_status(&self, node_pk: PublicKey, status: NodeConnectionStatus) -> Result<(), ConnectionError> { + pub async fn set_connection_status( + &self, + node_pk: PublicKey, + status: NodeConnectionStatus, + ) -> Result<(), ConnectionError> { if let Some(connection) = self.connections.write().await.get_mut(&node_pk) { if status == NodeConnectionStatus::Tcp && connection.status == NodeConnectionStatus::Udp { // unsleep clients let clients = self.clients.read().await; for client in connection.clients(&clients) { - client.clone().spawn(self.dht_sk.clone(), self.dht_pk.clone()).await + client + .clone() + .spawn(self.dht_sk.clone(), self.dht_pk.clone()) + .await .map_err(ConnectionError::Spawn)?; } }; @@ -281,7 +314,7 @@ impl Connections { if relays.is_empty() { None } else { - Some(relays[thread_rng().gen_range(0 .. relays.len())].clone()) + Some(relays[thread_rng().gen_range(0..relays.len())].clone()) } } @@ -326,7 +359,10 @@ impl Connections { if connected && client.connection_attempts().await > MAX_RECONNECTION_ATTEMPTS { to_remove.push(pk.clone()); } else { - client.clone().spawn(self.dht_sk.clone(), self.dht_pk.clone()).await + client + .clone() + .spawn(self.dht_sk.clone(), self.dht_pk.clone()) + .await .map_err(ConnectionError::Spawn)?; } } @@ -337,7 +373,8 @@ impl Connections { } // find out which relays are used right now - let used_relays = connections.values() + let used_relays = connections + .values() .filter(|connection| connection.status == NodeConnectionStatus::Tcp) .flat_map(|connection| connection.connections.iter().cloned()) .collect::>(); @@ -345,10 +382,10 @@ impl Connections { // send to sleep not used right now relays for client in clients.values() { // only connected relays have connected_time - if client.connected_time().await.map_or( - false, - |connected_time| clock_elapsed(connected_time) > TCP_CONNECTION_ANNOUNCE_TIMEOUT - ) && !used_relays.contains(&client.pk) { + if client.connected_time().await.map_or(false, |connected_time| { + clock_elapsed(connected_time) > TCP_CONNECTION_ANNOUNCE_TIMEOUT + }) && !used_relays.contains(&client.pk) + { client.sleep().await; } } @@ -394,16 +431,25 @@ impl Connections { #[cfg(test)] mod tests { use super::*; + use crate::relay::client::client::tests::*; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; use futures::StreamExt; use tox_binary_io::*; use tox_packet::dht::CryptoData; use tox_packet::ip_port::*; - use crate::relay::client::client::tests::*; use tox_packet::relay::connection_id::ConnectionId; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; impl Connections { - pub async fn add_client(&self) -> (mpsc::UnboundedReceiver<(PublicKey, IncomingPacket)>, mpsc::Receiver, PublicKey) { + pub async fn add_client( + &self, + ) -> ( + mpsc::UnboundedReceiver<(PublicKey, IncomingPacket)>, + mpsc::Receiver, + PublicKey, + ) { let (incoming_rx, outgoing_rx, client) = create_client().await; let relay_pk = client.pk.clone(); self.clients.write().await.insert(client.pk.clone(), client); @@ -465,7 +511,10 @@ mod tests { let relay_pk = SecretKey::generate(&mut rng).public_key(); let node_pk = SecretKey::generate(&mut rng).public_key(); - connections.add_relay_connection(addr, relay_pk.clone(), node_pk.clone()).await.unwrap(); + connections + .add_relay_connection(addr, relay_pk.clone(), node_pk.clone()) + .await + .unwrap(); let clients = connections.clients.read().await; let connections = connections.connections.read().await; @@ -495,7 +544,10 @@ mod tests { let node_pk = SecretKey::generate(&mut rng).public_key(); // new connection shouldn't be spawned - connections.add_relay_connection(addr, relay_pk.clone(), node_pk.clone()).await.unwrap(); + connections + .add_relay_connection(addr, relay_pk.clone(), node_pk.clone()) + .await + .unwrap(); let clients = connections.clients.read().await; let connections = connections.connections.read().await; @@ -524,7 +576,10 @@ mod tests { let node_pk = SecretKey::generate(&mut rng).public_key(); // new connection shouldn't be spawned - connections.add_connection(relay_pk.clone(), node_pk.clone()).await.unwrap(); + connections + .add_connection(relay_pk.clone(), node_pk.clone()) + .await + .unwrap(); let clients = connections.clients.read().await; let connections = connections.connections.read().await; @@ -571,7 +626,11 @@ mod tests { node_connection.connections.insert(relay_pk.clone()); connections.clients.write().await.insert(relay_pk.clone(), client); - connections.connections.write().await.insert(node_pk.clone(), node_connection); + connections + .connections + .write() + .await + .insert(node_pk.clone(), node_connection); connections.remove_connection(node_pk.clone()).await.unwrap(); @@ -620,25 +679,43 @@ mod tests { let outgoing_rx_2 = outgoing_rx_2.into_future().await.1; // make connections online - relay_1.handle_packet(Packet::RouteResponse(RouteResponse { - connection_id: ConnectionId::from_index(42), - pk: destination_pk.clone(), - })).await.unwrap(); - relay_2.handle_packet(Packet::RouteResponse(RouteResponse { - connection_id: ConnectionId::from_index(42), - pk: destination_pk.clone(), - })).await.unwrap(); - relay_1.handle_packet(Packet::ConnectNotification(ConnectNotification { - connection_id: ConnectionId::from_index(42), - })).await.unwrap(); - relay_2.handle_packet(Packet::ConnectNotification(ConnectNotification { - connection_id: ConnectionId::from_index(42), - })).await.unwrap(); - - connections.connections.write().await.insert(destination_pk.clone(), NodeConnection { - status: NodeConnectionStatus::Tcp, - connections: [relay_0.pk.clone(), relay_1.pk.clone(), relay_2.pk.clone()].iter().cloned().collect(), - }); + relay_1 + .handle_packet(Packet::RouteResponse(RouteResponse { + connection_id: ConnectionId::from_index(42), + pk: destination_pk.clone(), + })) + .await + .unwrap(); + relay_2 + .handle_packet(Packet::RouteResponse(RouteResponse { + connection_id: ConnectionId::from_index(42), + pk: destination_pk.clone(), + })) + .await + .unwrap(); + relay_1 + .handle_packet(Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(42), + })) + .await + .unwrap(); + relay_2 + .handle_packet(Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(42), + })) + .await + .unwrap(); + + connections.connections.write().await.insert( + destination_pk.clone(), + NodeConnection { + status: NodeConnectionStatus::Tcp, + connections: [relay_0.pk.clone(), relay_1.pk.clone(), relay_2.pk.clone()] + .iter() + .cloned() + .collect(), + }, + ); connections.clients.write().await.insert(relay_0.pk.clone(), relay_0); connections.clients.write().await.insert(relay_1.pk.clone(), relay_1); connections.clients.write().await.insert(relay_2.pk.clone(), relay_2); @@ -695,7 +772,10 @@ mod tests { let data = vec![42; 123]; - connections.send_oob(relay_pk, destination_pk, data.clone()).await.unwrap(); + connections + .send_oob(relay_pk, destination_pk, data.clone()) + .await + .unwrap(); let packet = unpack!(outgoing_rx.into_future().await.0.unwrap(), Packet::OobSend); @@ -783,14 +863,23 @@ mod tests { let node_pk = SecretKey::generate(&mut rng).public_key(); - connections.connections.write().await.insert(node_pk.clone(), NodeConnection { - status: NodeConnectionStatus::Tcp, - connections: HashSet::new(), - }); + connections.connections.write().await.insert( + node_pk.clone(), + NodeConnection { + status: NodeConnectionStatus::Tcp, + connections: HashSet::new(), + }, + ); - connections.set_connection_status(node_pk.clone(), NodeConnectionStatus::Udp).await.unwrap(); + connections + .set_connection_status(node_pk.clone(), NodeConnectionStatus::Udp) + .await + .unwrap(); - assert_eq!(connections.connections.read().await.get(&node_pk).unwrap().status, NodeConnectionStatus::Udp); + assert_eq!( + connections.connections.read().await.get(&node_pk).unwrap().status, + NodeConnectionStatus::Udp + ); } #[tokio::test] @@ -803,7 +892,9 @@ mod tests { let node_pk = SecretKey::generate(&mut rng).public_key(); - let res = connections.set_connection_status(node_pk, NodeConnectionStatus::Udp).await; + let res = connections + .set_connection_status(node_pk, NodeConnectionStatus::Udp) + .await; assert!(matches!(res, Err(ConnectionError::NoSuchRelay))); } @@ -892,14 +983,20 @@ mod tests { let node_pk_1 = SecretKey::generate(&mut rng).public_key(); let node_pk_2 = SecretKey::generate(&mut rng).public_key(); - connections.connections.write().await.insert(node_pk_1, NodeConnection { - status: NodeConnectionStatus::Tcp, - connections: std::iter::once(relay_pk_1.clone()).collect(), - }); - connections.connections.write().await.insert(node_pk_2, NodeConnection { - status: NodeConnectionStatus::Udp, - connections: std::iter::once(relay_pk_2.clone()).collect(), - }); + connections.connections.write().await.insert( + node_pk_1, + NodeConnection { + status: NodeConnectionStatus::Tcp, + connections: std::iter::once(relay_pk_1.clone()).collect(), + }, + ); + connections.connections.write().await.insert( + node_pk_2, + NodeConnection { + status: NodeConnectionStatus::Udp, + connections: std::iter::once(relay_pk_2.clone()).collect(), + }, + ); connections.clients.write().await.insert(relay_pk_1.clone(), relay_1); connections.clients.write().await.insert(relay_pk_2.clone(), relay_2); @@ -938,10 +1035,16 @@ mod tests { let node_pk = SecretKey::generate(&mut rng).public_key(); - connections.connections.write().await.insert(node_pk.clone(), NodeConnection { - status: NodeConnectionStatus::Tcp, - connections: [relay_pk_0.clone(), relay_pk_1.clone(), relay_pk_2.clone()].iter().cloned().collect(), - }); + connections.connections.write().await.insert( + node_pk.clone(), + NodeConnection { + status: NodeConnectionStatus::Tcp, + connections: [relay_pk_0.clone(), relay_pk_1.clone(), relay_pk_2.clone()] + .iter() + .cloned() + .collect(), + }, + ); connections.clients.write().await.insert(relay_pk_0.clone(), relay_0); connections.clients.write().await.insert(relay_pk_1.clone(), relay_1); @@ -987,10 +1090,16 @@ mod tests { relay_2.add_connection(node_pk.clone()).await; relay_3.add_connection(node_pk.clone()).await; - connections.connections.write().await.insert(node_pk, NodeConnection { - status: NodeConnectionStatus::Tcp, - connections: [relay_pk_1.clone(), relay_pk_2.clone(), relay_pk_3.clone()].iter().cloned().collect(), - }); + connections.connections.write().await.insert( + node_pk, + NodeConnection { + status: NodeConnectionStatus::Tcp, + connections: [relay_pk_1.clone(), relay_pk_2.clone(), relay_pk_3.clone()] + .iter() + .cloned() + .collect(), + }, + ); connections.clients.write().await.insert(relay_pk_0.clone(), relay_0); connections.clients.write().await.insert(relay_pk_1.clone(), relay_1); diff --git a/tox_core/src/relay/client/errors.rs b/tox_core/src/relay/client/errors.rs index 0b9fe84a1..2ef6d0936 100644 --- a/tox_core/src/relay/client/errors.rs +++ b/tox_core/src/relay/client/errors.rs @@ -1,5 +1,5 @@ -use std::io::Error as IoError; use futures::channel::mpsc::SendError; +use std::io::Error as IoError; use thiserror::Error; use crate::relay::codec::{DecodeError, EncodeError}; diff --git a/tox_core/src/relay/client/mod.rs b/tox_core/src/relay/client/mod.rs index b52f384bb..2af8d7839 100644 --- a/tox_core/src/relay/client/mod.rs +++ b/tox_core/src/relay/client/mod.rs @@ -1,11 +1,11 @@ /*! The implementation of tcp relay client. */ -mod connections; #[allow(clippy::module_inception)] mod client; +mod connections; mod errors; -pub use self::connections::*; pub use self::client::*; +pub use self::connections::*; pub use self::errors::*; diff --git a/tox_core/src/relay/codec.rs b/tox_core/src/relay/codec.rs index 0d979e962..5896a7dac 100644 --- a/tox_core/src/relay/codec.rs +++ b/tox_core/src/relay/codec.rs @@ -3,14 +3,14 @@ use std::io::Error as IoError; -use tox_binary_io::*; -use tox_packet::relay::*; use crate::relay::secure::*; use crate::stats::*; +use tox_binary_io::*; +use tox_packet::relay::*; +use bytes::{Buf, BytesMut}; +use nom::{error::ErrorKind, Err, Needed, Offset}; use thiserror::Error; -use nom::{Needed, Offset, Err, error::ErrorKind}; -use bytes::{BytesMut, Buf}; use tokio_util::codec::{Decoder, Encoder}; /// Error that can happen when decoding `Packet` from bytes @@ -47,15 +47,13 @@ pub enum DecodeError { #[error("IO error: {:?}", error)] IoError { /// IO error - error: IoError + error: IoError, }, } impl From for DecodeError { fn from(error: IoError) -> DecodeError { - DecodeError::IoError { - error - } + DecodeError::IoError { error } } } @@ -66,37 +64,32 @@ pub enum EncodeError { #[error("Serialize Packet error: {:?}", error)] SerializeError { /// Serialization error - error: GenError + error: GenError, }, /// General IO error #[error("IO error: {:?}", error)] IoError { /// IO error - error: IoError + error: IoError, }, } impl From for EncodeError { fn from(error: IoError) -> EncodeError { - EncodeError::IoError { - error - } + EncodeError::IoError { error } } } /// implements tokio-io's Decoder and Encoder to deal with Packet pub struct Codec { channel: Channel, - stats: Stats + stats: Stats, } impl Codec { /// create a new Codec with the given Channel pub fn new(channel: Channel, stats: Stats) -> Codec { - Codec { - channel, - stats - } + Codec { channel, stats } } } @@ -107,33 +100,42 @@ impl Decoder for Codec { fn decode(&mut self, buf: &mut BytesMut) -> Result, Self::Error> { // deserialize EncryptedPacket let (consumed, encrypted_packet) = match EncryptedPacket::from_bytes(buf) { - Err(Err::Incomplete(_)) => { - return Ok(None) - }, + Err(Err::Incomplete(_)) => return Ok(None), Err(Err::Error(error)) => { - return Err(DecodeError::DeserializeEncryptedError { error: error.code, buf: buf.to_vec() }) - }, + return Err(DecodeError::DeserializeEncryptedError { + error: error.code, + buf: buf.to_vec(), + }) + } Err(Err::Failure(error)) => { - return Err(DecodeError::DeserializeEncryptedError { error: error.code, buf: buf.to_vec() }) - }, - Ok((i, encrypted_packet)) => { - (buf.offset(i), encrypted_packet) + return Err(DecodeError::DeserializeEncryptedError { + error: error.code, + buf: buf.to_vec(), + }) } + Ok((i, encrypted_packet)) => (buf.offset(i), encrypted_packet), }; // decrypt payload - let decrypted_data = self.channel.decrypt(&encrypted_packet.payload) + let decrypted_data = self + .channel + .decrypt(&encrypted_packet.payload) .map_err(|()| DecodeError::DecryptError)?; // deserialize Packet match Packet::from_bytes(&decrypted_data) { - Err(Err::Incomplete(needed)) => Err(DecodeError::IncompleteDecryptedPacket { needed, packet: decrypted_data }), - Err(Err::Error(error)) => { - Err(DecodeError::DeserializeDecryptedError { error: error.code, packet: decrypted_data }) - }, - Err(Err::Failure(error)) => { - Err(DecodeError::DeserializeDecryptedError { error: error.code, packet: decrypted_data }) - }, + Err(Err::Incomplete(needed)) => Err(DecodeError::IncompleteDecryptedPacket { + needed, + packet: decrypted_data, + }), + Err(Err::Error(error)) => Err(DecodeError::DeserializeDecryptedError { + error: error.code, + packet: decrypted_data, + }), + Err(Err::Failure(error)) => Err(DecodeError::DeserializeDecryptedError { + error: error.code, + packet: decrypted_data, + }), Ok((_i, packet)) => { // Add 1 to incoming counter self.stats.counters.increase_incoming(); @@ -154,7 +156,8 @@ impl Encoder for Codec { // serialize Packet let mut packet_buf = [0; MAX_TCP_PACKET_SIZE]; - let (_, packet_size) = packet.to_bytes((&mut packet_buf, 0)) + let (_, packet_size) = packet + .to_bytes((&mut packet_buf, 0)) .map_err(|error| EncodeError::SerializeError { error })?; // encrypt it @@ -165,10 +168,11 @@ impl Encoder for Codec { // serialize EncryptedPacket to binary form let mut encrypted_packet_buf = [0; MAX_TCP_ENC_PACKET_SIZE]; - let (_, encrypted_packet_size) = encrypted_packet.to_bytes((&mut encrypted_packet_buf, 0)) - .expect("EncryptedPacket serialize failed"); // there is nothing to fail since - // serialized Packet is not longer than 2032 bytes - // and we provided 2050 bytes for EncryptedPacket + let (_, encrypted_packet_size) = encrypted_packet + .to_bytes((&mut encrypted_packet_buf, 0)) + .expect("EncryptedPacket serialize failed"); // there is nothing to fail since + // serialized Packet is not longer than 2032 bytes + // and we provided 2050 bytes for EncryptedPacket buf.extend_from_slice(&encrypted_packet_buf[..encrypted_packet_size]); Ok(()) } @@ -176,33 +180,38 @@ impl Encoder for Codec { #[cfg(test)] mod tests { - use crypto_box::{SalsaBox, SecretKey, aead::{Aead, AeadCore, generic_array::typenum::marker_traits::Unsigned}}; + use crate::relay::codec::*; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, Aead, AeadCore}, + SalsaBox, SecretKey, + }; use rand::thread_rng; use tox_packet::dht::CryptoData; - use tox_packet::onion::*; use tox_packet::ip_port::*; - use crate::relay::codec::*; + use tox_packet::onion::*; use tox_packet::relay::connection_id::ConnectionId; use std::io::ErrorKind as IoErrorKind; - use std::net::{ - IpAddr, - Ipv4Addr, - Ipv6Addr, - }; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; #[test] fn decode_error_from_io() { let error = IoError::new(IoErrorKind::Other, "io error"); let decode_error = DecodeError::from(error); - assert_eq!(unpack!(decode_error, DecodeError::IoError, error).kind(), IoErrorKind::Other); + assert_eq!( + unpack!(decode_error, DecodeError::IoError, error).kind(), + IoErrorKind::Other + ); } #[test] fn encode_error_from_io() { let error = IoError::new(IoErrorKind::Other, "io error"); let encode_error = EncodeError::from(error); - assert_eq!(unpack!(encode_error, EncodeError::IoError, error).kind(), IoErrorKind::Other); + assert_eq!( + unpack!(encode_error, EncodeError::IoError, error).kind(), + IoErrorKind::Other + ); } fn create_channels() -> (Channel, Channel) { @@ -235,15 +244,28 @@ mod tests { let mut bob_codec = Codec::new(bob_channel, stats); let test_packets = vec![ - Packet::RouteRequest( RouteRequest { pk: pk.clone() } ), - Packet::RouteResponse( RouteResponse { connection_id: ConnectionId::from_index(42), pk: pk.clone() } ), - Packet::ConnectNotification( ConnectNotification { connection_id: ConnectionId::from_index(42) } ), - Packet::DisconnectNotification( DisconnectNotification { connection_id: ConnectionId::from_index(42) } ), - Packet::PingRequest( PingRequest { ping_id: 4242 } ), - Packet::PongResponse( PongResponse { ping_id: 4242 } ), - Packet::OobSend( OobSend { destination_pk: pk.clone(), data: vec![13; 42] } ), - Packet::OobReceive( OobReceive { sender_pk: pk, data: vec![13; 24] } ), - Packet::OnionRequest( OnionRequest { + Packet::RouteRequest(RouteRequest { pk: pk.clone() }), + Packet::RouteResponse(RouteResponse { + connection_id: ConnectionId::from_index(42), + pk: pk.clone(), + }), + Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(42), + }), + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(42), + }), + Packet::PingRequest(PingRequest { ping_id: 4242 }), + Packet::PongResponse(PongResponse { ping_id: 4242 }), + Packet::OobSend(OobSend { + destination_pk: pk.clone(), + data: vec![13; 42], + }), + Packet::OobReceive(OobReceive { + sender_pk: pk, + data: vec![13; 24], + }), + Packet::OnionRequest(OnionRequest { nonce: [42; ::NonceSize::USIZE], ip_port: IpPort { protocol: ProtocolType::Tcp, @@ -251,9 +273,9 @@ mod tests { port: 12345, }, temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![13; 207] - } ), - Packet::OnionRequest( OnionRequest { + payload: vec![13; 207], + }), + Packet::OnionRequest(OnionRequest { nonce: [42; ::NonceSize::USIZE], ip_port: IpPort { protocol: ProtocolType::Tcp, @@ -261,32 +283,34 @@ mod tests { port: 54321, }, temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![13; 201] - } ), - Packet::OnionResponse( OnionResponse { + payload: vec![13; 201], + }), + Packet::OnionResponse(OnionResponse { payload: InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] - }) - } ), - Packet::OnionResponse( OnionResponse { + payload: vec![42; 123], + }), + }), + Packet::OnionResponse(OnionResponse { payload: InnerOnionResponse::OnionDataResponse(OnionDataResponse { nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] - }) - } ), - Packet::Data( Data { + payload: vec![42; 123], + }), + }), + Packet::Data(Data { connection_id: ConnectionId::from_index(42), data: DataPayload::CryptoData(CryptoData { nonce_last_bytes: 42, payload: vec![42; 123], }), - } ) + }), ]; for packet in test_packets { - alice_codec.encode(packet.clone(), &mut buf).expect("Alice should encode"); + alice_codec + .encode(packet.clone(), &mut buf) + .expect("Alice should encode"); let res = bob_codec.decode(&mut buf).unwrap().expect("Bob should decode"); assert_eq!(packet, res); @@ -327,7 +351,7 @@ mod tests { let mut mallory_codec = Codec::new(mallory_channel, stats); let mut buf = BytesMut::new(); - let packet = Packet::PingRequest( PingRequest { ping_id: 4242 } ); + let packet = Packet::PingRequest(PingRequest { ping_id: 4242 }); alice_codec.encode(packet, &mut buf).expect("Alice should encode"); // Mallory cannot decode the payload of EncryptedPacket @@ -366,9 +390,7 @@ mod tests { // packet with invalid id let precomputed_key = SalsaBox::new(&alice_pk, &bob_sk); let payload = precomputed_key.encrypt(&bob_nonce, &[0x0F][..]).unwrap(); - let packet = EncryptedPacket { - payload, - }; + let packet = EncryptedPacket { payload }; let mut packet_bytes = [0; 32]; let (_, size) = packet.to_bytes((&mut packet_bytes, 0)).unwrap(); @@ -384,13 +406,13 @@ mod tests { let mut buf = BytesMut::new(); let stats = Stats::new(); let mut alice_codec = Codec::new(alice_channel, stats); - let packet = Packet::Data( Data { + let packet = Packet::Data(Data { connection_id: ConnectionId::from_index(42), data: DataPayload::CryptoData(CryptoData { nonce_last_bytes: 42, payload: vec![42; 2030], - }) - } ); + }), + }); // Alice cannot serialize Packet because it is too long assert!(alice_codec.encode(packet, &mut buf).is_err()); diff --git a/tox_core/src/relay/handshake/codec.rs b/tox_core/src/relay/handshake/codec.rs index 4d4256793..6e4f46af9 100644 --- a/tox_core/src/relay/handshake/codec.rs +++ b/tox_core/src/relay/handshake/codec.rs @@ -1,11 +1,11 @@ /*! Codecs to deal with ClientHandshake and ServerHandshake in terms of tokio-io */ -use tox_binary_io::*; use crate::relay::handshake::packet::*; +use tox_binary_io::*; +use bytes::{Buf, BytesMut}; use nom::{Err, Offset}; -use bytes::{BytesMut, Buf}; use std::io::{Error, ErrorKind}; use tokio_util::codec::{Decoder, Encoder}; @@ -18,13 +18,9 @@ impl Decoder for ClientHandshakeCodec { fn decode(&mut self, buf: &mut BytesMut) -> Result, Self::Error> { let (consumed, handshake) = match ClientHandshake::from_bytes(buf) { - Err(Err::Incomplete(_)) => { - return Ok(None) - }, + Err(Err::Incomplete(_)) => return Ok(None), Err(_) => unreachable!("ClientHandshake cannot be deserialized with error"), - Ok((i, handshake)) => { - (buf.offset(i), handshake) - } + Ok((i, handshake)) => (buf.offset(i), handshake), }; buf.advance(consumed); Ok(Some(handshake)) @@ -36,14 +32,10 @@ impl Encoder for ClientHandshakeCodec { fn encode(&mut self, handshake: ClientHandshake, buf: &mut BytesMut) -> Result<(), Self::Error> { let mut handshake_buf = [0; CLIENT_HANDSHAKE_SIZE]; - handshake.to_bytes((&mut handshake_buf, 0)) - .map(|(handshake_buf, handshake_size)| - buf.extend_from_slice(&handshake_buf[..handshake_size]) - ) - .map_err(|e| - Error::new(ErrorKind::Other, - format!("Client handshake serialize error: {:?}", e)) - ) + handshake + .to_bytes((&mut handshake_buf, 0)) + .map(|(handshake_buf, handshake_size)| buf.extend_from_slice(&handshake_buf[..handshake_size])) + .map_err(|e| Error::new(ErrorKind::Other, format!("Client handshake serialize error: {:?}", e))) } } @@ -56,13 +48,9 @@ impl Decoder for ServerHandshakeCodec { fn decode(&mut self, buf: &mut BytesMut) -> Result, Self::Error> { let (consumed, handshake) = match ServerHandshake::from_bytes(buf) { - Err(Err::Incomplete(_)) => { - return Ok(None) - }, + Err(Err::Incomplete(_)) => return Ok(None), Err(_) => unreachable!("ServerHandshake cannot be deserialized with error"), - Ok((i, handshake)) => { - (buf.offset(i), handshake) - } + Ok((i, handshake)) => (buf.offset(i), handshake), }; buf.advance(consumed); Ok(Some(handshake)) @@ -74,14 +62,10 @@ impl Encoder for ServerHandshakeCodec { fn encode(&mut self, handshake: ServerHandshake, buf: &mut BytesMut) -> Result<(), Self::Error> { let mut handshake_buf = [0; SERVER_HANDSHAKE_SIZE]; - handshake.to_bytes((&mut handshake_buf, 0)) - .map(|(handshake_buf, handshake_size)| - buf.extend_from_slice(&handshake_buf[..handshake_size]) - ) - .map_err(|e| - Error::new(ErrorKind::Other, - format!("Server handshake serialize error: {:?}", e)) - ) + handshake + .to_bytes((&mut handshake_buf, 0)) + .map(|(handshake_buf, handshake_size)| buf.extend_from_slice(&handshake_buf[..handshake_size])) + .map_err(|e| Error::new(ErrorKind::Other, format!("Server handshake serialize error: {:?}", e))) } } @@ -89,14 +73,17 @@ impl Encoder for ServerHandshakeCodec { mod tests { use crate::relay::handshake::codec::*; use bytes::BytesMut; - use crypto_box::{SalsaBox, SecretKey, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, SecretKey, + }; use rand::thread_rng; #[test] fn client_encode_decode() { let pk = SecretKey::generate(&mut thread_rng()).public_key(); let mut buf = BytesMut::new(); - let mut codec = ClientHandshakeCodec { }; + let mut codec = ClientHandshakeCodec {}; let handshake = ClientHandshake { pk, nonce: [42; ::NonceSize::USIZE], @@ -109,7 +96,7 @@ mod tests { #[test] fn client_decode_incomplete() { let mut buf = BytesMut::new(); - let mut codec = ClientHandshakeCodec { }; + let mut codec = ClientHandshakeCodec {}; assert!(codec.decode(&mut buf).unwrap().is_none()); } #[test] @@ -121,13 +108,13 @@ mod tests { payload: vec![42; ENC_PAYLOAD_SIZE + 1], }; let mut buf = BytesMut::new(); - let mut codec = ClientHandshakeCodec { }; + let mut codec = ClientHandshakeCodec {}; assert!(codec.encode(handshake, &mut buf).is_err()); } #[test] fn server_encode_decode() { let mut buf = BytesMut::new(); - let mut codec = ServerHandshakeCodec { }; + let mut codec = ServerHandshakeCodec {}; let handshake = ServerHandshake { nonce: [42; ::NonceSize::USIZE], payload: vec![42; ENC_PAYLOAD_SIZE], @@ -139,13 +126,13 @@ mod tests { #[test] fn server_decode_incomplete() { let mut buf = BytesMut::new(); - let mut codec = ServerHandshakeCodec { }; + let mut codec = ServerHandshakeCodec {}; assert!(codec.decode(&mut buf).unwrap().is_none()); } #[test] fn server_encode_too_big() { let mut buf = BytesMut::new(); - let mut codec = ServerHandshakeCodec { }; + let mut codec = ServerHandshakeCodec {}; let handshake = ServerHandshake { nonce: [42; ::NonceSize::USIZE], payload: vec![42; ENC_PAYLOAD_SIZE + 1], diff --git a/tox_core/src/relay/handshake/mod.rs b/tox_core/src/relay/handshake/mod.rs index 60802a2b0..a187e24d7 100644 --- a/tox_core/src/relay/handshake/mod.rs +++ b/tox_core/src/relay/handshake/mod.rs @@ -3,29 +3,36 @@ handshake using [`Diagram`](https://zetok.github.io/tox-spec/#handshake-diagram) */ -pub mod packet; pub mod codec; +pub mod packet; -pub use self::packet::*; pub use self::codec::*; +pub use self::packet::*; -use crypto_box::{SalsaBox, aead::{Aead, AeadCore, Error as AeadError}}; +use crate::relay::secure; +use crypto_box::{ + aead::{Aead, AeadCore, Error as AeadError}, + SalsaBox, +}; use tox_binary_io::*; use tox_crypto::*; -use crate::relay::secure; -use futures::{self, StreamExt, SinkExt, TryFutureExt}; +use futures::{self, SinkExt, StreamExt, TryFutureExt}; use std::io::{Error, ErrorKind}; -use tokio_util::codec::Framed; use tokio::net::TcpStream; +use tokio_util::codec::Framed; /// Create a handshake from client to server -pub fn create_client_handshake(client_pk: &PublicKey, - client_sk: &SecretKey, - server_pk: &PublicKey) - -> Result<(secure::Session, SalsaBox, ClientHandshake), Error> { +pub fn create_client_handshake( + client_pk: &PublicKey, + client_sk: &SecretKey, + server_pk: &PublicKey, +) -> Result<(secure::Session, SalsaBox, ClientHandshake), Error> { let session = secure::Session::random(); - let payload = HandshakePayload { session_pk: session.pk().clone(), session_nonce: *session.nonce() }; + let payload = HandshakePayload { + session_pk: session.pk().clone(), + session_nonce: *session.nonce(), + }; let mut serialized_payload = [0; PAYLOAD_SIZE]; // HandshakePayload::to_bytes may not fail because we created buffer with enough size @@ -45,25 +52,26 @@ pub fn create_client_handshake(client_pk: &PublicKey, /// Handle received client handshake on the server side. /// Return secure::Channel, Client PK, server handshake -pub fn handle_client_handshake(server_sk: &SecretKey, - client_handshake: &ClientHandshake) - -> Result<(secure::Channel, PublicKey, ServerHandshake), Error> { +pub fn handle_client_handshake( + server_sk: &SecretKey, + client_handshake: &ClientHandshake, +) -> Result<(secure::Channel, PublicKey, ServerHandshake), Error> { let common_key = SalsaBox::new(&client_handshake.pk, server_sk); - let payload_bytes = common_key.decrypt((&client_handshake.nonce).into(), &client_handshake.payload[..]) - .map_err( - |AeadError| Error::new(ErrorKind::Other, "Failed to decrypt ClientHandshake payload") - )?; + let payload_bytes = common_key + .decrypt((&client_handshake.nonce).into(), &client_handshake.payload[..]) + .map_err(|AeadError| Error::new(ErrorKind::Other, "Failed to decrypt ClientHandshake payload"))?; let (_, payload) = HandshakePayload::from_bytes(&payload_bytes) - .map_err( - |_| Error::new(ErrorKind::Other, "Failed to deserialize ClientHandshake payload") - )?; + .map_err(|_| Error::new(ErrorKind::Other, "Failed to deserialize ClientHandshake payload"))?; let client_pk = payload.session_pk; let client_nonce = payload.session_nonce; let session = secure::Session::random(); - let server_payload = HandshakePayload { session_pk: session.pk().clone(), session_nonce: *session.nonce() }; + let server_payload = HandshakePayload { + session_pk: session.pk().clone(), + session_nonce: *session.nonce(), + }; let mut serialized_payload = [0; PAYLOAD_SIZE]; // HandshakePayload::to_bytes may not fail because we created buffer with enough size @@ -81,18 +89,16 @@ pub fn handle_client_handshake(server_sk: &SecretKey, } /// Handle received server handshake on the client side. -pub fn handle_server_handshake(common_key: &SalsaBox, - client_session: &secure::Session, - server_handshake: &ServerHandshake) - -> Result { - let payload_bytes = common_key.decrypt((&server_handshake.nonce).into(), &server_handshake.payload[..]) - .map_err( - |AeadError| Error::new(ErrorKind::Other, "Failed to decrypt ServerHandshake payload") - )?; +pub fn handle_server_handshake( + common_key: &SalsaBox, + client_session: &secure::Session, + server_handshake: &ServerHandshake, +) -> Result { + let payload_bytes = common_key + .decrypt((&server_handshake.nonce).into(), &server_handshake.payload[..]) + .map_err(|AeadError| Error::new(ErrorKind::Other, "Failed to decrypt ServerHandshake payload"))?; let (_, payload) = HandshakePayload::from_bytes(&payload_bytes) - .map_err( - |_| Error::new(ErrorKind::Other, "Failed to deserialize ServerHandshake payload") - )?; + .map_err(|_| Error::new(ErrorKind::Other, "Failed to deserialize ServerHandshake payload"))?; let server_pk = payload.session_pk; let server_nonce = payload.session_nonce; @@ -107,28 +113,21 @@ pub async fn make_client_handshake( socket: TcpStream, client_pk: &PublicKey, client_sk: &SecretKey, - server_pk: &PublicKey + server_pk: &PublicKey, ) -> Result<(TcpStream, secure::Channel), Error> { - let (session, common_key, handshake) = - create_client_handshake(client_pk, client_sk, server_pk)?; + let (session, common_key, handshake) = create_client_handshake(client_pk, client_sk, server_pk)?; let mut client = Framed::new(socket, ClientHandshakeCodec); - client.send(handshake) - .map_err(|e| { - Error::new( - ErrorKind::Other, - format!("Could not send ClientHandshake {:?}", e), - ) - }) + client + .send(handshake) + .map_err(|e| Error::new(ErrorKind::Other, format!("Could not send ClientHandshake {:?}", e))) .await?; let socket = client.into_inner(); let server = Framed::new(socket, ServerHandshakeCodec); let (handshake, server_socket) = server.into_future().await; let handshake = match handshake { - None => Err(Error::new( - ErrorKind::Other, "Option is empty" - )), + None => Err(Error::new(ErrorKind::Other, "Option is empty")), Some(Err(e)) => Err(Error::new( ErrorKind::Other, format!("Could not read ServerHandshake {:?}", e), @@ -136,23 +135,20 @@ pub async fn make_client_handshake( Some(res) => res, }?; - handle_server_handshake(&common_key, &session, &handshake) - .map(|chan| (server_socket.into_inner(), chan)) + handle_server_handshake(&common_key, &session, &handshake).map(|chan| (server_socket.into_inner(), chan)) } /// Receives handshake from the client, processes it and /// sends handshake to the client pub async fn make_server_handshake( socket: TcpStream, - server_sk: SecretKey + server_sk: SecretKey, ) -> Result<(TcpStream, secure::Channel, PublicKey), Error> { let client = Framed::new(socket, ClientHandshakeCodec); let (handshake, client) = client.into_future().await; let handshake = match handshake { - None => Err(Error::new( - ErrorKind::Other, "Option is empty" - )), + None => Err(Error::new(ErrorKind::Other, "Option is empty")), Some(Err(e)) => Err(Error::new( ErrorKind::Other, format!("Could not read ClientHandshake {:?}", e), @@ -160,18 +156,14 @@ pub async fn make_server_handshake( Some(res) => res, }?; - let (channel, client_pk, server_handshake) = - handle_client_handshake(&server_sk, &handshake)?; + let (channel, client_pk, server_handshake) = handle_client_handshake(&server_sk, &handshake)?; let socket = client.into_inner(); let mut server = Framed::new(socket, ServerHandshakeCodec); - server.send(server_handshake).await - .map_err(|e| { - Error::new( - ErrorKind::Other, - format!("Could not send ServerHandshake {:?}", e), - ) - })?; + server + .send(server_handshake) + .await + .map_err(|e| Error::new(ErrorKind::Other, format!("Could not send ServerHandshake {:?}", e)))?; let socket = server.into_inner(); Ok((socket, channel, client_pk)) @@ -181,10 +173,9 @@ pub async fn make_server_handshake( mod tests { use std::net::SocketAddr; - use rand::thread_rng; - use tox_crypto::*; - use crate::relay::*; use crate::relay::handshake::*; + use crate::relay::*; + use rand::thread_rng; fn create_channels_with_handshake() -> (secure::Channel, secure::Channel) { let mut rng = thread_rng(); @@ -194,7 +185,8 @@ mod tests { let server_pk = server_sk.public_key(); // client creates a handshake packet - let (client_session, common_key, client_handshake) = create_client_handshake(&client_pk, &client_sk, &server_pk).unwrap(); + let (client_session, common_key, client_handshake) = + create_client_handshake(&client_pk, &client_sk, &server_pk).unwrap(); assert_eq!(handshake::ENC_PAYLOAD_SIZE, client_handshake.payload.len()); // sends client_handshake via network // .. @@ -202,7 +194,8 @@ mod tests { // .. // server receives a handshake packet // handles it & creates a secure Channel - let (server_channel, received_client_pk, server_handshake) = handle_client_handshake(&server_sk, &client_handshake).unwrap(); + let (server_channel, received_client_pk, server_handshake) = + handle_client_handshake(&server_sk, &client_handshake).unwrap(); assert_eq!(received_client_pk, client_pk); // sends server_handshake via network // .. @@ -227,7 +220,10 @@ mod tests { // Alice sends it somehow // Bob receives and decrypts - assert_eq!( alice_msg.as_bytes().to_vec(), bob_channel.decrypt(alice_msg_encrypted.as_ref()).unwrap() ); + assert_eq!( + alice_msg.as_bytes().to_vec(), + bob_channel.decrypt(alice_msg_encrypted.as_ref()).unwrap() + ); // Now Bob encrypts his message let bob_msg = "Oh hello Alice!"; @@ -235,7 +231,10 @@ mod tests { assert_ne!(bob_msg.as_bytes().to_vec(), bob_msg_encrypted); // And sends it back to Alice - assert_eq!( bob_msg.as_bytes().to_vec(), alice_channel.decrypt(bob_msg_encrypted.as_ref()).unwrap() ); + assert_eq!( + bob_msg.as_bytes().to_vec(), + alice_channel.decrypt(bob_msg_encrypted.as_ref()).unwrap() + ); } #[test] fn client_handshake_with_different_keypair() { @@ -245,7 +244,8 @@ mod tests { let server_pk = SecretKey::generate(&mut rng).public_key(); let mallory_sk = SecretKey::generate(&mut rng); - let (_client_session, _common_key, client_handshake) = create_client_handshake(&client_pk, &client_sk, &server_pk).unwrap(); + let (_client_session, _common_key, client_handshake) = + create_client_handshake(&client_pk, &client_sk, &server_pk).unwrap(); assert!(handle_client_handshake(&mallory_sk, &client_handshake).is_err()); } #[test] @@ -257,8 +257,10 @@ mod tests { let server_pk = server_sk.public_key(); let mallory_sk = SecretKey::generate(&mut rng); - let (client_session, _common_key, client_handshake) = create_client_handshake(&client_pk, &client_sk, &server_pk).unwrap(); - let (_server_channel, _client_pk, server_handshake) = handle_client_handshake(&server_sk, &client_handshake).unwrap(); + let (client_session, _common_key, client_handshake) = + create_client_handshake(&client_pk, &client_sk, &server_pk).unwrap(); + let (_server_channel, _client_pk, server_handshake) = + handle_client_handshake(&server_sk, &client_handshake).unwrap(); let common_key = SalsaBox::new(&client_pk, &mallory_sk); assert!(handle_server_handshake(&common_key, &client_session, &server_handshake).is_err()); } @@ -276,7 +278,11 @@ mod tests { // bad payload [1,2,3] let encrypted_payload = common_key.encrypt(&nonce, &[1, 2, 3][..]).unwrap(); - ClientHandshake { pk: client_pk, nonce: nonce.into(), payload: encrypted_payload } + ClientHandshake { + pk: client_pk, + nonce: nonce.into(), + payload: encrypted_payload, + } }; assert!(handle_client_handshake(&server_sk, &client_handshake).is_err()); } @@ -294,7 +300,10 @@ mod tests { // bad payload [1,2,3] let server_encrypted_payload = common_key.encrypt(&nonce, &[1, 2, 3][..]).unwrap(); - ServerHandshake { nonce: nonce.into(), payload: server_encrypted_payload } + ServerHandshake { + nonce: nonce.into(), + payload: server_encrypted_payload, + } }; assert!(handle_server_handshake(&common_key, &client_session, &server_handshake).is_err()); } diff --git a/tox_core/src/relay/handshake/packet.rs b/tox_core/src/relay/handshake/packet.rs index 1aa5e882f..a3ce24fa1 100644 --- a/tox_core/src/relay/handshake/packet.rs +++ b/tox_core/src/relay/handshake/packet.rs @@ -3,9 +3,9 @@ handshake using [`diagram`](https://zetok.github.io/tox-spec/#handshake-diagram) */ +use nom::bytes::streaming::take; use tox_binary_io::*; use tox_crypto::*; -use nom::bytes::streaming::take; /** The request of the client to create a TCP handshake. @@ -29,7 +29,7 @@ pub struct ClientHandshake { pub nonce: Nonce, /// Encrypted payload according to /// [Tox spec](https://zetok.github.io/tox-spec/#handshake-request-packet-payload). - pub payload: Vec + pub payload: Vec, } /// A serialized client handshake must be equal to 32 (PK) + 24 (nonce) @@ -41,11 +41,19 @@ impl FromBytes for ClientHandshake { let (input, pk) = PublicKey::from_bytes(input)?; let (input, nonce) = Nonce::from_bytes(input)?; let (input, payload) = take(ENC_PAYLOAD_SIZE)(input)?; - Ok((input, ClientHandshake { pk, nonce, payload: payload.to_vec() })) + Ok(( + input, + ClientHandshake { + pk, + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for ClientHandshake { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.pk.as_ref()) >> @@ -74,7 +82,7 @@ pub struct ServerHandshake { pub nonce: Nonce, /// Encrypted payload according to /// [Tox spec](https://zetok.github.io/tox-spec/#handshake-response-payload). - pub payload: Vec + pub payload: Vec, } /// A serialized server handshake must be equal to 24 (nonce) @@ -85,11 +93,18 @@ impl FromBytes for ServerHandshake { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, nonce) = Nonce::from_bytes(input)?; let (input, payload) = take(ENC_PAYLOAD_SIZE)(input)?; - Ok((input, ServerHandshake { nonce, payload: payload.to_vec() })) + Ok(( + input, + ServerHandshake { + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for ServerHandshake { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.nonce.as_ref()) >> @@ -123,7 +138,7 @@ pub struct HandshakePayload { /// Temporary Session PK pub session_pk: PublicKey, /// Temporary Session Nonce - pub session_nonce: Nonce + pub session_nonce: Nonce, } /// A serialized payload must be equal to 32 (PK) + 24 (nonce) bytes @@ -136,11 +151,18 @@ impl FromBytes for HandshakePayload { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, pk) = PublicKey::from_bytes(input)?; let (input, nonce) = Nonce::from_bytes(input)?; - Ok((input, HandshakePayload { session_pk: pk, session_nonce: nonce })) + Ok(( + input, + HandshakePayload { + session_pk: pk, + session_nonce: nonce, + }, + )) } } impl ToBytes for HandshakePayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.session_pk.as_ref()) >> diff --git a/tox_core/src/relay/links.rs b/tox_core/src/relay/links.rs index a5d505a34..4db300a48 100644 --- a/tox_core/src/relay/links.rs +++ b/tox_core/src/relay/links.rs @@ -71,7 +71,7 @@ impl Links { const LINK: Option = None; Links { links: [LINK; 240], - pk_to_id: HashMap::new() + pk_to_id: HashMap::new(), } } /** Try to find a hole inside `links` and insert a new `Link` to the given PK @@ -100,7 +100,12 @@ impl Links { Return false if there is a `Link` with such PK or there is no hole at links[id] */ pub fn insert_by_id(&mut self, pk: PublicKey, index: u8) -> bool { - assert!(index < MAX_LINKS_N, "The index {} must be lower than {}", index, MAX_LINKS_N); + assert!( + index < MAX_LINKS_N, + "The index {} must be lower than {}", + index, + MAX_LINKS_N + ); if !self.pk_to_id.contains_key(&pk) && self.links[index as usize].is_none() { let link = Link::new(pk.clone()); self.links[index as usize] = Some(link); @@ -138,7 +143,12 @@ impl Links { /// Call Links::downgrade on the `Link` by id /// Return false of links[id] is None pub fn downgrade(&mut self, index: u8) -> bool { - assert!(index < MAX_LINKS_N, "The index {} must be lower than {}", index, MAX_LINKS_N); + assert!( + index < MAX_LINKS_N, + "The index {} must be lower than {}", + index, + MAX_LINKS_N + ); if let Some(ref mut link) = self.links[index as usize] { link.downgrade(); true @@ -149,7 +159,12 @@ impl Links { /// Call Links::upgrade on the `Link` by id /// Return false of links[id] is None pub fn upgrade(&mut self, index: u8) -> bool { - assert!(index < MAX_LINKS_N, "The index {} must be lower than {}", index, MAX_LINKS_N); + assert!( + index < MAX_LINKS_N, + "The index {} must be lower than {}", + index, + MAX_LINKS_N + ); if let Some(ref mut link) = self.links[index as usize] { link.upgrade(); true @@ -277,14 +292,13 @@ mod tests { let id1 = links.insert(pk1.clone()).unwrap(); - assert!(!links.insert_by_id(pk1, id1+1)); + assert!(!links.insert_by_id(pk1, id1 + 1)); assert!(!links.insert_by_id(pk2.clone(), id1)); - assert!(links.insert_by_id(pk2.clone(), id1+1)); + assert!(links.insert_by_id(pk2.clone(), id1 + 1)); - assert_eq!(links.by_id(id1+1).unwrap().pk, pk2); + assert_eq!(links.by_id(id1 + 1).unwrap().pk, pk2); } - #[test] fn links_by_id() { let mut links = Links::new(); @@ -325,7 +339,7 @@ mod tests { assert_eq!(LinkStatus::Online, links.by_id(id).unwrap().status); - assert!(!links.upgrade(id+1)); // try to upgrade an nonexistent link + assert!(!links.upgrade(id + 1)); // try to upgrade an nonexistent link } #[test] @@ -342,7 +356,7 @@ mod tests { assert_eq!(LinkStatus::Registered, links.by_id(id).unwrap().status); - assert!(!links.downgrade(id+1)); // try to downgrade an nonexistent link + assert!(!links.downgrade(id + 1)); // try to downgrade an nonexistent link } #[test] diff --git a/tox_core/src/relay/mod.rs b/tox_core/src/relay/mod.rs index 3772ade7b..565a1856b 100644 --- a/tox_core/src/relay/mod.rs +++ b/tox_core/src/relay/mod.rs @@ -2,9 +2,9 @@ */ +pub mod client; +pub mod codec; pub mod handshake; +mod links; pub mod secure; -pub mod codec; pub mod server; -pub mod client; -mod links; diff --git a/tox_core/src/relay/secure.rs b/tox_core/src/relay/secure.rs index 4e7f864af..fbbb1f73c 100644 --- a/tox_core/src/relay/secure.rs +++ b/tox_core/src/relay/secure.rs @@ -45,7 +45,10 @@ assert_eq!( bob_msg.as_bytes().to_vec(), alice_channel.decrypt(bob_msg_encrypted */ -use crypto_box::{SalsaBox, aead::{Aead, AeadCore, Error as AeadError}}; +use crypto_box::{ + aead::{Aead, AeadCore, Error as AeadError}, + SalsaBox, +}; use rand::thread_rng; use tox_crypto::*; @@ -67,7 +70,7 @@ pub struct Session { /// to establish a secure [`Channel`](./struct.Channel.html) sk: SecretKey, /// nonce must be sent to another person - nonce: Nonce + nonce: Nonce, } impl Session { @@ -108,32 +111,39 @@ increment `recv_nonce` after data was decrypted. pub struct Channel { precomputed_key: SalsaBox, sent_nonce: RefCell, - recv_nonce: RefCell + recv_nonce: RefCell, } impl Channel { /** Create a secure channel with `our_session` and `their_pk` & `their_nonce` - */ + */ pub fn new(our_session: &Session, their_pk: &PublicKey, their_nonce: &Nonce) -> Channel { let precomputed = our_session.create_precomputed_key(their_pk); let sent_n = RefCell::new(*our_session.nonce()); let recv_n = RefCell::new(*their_nonce); - Channel { precomputed_key: precomputed, sent_nonce: sent_n, recv_nonce: recv_n } + Channel { + precomputed_key: precomputed, + sent_nonce: sent_n, + recv_nonce: recv_n, + } } /** Encrypt data, increment sent_nonce - */ + */ pub fn encrypt(&self, plain: &[u8]) -> Vec { let mut nonce = self.sent_nonce.borrow_mut(); let encrypted = self.precomputed_key.encrypt((&nonce[..]).into(), plain).unwrap(); - increment_nonce( &mut nonce ); + increment_nonce(&mut nonce); encrypted } /** Decrypt data, increment recv_nonce - */ + */ pub fn decrypt(&self, encrypted: &[u8]) -> Result, ()> { let mut nonce = self.recv_nonce.borrow_mut(); - let decrypted = self.precomputed_key.decrypt((&nonce[..]).into(), encrypted).map_err(|AeadError| ()); - increment_nonce( &mut nonce ); + let decrypted = self + .precomputed_key + .decrypt((&nonce[..]).into(), encrypted) + .map_err(|AeadError| ()); + increment_nonce(&mut nonce); decrypted } } @@ -173,7 +183,10 @@ mod tests { // Alice sends it somehow // Bob receives and decrypts - assert_eq!( alice_msg.as_bytes().to_vec(), bob_channel.decrypt(alice_msg_encrypted.as_ref()).unwrap() ); + assert_eq!( + alice_msg.as_bytes().to_vec(), + bob_channel.decrypt(alice_msg_encrypted.as_ref()).unwrap() + ); // Now Bob encrypts his message let bob_msg = "Oh hello Alice!"; @@ -181,6 +194,9 @@ mod tests { assert_ne!(bob_msg.as_bytes().to_vec(), bob_msg_encrypted); // And sends it back to Alice - assert_eq!( bob_msg.as_bytes().to_vec(), alice_channel.decrypt(bob_msg_encrypted.as_ref()).unwrap() ); + assert_eq!( + bob_msg.as_bytes().to_vec(), + alice_channel.decrypt(bob_msg_encrypted.as_ref()).unwrap() + ); } } diff --git a/tox_core/src/relay/server/client.rs b/tox_core/src/relay/server/client.rs index 4d4b895eb..763be01d0 100644 --- a/tox_core/src/relay/server/client.rs +++ b/tox_core/src/relay/server/client.rs @@ -1,14 +1,14 @@ /*! The inner implementation of client used only by relay server. */ -use tox_crypto::*; -use tox_packet::relay::*; use crate::relay::links::Links; use crate::time::*; use crate::utils::*; +use tox_crypto::*; +use tox_packet::relay::*; use std::net::IpAddr; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; use futures::channel::mpsc; use rand::thread_rng; @@ -46,12 +46,12 @@ pub struct Client { /// Last time sent PingRequest packet last_pinged: Instant, /// Last time received PongResponse - last_pong_resp: Instant + last_pong_resp: Instant, } impl Client { /** Create new Client - */ + */ pub fn new(tx: mpsc::Sender, pk: &PublicKey, ip_addr: IpAddr, port: u16) -> Client { Client { pk: pk.clone(), @@ -61,60 +61,60 @@ impl Client { links: Links::new(), ping_id: 0, last_pinged: clock_now(), - last_pong_resp: clock_now() + last_pong_resp: clock_now(), } } /** PK of the `Client` - */ + */ pub fn pk(&self) -> PublicKey { self.pk.clone() } /** `std::net::IpAddr` of the `Client` - */ + */ pub fn ip_addr(&self) -> IpAddr { self.ip_addr } /** Port of the `Client` - */ + */ pub fn port(&self) -> u16 { self.port } /** Last ping_id sent to client. - */ + */ pub fn ping_id(&self) -> u64 { self.ping_id } /** Set last_pong_resp - */ + */ pub fn set_last_pong_resp(&mut self, time: Instant) { self.last_pong_resp = time; } /** Check if PongResponse timed out - */ + */ pub fn is_pong_timedout(&self) -> bool { clock_elapsed(self.last_pong_resp) > TCP_PING_TIMEOUT + TCP_PING_FREQUENCY } /** Check if Ping interval is elapsed - */ + */ pub fn is_ping_interval_passed(&self) -> bool { clock_elapsed(self.last_pinged) >= TCP_PING_FREQUENCY } /** Get the Links of the Client - */ + */ pub fn links(&self) -> &Links { &self.links } /** Get the Links of the Client - */ + */ pub fn links_mut(&mut self) -> &mut Links { &mut self.links } diff --git a/tox_core/src/relay/server/server.rs b/tox_core/src/relay/server/server.rs index 748d0d223..002ccdd33 100644 --- a/tox_core/src/relay/server/server.rs +++ b/tox_core/src/relay/server/server.rs @@ -1,23 +1,23 @@ /*! The implementation of relay server */ +use crate::relay::links::*; +use crate::relay::server::client::Client; use tox_crypto::*; use tox_packet::onion::InnerOnionResponse; -use crate::relay::server::client::Client; use tox_packet::relay::connection_id::ConnectionId; -use crate::relay::links::*; use tox_packet::relay::*; -use std::io::{Error, ErrorKind}; use std::collections::HashMap; +use std::io::{Error, ErrorKind}; use std::net::{IpAddr, SocketAddr}; use std::sync::Arc; -use std::time::{Instant, Duration}; +use std::time::{Duration, Instant}; -use futures::{SinkExt, StreamExt}; use futures::channel::mpsc; -use tokio::sync::RwLock; use futures::stream::FuturesUnordered; +use futures::{SinkExt, StreamExt}; +use tokio::sync::RwLock; /// Interval of time for packet sending const TCP_SEND_TIMEOUT: Duration = Duration::from_millis(100); @@ -47,10 +47,7 @@ struct ServerState { } async fn send_packet(packet: Packet, mut tx: mpsc::Sender) { - tokio::time::timeout( - TCP_SEND_TIMEOUT, - tx.send(packet) - ).await.ok(); + tokio::time::timeout(TCP_SEND_TIMEOUT, tx.send(packet)).await.ok(); } /// Send all packets concurrently. The error in a single sending @@ -60,7 +57,7 @@ async fn send_packets)>>(pa .into_iter() .map(|(packet, tx)| send_packet(packet, tx)) .collect::>(); - while futures.next().await.is_some() { }; + while futures.next().await.is_some() {} } /// The result of handling one TCP `Packet` whose main purpose is to avoid @@ -90,25 +87,23 @@ impl HandleAction { HandleAction::Send(packets) => send_packets(packets).await, HandleAction::Onion(packet, saddr) => { if let Some(tx) = onion_sink { - tokio::time::timeout( - TCP_SEND_TIMEOUT, - tx.clone().send((packet, saddr)), - ).await.ok(); + tokio::time::timeout(TCP_SEND_TIMEOUT, tx.clone().send((packet, saddr))) + .await + .ok(); } - }, + } } } } - impl Server { /** Create a new `Server` without onion - */ + */ pub fn new() -> Server { Server::default() } /** Create a new `Server` with onion - */ + */ pub fn set_udp_onion_sink(&mut self, onion_sink: mpsc::Sender<(OnionRequest, SocketAddr)>) { self.onion_sink = Some(onion_sink) } @@ -124,10 +119,10 @@ impl Server { vec![] }; - state.keys_by_addr + state + .keys_by_addr .insert((client.ip_addr(), client.port()), client.pk()); - state.connected_clients - .insert(client.pk(), client); + state.connected_clients.insert(client.pk(), client); drop(state); @@ -156,13 +151,25 @@ impl Server { Ok(()) } /** Send `OnionResponse` packet to the client by it's `std::net::IpAddr`. - */ - pub async fn handle_udp_onion_response(&self, ip_addr: IpAddr, port: u16, payload: InnerOnionResponse) -> Result<(), Error> { + */ + pub async fn handle_udp_onion_response( + &self, + ip_addr: IpAddr, + port: u16, + payload: InnerOnionResponse, + ) -> Result<(), Error> { let state = self.state.read().await; - let tx = if let Some(client) = state.keys_by_addr.get(&(ip_addr, port)).and_then(|pk| state.connected_clients.get(pk)) { + let tx = if let Some(client) = state + .keys_by_addr + .get(&(ip_addr, port)) + .and_then(|pk| state.connected_clients.get(pk)) + { client.tx() } else { - return Err(Error::new(ErrorKind::Other, "Cannot find client by ip_addr to send onion response")) + return Err(Error::new( + ErrorKind::Other, + "Cannot find client by ip_addr to send onion response", + )); }; drop(state); @@ -186,10 +193,10 @@ impl Server { // check that the client's address isn't changed if let Some(client) = state.connected_clients.get(pk) { if client.ip_addr() != ip_addr || client.port() != port { - return Err(Error::new(ErrorKind::Other, "Client with pk has different address")) + return Err(Error::new(ErrorKind::Other, "Client with pk has different address")); } } else { - return Err(Error::new(ErrorKind::Other, "Cannot find client by pk to shutdown it")) + return Err(Error::new(ErrorKind::Other, "Cannot find client by pk to shutdown it")); } let packets = self.shutdown_client_inner(pk, &mut state)?; @@ -202,34 +209,42 @@ impl Server { } /** Actual shutdown is done here. - */ - fn shutdown_client_inner(&self, pk: &PublicKey, state: &mut ServerState) -> Result)>, Error> { + */ + fn shutdown_client_inner( + &self, + pk: &PublicKey, + state: &mut ServerState, + ) -> Result)>, Error> { // remove client by pk from connected_clients let client_a = if let Some(client) = state.connected_clients.remove(pk) { client } else { - return Err(Error::new( - ErrorKind::Other, - "Cannot find client by pk to shutdown it" - )) + return 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 result = client_a.links().iter_links().filter(|link| link.status == LinkStatus::Online).filter_map(|link| { - let client_b_pk = link.pk; - if let Some(client_b) = state.connected_clients.get_mut(&client_b_pk) { - if let Some(a_id_in_client_b) = client_b.links().id_by_pk(pk) { - // they are linked, we should notify client_b - // link from client_b.links should be downgraded - client_b.links_mut().downgrade(a_id_in_client_b); - - let packet = Packet::DisconnectNotification(DisconnectNotification { connection_id: ConnectionId::from_index(a_id_in_client_b) }); - return Some((packet, client_b.tx())) + let result = client_a + .links() + .iter_links() + .filter(|link| link.status == LinkStatus::Online) + .filter_map(|link| { + let client_b_pk = link.pk; + if let Some(client_b) = state.connected_clients.get_mut(&client_b_pk) { + if let Some(a_id_in_client_b) = client_b.links().id_by_pk(pk) { + // they are linked, we should notify client_b + // link from client_b.links should be downgraded + client_b.links_mut().downgrade(a_id_in_client_b); + + let packet = Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(a_id_in_client_b), + }); + return Some((packet, client_b.tx())); + } } - } - None - }).collect(); + None + }) + .collect(); Ok(result) } // Here start the impl of `handle_***` methods @@ -238,23 +253,28 @@ impl Server { let mut state = self.state.write().await; // get client_a - let client_a = - if let Some(client) = state.connected_clients.get_mut(pk) { - client - } else { - return Err(Error::new(ErrorKind::Other, "RouteRequest: no such PK")) - }; + let client_a = if let Some(client) = state.connected_clients.get_mut(pk) { + client + } else { + return Err(Error::new(ErrorKind::Other, "RouteRequest: no such PK")); + }; if pk == &packet.pk { // send RouteResponse(0) if client requests its own pk - let packet = Packet::RouteResponse(RouteResponse { connection_id: ConnectionId::zero(), pk: pk.clone() }); + let packet = Packet::RouteResponse(RouteResponse { + connection_id: ConnectionId::zero(), + pk: pk.clone(), + }); return Ok(HandleAction::one(packet, client_a.tx())); } // check if client_a is already linked if let Some(index) = client_a.links().id_by_pk(&packet.pk) { // send RouteResponse if client was already linked to pk - let packet = Packet::RouteResponse(RouteResponse { connection_id: ConnectionId::from_index(index), pk: packet.pk.clone() }); + let packet = Packet::RouteResponse(RouteResponse { + connection_id: ConnectionId::from_index(index), + pk: packet.pk.clone(), + }); return Ok(HandleAction::one(packet, client_a.tx())); } @@ -263,11 +283,17 @@ impl Server { index } else { // send RouteResponse(0) if no space to insert new link - let packet = Packet::RouteResponse(RouteResponse { connection_id: ConnectionId::zero(), pk: packet.pk.clone() }); + let packet = Packet::RouteResponse(RouteResponse { + connection_id: ConnectionId::zero(), + pk: packet.pk.clone(), + }); return Ok(HandleAction::one(packet, client_a.tx())); }; - let route_response = Packet::RouteResponse(RouteResponse { connection_id: ConnectionId::from_index(b_id_in_client_a), pk: packet.pk.clone() }); + let route_response = Packet::RouteResponse(RouteResponse { + connection_id: ConnectionId::from_index(b_id_in_client_a), + pk: packet.pk.clone(), + }); let route_response_tx = client_a.tx(); // get client_b @@ -290,12 +316,16 @@ impl Server { // we don't care if connect notifications fail let client_a = state.connected_clients.get_mut(pk).unwrap(); client_a.links_mut().upgrade(b_id_in_client_a); - let connect_notification_a = Packet::ConnectNotification(ConnectNotification { connection_id: ConnectionId::from_index(b_id_in_client_a) }); + let connect_notification_a = Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(b_id_in_client_a), + }); let connect_notification_a_tx = client_a.tx(); let client_b = state.connected_clients.get_mut(&packet.pk).unwrap(); client_b.links_mut().upgrade(a_id_in_client_b); - let connect_notification_b = Packet::ConnectNotification(ConnectNotification { connection_id: ConnectionId::from_index(a_id_in_client_b) }); + let connect_notification_b = Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(a_id_in_client_b), + }); let connect_notification_b_tx = client_b.tx(); Ok(HandleAction::Send(vec![ @@ -306,19 +336,33 @@ impl Server { } async fn handle_route_response(&self, _pk: &PublicKey, _packet: &RouteResponse) -> Result { - Err(Error::new(ErrorKind::Other, "Client must not send RouteResponse to server")) + Err(Error::new( + ErrorKind::Other, + "Client must not send RouteResponse to server", + )) } - async fn handle_connect_notification(&self, _pk: &PublicKey, _packet: &ConnectNotification) -> Result { + async fn handle_connect_notification( + &self, + _pk: &PublicKey, + _packet: &ConnectNotification, + ) -> Result { // Although normally a client should not send ConnectNotification to server // we ignore it for backward compatibility Ok(HandleAction::empty()) } - async fn handle_disconnect_notification(&self, pk: &PublicKey, packet: &DisconnectNotification) -> Result { + async fn handle_disconnect_notification( + &self, + pk: &PublicKey, + packet: &DisconnectNotification, + ) -> Result { let index = if let Some(index) = packet.connection_id.index() { index } else { - return Err(Error::new(ErrorKind::Other, "DisconnectNotification: connection id is zero")) + return Err(Error::new( + ErrorKind::Other, + "DisconnectNotification: connection id is zero", + )); }; let mut state = self.state.write().await; @@ -329,15 +373,18 @@ impl Server { if let Some(link) = client_a.links_mut().take(index) { link } else { - trace!("DisconnectNotification.connection_id is not linked for the client {:?}", pk); + trace!( + "DisconnectNotification.connection_id is not linked for the client {:?}", + pk + ); // There is possibility that the first client disconnected but the second client // haven't received DisconnectNotification yet and have sent yet another packet. // In this case we don't want to throw an error and force disconnect the second client. // TODO: failure can be used to return an error and handle it inside ServerProcessor - return Ok(HandleAction::empty()) + return Ok(HandleAction::empty()); } } else { - return Err(Error::new(ErrorKind::Other, "DisconnectNotification: no such PK")) + return Err(Error::new(ErrorKind::Other, "DisconnectNotification: no such PK")); }; match a_link.status { @@ -345,27 +392,29 @@ impl Server { // Do nothing because // client_b has not sent RouteRequest yet to connect to client_a Ok(HandleAction::empty()) - }, + } LinkStatus::Online => { let client_b_pk = a_link.pk; // get client_b let client_b = if let Some(client) = state.connected_clients.get_mut(&client_b_pk) { client - } else { + } else { // client_b is not connected to the server // so ignore DisconnectNotification - return Ok(HandleAction::empty()) + return Ok(HandleAction::empty()); }; let a_id_in_client_b = if let Some(id) = client_b.links().id_by_pk(pk) { id } else { // No a_id_in_client_b - return Ok(HandleAction::empty()) + return Ok(HandleAction::empty()); }; // it is linked, we should notify client_b // link from client_b.links should be downgraded client_b.links_mut().downgrade(a_id_in_client_b); - let packet = Packet::DisconnectNotification(DisconnectNotification { connection_id: ConnectionId::from_index(a_id_in_client_b)}); + let packet = Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(a_id_in_client_b), + }); Ok(HandleAction::one(packet, client_b.tx())) } } @@ -373,11 +422,13 @@ impl Server { async fn handle_ping_request(&self, pk: &PublicKey, packet: &PingRequest) -> Result { if packet.ping_id == 0 { - return Err(Error::new(ErrorKind::Other, "PingRequest.ping_id == 0")) + return Err(Error::new(ErrorKind::Other, "PingRequest.ping_id == 0")); } let state = self.state.read().await; if let Some(client_a) = state.connected_clients.get(pk) { - let packet = Packet::PongResponse(PongResponse { ping_id: packet.ping_id }); + let packet = Packet::PongResponse(PongResponse { + ping_id: packet.ping_id, + }); Ok(HandleAction::one(packet, client_a.tx())) } else { Err(Error::new(ErrorKind::Other, "PingRequest: no such PK")) @@ -386,10 +437,7 @@ impl Server { async fn handle_pong_response(&self, pk: &PublicKey, packet: &PongResponse) -> Result { if packet.ping_id == 0 { - return Err( - Error::new(ErrorKind::Other, - "PongResponse.ping_id == 0" - )) + return Err(Error::new(ErrorKind::Other, "PongResponse.ping_id == 0")); } let mut state = self.state.write().await; if let Some(client_a) = state.connected_clients.get_mut(pk) { @@ -407,11 +455,14 @@ impl Server { async fn handle_oob_send(&self, pk: &PublicKey, packet: OobSend) -> Result { if packet.data.is_empty() || packet.data.len() > 1024 { - return Err(Error::new(ErrorKind::Other, "OobSend wrong data length")) + return Err(Error::new(ErrorKind::Other, "OobSend wrong data length")); } let state = self.state.read().await; if let Some(client_b) = state.connected_clients.get(&packet.destination_pk) { - let packet = Packet::OobReceive(OobReceive { sender_pk: pk.clone(), data: packet.data }); + let packet = Packet::OobReceive(OobReceive { + sender_pk: pk.clone(), + data: packet.data, + }); Ok(HandleAction::one(packet, client_b.tx())) } else { Ok(HandleAction::empty()) @@ -419,7 +470,10 @@ impl Server { } async fn handle_oob_receive(&self, _pk: &PublicKey, _packet: &OobReceive) -> Result { - Err(Error::new(ErrorKind::Other, "Client must not send OobReceive to server")) + Err(Error::new( + ErrorKind::Other, + "Client must not send OobReceive to server", + )) } async fn handle_onion_request(&self, pk: &PublicKey, packet: OnionRequest) -> Result { @@ -429,7 +483,7 @@ impl Server { let saddr = SocketAddr::new(client.ip_addr(), client.port()); Ok(HandleAction::Onion(packet, saddr)) } else { - Err(Error::new(ErrorKind::Other, "OnionRequest: no such PK")) + Err(Error::new(ErrorKind::Other, "OnionRequest: no such PK")) } } else { // Ignore OnionRequest as the server is not connected to onion subsystem @@ -438,14 +492,17 @@ impl Server { } async fn handle_onion_response(&self, _pk: &PublicKey, _packet: &OnionResponse) -> Result { - Err(Error::new(ErrorKind::Other, "Client must not send OnionResponse to server")) + Err(Error::new( + ErrorKind::Other, + "Client must not send OnionResponse to server", + )) } async fn handle_data(&self, pk: &PublicKey, packet: Data) -> Result { let index = if let Some(index) = packet.connection_id.index() { index } else { - return Err(Error::new(ErrorKind::Other, "Data: connection id is zero")) + return Err(Error::new(ErrorKind::Other, "Data: connection id is zero")); }; let state = self.state.read().await; @@ -453,7 +510,7 @@ impl Server { // get client_a let client_a = if let Some(client) = state.connected_clients.get(pk) { client - } else { + } else { return Err(Error::new(ErrorKind::Other, "Data: no such PK")); }; @@ -466,7 +523,7 @@ impl Server { // haven't received DisconnectNotification yet and have sent yet another packet. // In this case we don't want to throw an error and force disconnect the second client. // TODO: failure can be used to return an error and handle it inside ServerProcessor - return Ok(HandleAction::empty()) + return Ok(HandleAction::empty()); }; match a_link.status { @@ -474,33 +531,38 @@ impl Server { // Do nothing because // client_b has not sent RouteRequest yet to connect to client_a Ok(HandleAction::empty()) - }, + } LinkStatus::Online => { let client_b_pk = a_link.pk; // get client_b let client_b = if let Some(client) = state.connected_clients.get(&client_b_pk) { client - } else { + } else { // Do nothing because client_b is not connected to server - return Ok(HandleAction::empty()) + return Ok(HandleAction::empty()); }; let a_id_in_client_b = if let Some(id) = client_b.links().id_by_pk(pk) { id } else { // No a_id_in_client_b - return Ok(HandleAction::empty()) + return Ok(HandleAction::empty()); }; // it is linked, we should send data to client_b - let packet = Packet::Data(Data { connection_id: ConnectionId::from_index(a_id_in_client_b), data: packet.data }); + let packet = Packet::Data(Data { + connection_id: ConnectionId::from_index(a_id_in_client_b), + data: packet.data, + }); Ok(HandleAction::one(packet, client_b.tx())) } } } /** Remove timedout connected clients - */ + */ fn remove_timedout_clients(&self, state: &mut ServerState) -> Result)>, Error> { - let keys = state.connected_clients.iter() + let keys = state + .connected_clients + .iter() .filter(|(_key, client)| client.is_pong_timedout()) .map(|(key, _client)| key.clone()) .collect::>(); @@ -516,7 +578,7 @@ impl Server { } /** Send pings to all connected clients and terminate all timed out clients. - */ + */ pub async fn send_pings(&self) -> Result<(), Error> { let mut state = self.state.write().await; @@ -524,7 +586,9 @@ impl Server { for client in state.connected_clients.values_mut() { if client.is_ping_interval_passed() { - let packet = Packet::PingRequest(PingRequest { ping_id: client.new_ping_id() }); + let packet = Packet::PingRequest(PingRequest { + ping_id: client.new_ping_id(), + }); packets.push((packet, client.tx())); } } @@ -541,18 +605,21 @@ impl Server { mod tests { use super::*; + use crate::relay::server::client::*; + use crate::relay::server::{Client, Server}; use rand::thread_rng; use tox_packet::dht::CryptoData; use tox_packet::ip_port::*; use tox_packet::onion::*; - use crate::relay::server::{Client, Server}; - use crate::relay::server::client::*; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, + }; use futures::channel::mpsc; use futures::StreamExt; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::time::Duration; - use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; use crate::time::*; @@ -590,15 +657,25 @@ mod tests { let client_pk_2 = client_2.pk(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2.clone(), connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2.clone(), + connection_id: ConnectionId::from_index(0) + }) + ); { // check links @@ -614,15 +691,25 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send RouteRequest from client_1 again - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2.clone(), connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2.clone(), + connection_id: ConnectionId::from_index(0) + }) + ); { // check links @@ -634,27 +721,43 @@ mod tests { } // emulate send RouteRequest from client_2 - server.handle_packet(&client_pk_2, Packet::RouteRequest( - RouteRequest { pk: client_pk_1.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_2, + Packet::RouteRequest(RouteRequest { + pk: client_pk_1.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_2 let (packet, rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_1.clone(), connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_1.clone(), + connection_id: ConnectionId::from_index(0) + }) + ); // AND // the server should put ConnectNotification into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::ConnectNotification( - ConnectNotification { connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(0) + }) + ); // AND // the server should put ConnectNotification into rx_2 let (packet, rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::ConnectNotification( - ConnectNotification { connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(0) + }) + ); { // check links @@ -672,35 +775,46 @@ mod tests { } // emulate send Data from client_1 - server.handle_packet(&client_pk_1, Packet::Data( - Data { - connection_id: ConnectionId::from_index(0), - data: DataPayload::CryptoData(CryptoData { - nonce_last_bytes: 42, - payload: vec![42; 123], + server + .handle_packet( + &client_pk_1, + Packet::Data(Data { + connection_id: ConnectionId::from_index(0), + data: DataPayload::CryptoData(CryptoData { + nonce_last_bytes: 42, + payload: vec![42; 123], + }), }), - } - )).await.unwrap(); + ) + .await + .unwrap(); // the server should put Data into rx_2 let (packet, rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::Data( - Data { + assert_eq!( + packet.unwrap(), + Packet::Data(Data { connection_id: ConnectionId::from_index(0), data: DataPayload::CryptoData(CryptoData { nonce_last_bytes: 42, payload: vec![42; 123], }), - } - )); + }) + ); // emulate client_1 disconnected - server.shutdown_client(&client_pk_1, client_ip_addr_1, client_port_1).await.unwrap(); + server + .shutdown_client(&client_pk_1, client_ip_addr_1, client_port_1) + .await + .unwrap(); // the server should put DisconnectNotification into rx_2 let (packet, _rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(0) + }) + ); // check client_2.links[client_1] == Registered let state = server.state.read().await; @@ -720,15 +834,25 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2.clone(), connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2.clone(), + connection_id: ConnectionId::from_index(0) + }) + ); { // check links @@ -753,15 +877,25 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_1.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_1.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_1, connection_id: ConnectionId::zero() } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_1, + connection_id: ConnectionId::zero() + }) + ); } #[tokio::test] async fn handle_route_request_too_many_connections() { @@ -779,15 +913,25 @@ mod tests { server.insert(other_client).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: other_client_pk.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: other_client_pk.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, rx_1_nested) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: other_client_pk, connection_id: ConnectionId::from_index(i) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: other_client_pk, + connection_id: ConnectionId::from_index(i) + }) + ); rx_1 = rx_1_nested; } // and send one more again @@ -795,15 +939,25 @@ mod tests { let other_client_pk = other_client.pk(); server.insert(other_client).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: other_client_pk.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: other_client_pk.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: other_client_pk, connection_id: ConnectionId::zero() } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: other_client_pk, + connection_id: ConnectionId::zero() + }) + ); } #[tokio::test] async fn handle_connect_notification() { @@ -814,9 +968,14 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send ConnectNotification from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::ConnectNotification( - ConnectNotification { connection_id: ConnectionId::from_index(42) } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(42), + }), + ) + .await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -832,38 +991,64 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2.clone(), connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2.clone(), + connection_id: ConnectionId::from_index(0) + }) + ); // emulate send RouteRequest from client_2 - server.handle_packet(&client_pk_2, Packet::RouteRequest( - RouteRequest { pk: client_pk_1.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_2, + Packet::RouteRequest(RouteRequest { + pk: client_pk_1.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_2 let (packet, rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_1.clone(), connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_1.clone(), + connection_id: ConnectionId::from_index(0) + }) + ); // AND // the server should put ConnectNotification into rx_1 let (packet, rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::ConnectNotification( - ConnectNotification { connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(0) + }) + ); // AND // the server should put ConnectNotification into rx_2 let (packet, rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::ConnectNotification( - ConnectNotification { connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::ConnectNotification(ConnectNotification { + connection_id: ConnectionId::from_index(0) + }) + ); { // check links @@ -881,15 +1066,24 @@ mod tests { } // emulate send DisconnectNotification from client_1 - server.handle_packet(&client_pk_1, Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(0) } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(0), + }), + ) + .await + .unwrap(); // the server should put DisconnectNotification into rx_2 let (packet, _rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(0) + }) + ); { // check links @@ -906,9 +1100,15 @@ mod tests { } // emulate send DisconnectNotification from client_2 - server.handle_packet(&client_pk_2, Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(0) } - )).await.unwrap(); + server + .handle_packet( + &client_pk_2, + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(0), + }), + ) + .await + .unwrap(); { // check links @@ -937,14 +1137,20 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2 } - )).await.unwrap(); + server + .handle_packet(&client_pk_1, Packet::RouteRequest(RouteRequest { pk: client_pk_2 })) + .await + .unwrap(); // emulate send DisconnectNotification from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(0) } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(0), + }), + ) + .await; assert!(handle_res.is_ok()); // check that packets from client_1 did not put anything in client2.rx @@ -958,9 +1164,14 @@ mod tests { let client_pk = SecretKey::generate(&mut thread_rng()).public_key(); - let handle_res = server.handle_packet(&client_pk, Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::zero() } - )).await; + let handle_res = server + .handle_packet( + &client_pk, + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::zero(), + }), + ) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -972,15 +1183,14 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send PingRequest from client_1 - server.handle_packet(&client_pk_1, Packet::PingRequest( - PingRequest { ping_id: 42 } - )).await.unwrap(); + server + .handle_packet(&client_pk_1, Packet::PingRequest(PingRequest { ping_id: 42 })) + .await + .unwrap(); // the server should put PongResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::PongResponse( - PongResponse { ping_id: 42 } - )); + assert_eq!(packet.unwrap(), Packet::PongResponse(PongResponse { ping_id: 42 })); } #[tokio::test] async fn handle_oob_send() { @@ -995,15 +1205,26 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send OobSend from client_1 - server.handle_packet(&client_pk_1, Packet::OobSend( - OobSend { destination_pk: client_pk_2, data: vec![13; 1024] } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::OobSend(OobSend { + destination_pk: client_pk_2, + data: vec![13; 1024], + }), + ) + .await + .unwrap(); // the server should put OobReceive into rx_2 let (packet, _rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::OobReceive( - OobReceive { sender_pk: client_pk_1, data: vec![13; 1024] } - )); + assert_eq!( + packet.unwrap(), + Packet::OobReceive(OobReceive { + sender_pk: client_pk_1, + data: vec![13; 1024] + }) + ); } #[tokio::test] async fn handle_onion_request() { @@ -1025,7 +1246,7 @@ mod tests { port: 12345, }, temporary_pk: SecretKey::generate(&mut thread_rng()).public_key(), - payload: vec![13; 170] + payload: vec![13; 170], }; let handle_res = server .handle_packet(&client_pk_1, Packet::OnionRequest(request.clone())) @@ -1051,7 +1272,7 @@ mod tests { let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); let handle_res = server .handle_udp_onion_response(client_addr_1, client_port_1, payload.clone()) @@ -1059,9 +1280,7 @@ mod tests { assert!(handle_res.is_ok()); let (packet, _) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::OnionResponse( - OnionResponse { payload } - )); + assert_eq!(packet.unwrap(), Packet::OnionResponse(OnionResponse { payload })); } #[tokio::test] async fn insert_with_same_pk() { @@ -1089,9 +1308,12 @@ mod tests { server.insert(client_3).await.unwrap(); let (packet, _) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(index_2) } - )); + assert_eq!( + packet.unwrap(), + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(index_2) + }) + ); let state = server.state.read().await; let client = &state.connected_clients[&client_pk_1]; @@ -1114,18 +1336,30 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2, connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2, + connection_id: ConnectionId::from_index(0) + }) + ); // emulate shutdown - let handle_res = server.shutdown_client(&client_pk_1, client_ip_addr_1, client_port_1).await; + let handle_res = server + .shutdown_client(&client_pk_1, client_ip_addr_1, client_port_1) + .await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1141,26 +1375,39 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2, connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2, + connection_id: ConnectionId::from_index(0) + }) + ); // emulate send Data from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::Data( - Data { - connection_id: ConnectionId::from_index(0), - data: DataPayload::CryptoData(CryptoData { - nonce_last_bytes: 42, - payload: vec![42; 123], + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::Data(Data { + connection_id: ConnectionId::from_index(0), + data: DataPayload::CryptoData(CryptoData { + nonce_last_bytes: 42, + payload: vec![42; 123], + }), }), - } - )).await; + ) + .await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1169,15 +1416,18 @@ mod tests { let client_pk = SecretKey::generate(&mut thread_rng()).public_key(); - let handle_res = server.handle_packet(&client_pk, Packet::Data( - Data { - connection_id: ConnectionId::zero(), - data: DataPayload::CryptoData(CryptoData { - nonce_last_bytes: 42, - payload: vec![42; 123], + let handle_res = server + .handle_packet( + &client_pk, + Packet::Data(Data { + connection_id: ConnectionId::zero(), + data: DataPayload::CryptoData(CryptoData { + nonce_last_bytes: 42, + payload: vec![42; 123], + }), }), - } - )).await; + ) + .await; assert!(handle_res.is_err()); } @@ -1192,9 +1442,15 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send RouteResponse from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::RouteResponse( - RouteResponse { pk: client_pk_1.clone(), connection_id: ConnectionId::from_index(42) } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::RouteResponse(RouteResponse { + pk: client_pk_1.clone(), + connection_id: ConnectionId::from_index(42), + }), + ) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1206,9 +1462,14 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send DisconnectNotification from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(0) } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(0), + }), + ) + .await; assert!(handle_res.is_ok()); // Necessary to drop tx so that rx.collect() can be finished @@ -1225,9 +1486,9 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send PingRequest from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::PingRequest( - PingRequest { ping_id: 0 } - )).await; + let handle_res = server + .handle_packet(&client_pk_1, Packet::PingRequest(PingRequest { ping_id: 0 })) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1239,9 +1500,9 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send PongResponse from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::PongResponse( - PongResponse { ping_id: 0 } - )).await; + let handle_res = server + .handle_packet(&client_pk_1, Packet::PongResponse(PongResponse { ping_id: 0 })) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1257,9 +1518,15 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send OobSend from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::OobSend( - OobSend { destination_pk: client_pk_2, data: vec![] } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::OobSend(OobSend { + destination_pk: client_pk_2, + data: vec![], + }), + ) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1271,15 +1538,18 @@ mod tests { server.insert(client_1).await.unwrap(); // emulate send Data from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::Data( - Data { - connection_id: ConnectionId::from_index(0), - data: DataPayload::CryptoData(CryptoData { - nonce_last_bytes: 42, - payload: vec![42; 123], + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::Data(Data { + connection_id: ConnectionId::from_index(0), + data: DataPayload::CryptoData(CryptoData { + nonce_last_bytes: 42, + payload: vec![42; 123], + }), }), - } - )).await; + ) + .await; assert!(handle_res.is_ok()); // Necessary to drop tx so that rx.collect() can be finished @@ -1300,9 +1570,15 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send OobSend from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::OobSend( - OobSend { destination_pk: client_pk_2, data: vec![42; 1024 + 1] } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::OobSend(OobSend { + destination_pk: client_pk_2, + data: vec![42; 1024 + 1], + }), + ) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1318,9 +1594,15 @@ mod tests { server.insert(client_2).await.unwrap(); // emulate send OobReceive from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::OobReceive( - OobReceive { sender_pk: client_pk_2, data: vec![42; 1024] } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::OobReceive(OobReceive { + sender_pk: client_pk_2, + data: vec![42; 1024], + }), + ) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1339,11 +1621,9 @@ mod tests { port: 12345, }, temporary_pk: SecretKey::generate(&mut thread_rng()).public_key(), - payload: vec![13; 1500] + payload: vec![13; 1500], }; - let handle_res = server - .handle_packet(&client_pk_1, Packet::OnionRequest(request)) - .await; + let handle_res = server.handle_packet(&client_pk_1, Packet::OnionRequest(request)).await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1357,11 +1637,11 @@ mod tests { let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); - let handle_res = server.handle_packet(&client_pk_1, Packet::OnionResponse( - OnionResponse { payload } - )).await; + let handle_res = server + .handle_packet(&client_pk_1, Packet::OnionResponse(OnionResponse { payload })) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1383,7 +1663,7 @@ mod tests { let payload = InnerOnionResponse::OnionAnnounceResponse(OnionAnnounceResponse { sendback_data: 12345, nonce: [42; ::NonceSize::USIZE], - payload: vec![42; 123] + payload: vec![42; 123], }); let handle_res = server .handle_udp_onion_response(client_addr_2, client_port_2, payload) @@ -1401,9 +1681,9 @@ mod tests { let client_pk_2 = SecretKey::generate(&mut rng).public_key(); // emulate send RouteRequest from client_pk_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2 } - )).await; + let handle_res = server + .handle_packet(&client_pk_1, Packet::RouteRequest(RouteRequest { pk: client_pk_2 })) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1412,9 +1692,14 @@ mod tests { let client_pk_1 = SecretKey::generate(&mut thread_rng()).public_key(); // emulate send DisconnectNotification from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(42) } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(42), + }), + ) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1428,14 +1713,20 @@ mod tests { let client_pk_2 = SecretKey::generate(&mut thread_rng()).public_key(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2 } - )).await.unwrap(); + server + .handle_packet(&client_pk_1, Packet::RouteRequest(RouteRequest { pk: client_pk_2 })) + .await + .unwrap(); // emulate send DisconnectNotification from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::DisconnectNotification( - DisconnectNotification { connection_id: ConnectionId::from_index(0) } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::DisconnectNotification(DisconnectNotification { + connection_id: ConnectionId::from_index(0), + }), + ) + .await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1444,9 +1735,9 @@ mod tests { let client_pk_1 = SecretKey::generate(&mut thread_rng()).public_key(); // emulate send PingRequest from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::PingRequest( - PingRequest { ping_id: 42 } - )).await; + let handle_res = server + .handle_packet(&client_pk_1, Packet::PingRequest(PingRequest { ping_id: 42 })) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1455,9 +1746,9 @@ mod tests { let client_pk_1 = SecretKey::generate(&mut thread_rng()).public_key(); // emulate send PongResponse from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::PongResponse( - PongResponse { ping_id: 42 } - )).await; + let handle_res = server + .handle_packet(&client_pk_1, Packet::PongResponse(PongResponse { ping_id: 42 })) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1468,9 +1759,15 @@ mod tests { let client_pk_2 = SecretKey::generate(&mut rng).public_key(); // emulate send OobSend from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::OobSend( - OobSend { destination_pk: client_pk_2, data: vec![42; 1024] } - )).await; + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::OobSend(OobSend { + destination_pk: client_pk_2, + data: vec![42; 1024], + }), + ) + .await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1479,15 +1776,18 @@ mod tests { let client_pk_1 = SecretKey::generate(&mut thread_rng()).public_key(); // emulate send Data from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::Data( - Data { - connection_id: ConnectionId::from_index(0), - data: DataPayload::CryptoData(CryptoData { - nonce_last_bytes: 42, - payload: vec![42; 123], + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::Data(Data { + connection_id: ConnectionId::from_index(0), + data: DataPayload::CryptoData(CryptoData { + nonce_last_bytes: 42, + payload: vec![42; 123], + }), }), - } - )).await; + ) + .await; assert!(handle_res.is_err()); } #[tokio::test] @@ -1501,26 +1801,39 @@ mod tests { let client_pk_2 = SecretKey::generate(&mut thread_rng()).public_key(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2, connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2, + connection_id: ConnectionId::from_index(0) + }) + ); // emulate send Data from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::Data( - Data { - connection_id: ConnectionId::from_index(0), - data: DataPayload::CryptoData(CryptoData { - nonce_last_bytes: 42, - payload: vec![42; 123], + let handle_res = server + .handle_packet( + &client_pk_1, + Packet::Data(Data { + connection_id: ConnectionId::from_index(0), + data: DataPayload::CryptoData(CryptoData { + nonce_last_bytes: 42, + payload: vec![42; 123], + }), }), - } - )).await; + ) + .await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1532,7 +1845,9 @@ mod tests { server.insert(client).await.unwrap(); // emulate shutdown - let handle_res = server.shutdown_client(&client_pk, "1.2.3.4".parse().unwrap(), 12346).await; + let handle_res = server + .shutdown_client(&client_pk, "1.2.3.4".parse().unwrap(), 12346) + .await; assert!(handle_res.is_err()); let state = server.state.read().await; @@ -1574,18 +1889,30 @@ mod tests { let client_pk_2 = SecretKey::generate(&mut thread_rng()).public_key(); // emulate send RouteRequest from client_1 - server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2.clone() } - )).await.unwrap(); + server + .handle_packet( + &client_pk_1, + Packet::RouteRequest(RouteRequest { + pk: client_pk_2.clone(), + }), + ) + .await + .unwrap(); // the server should put RouteResponse into rx_1 let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::RouteResponse( - RouteResponse { pk: client_pk_2, connection_id: ConnectionId::from_index(0) } - )); + assert_eq!( + packet.unwrap(), + Packet::RouteResponse(RouteResponse { + pk: client_pk_2, + connection_id: ConnectionId::from_index(0) + }) + ); // emulate shutdown - let handle_res = server.shutdown_client(&client_pk_1, client_ip_addr_1, client_port_1).await; + let handle_res = server + .shutdown_client(&client_pk_1, client_ip_addr_1, client_port_1) + .await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1603,9 +1930,9 @@ mod tests { drop(rx_1); // emulate send RouteRequest from client_1 - let handle_res = server.handle_packet(&client_pk_1, Packet::RouteRequest( - RouteRequest { pk: client_pk_2 } - )).await; + let handle_res = server + .handle_packet(&client_pk_1, Packet::RouteRequest(RouteRequest { pk: client_pk_2 })) + .await; assert!(handle_res.is_ok()) } #[tokio::test] @@ -1629,11 +1956,9 @@ mod tests { port: 12345, }, temporary_pk: SecretKey::generate(&mut thread_rng()).public_key(), - payload: vec![13; 170] + payload: vec![13; 170], }; - let handle_res = server - .handle_packet(&client_pk_1, Packet::OnionRequest(request)) - .await; + let handle_res = server.handle_packet(&client_pk_1, Packet::OnionRequest(request)).await; assert!(handle_res.is_ok()); } #[tokio::test] @@ -1655,7 +1980,6 @@ mod tests { let pk_3 = client_3.pk(); server.insert(client_3).await.unwrap(); - tokio::time::pause(); // time when all entries is needed to send PingRequest tokio::time::advance(TCP_PING_FREQUENCY + Duration::from_secs(1)).await; @@ -1664,17 +1988,26 @@ mod tests { assert!(sender_res.is_ok()); let (packet, _rx_1) = rx_1.into_future().await; - assert_eq!(packet.unwrap(), Packet::PingRequest( - PingRequest { ping_id: server.state.read().await.connected_clients[&pk_1].ping_id() } - )); + assert_eq!( + packet.unwrap(), + Packet::PingRequest(PingRequest { + ping_id: server.state.read().await.connected_clients[&pk_1].ping_id() + }) + ); let (packet, _rx_2) = rx_2.into_future().await; - assert_eq!(packet.unwrap(), Packet::PingRequest( - PingRequest { ping_id: server.state.read().await.connected_clients[&pk_2].ping_id() } - )); + assert_eq!( + packet.unwrap(), + Packet::PingRequest(PingRequest { + ping_id: server.state.read().await.connected_clients[&pk_2].ping_id() + }) + ); let (packet, _rx_3) = rx_3.into_future().await; - assert_eq!(packet.unwrap(), Packet::PingRequest( - PingRequest { ping_id: server.state.read().await.connected_clients[&pk_3].ping_id() } - )); + assert_eq!( + packet.unwrap(), + Packet::PingRequest(PingRequest { + ping_id: server.state.read().await.connected_clients[&pk_3].ping_id() + }) + ); } #[tokio::test] async fn tcp_send_remove_timedouts() { diff --git a/tox_core/src/relay/server/server_ext.rs b/tox_core/src/relay/server/server_ext.rs index e154891c7..41eb1f2a5 100644 --- a/tox_core/src/relay/server/server_ext.rs +++ b/tox_core/src/relay/server/server_ext.rs @@ -2,22 +2,22 @@ */ use std::io::Error as IoError; -use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; +use std::sync::Arc; use std::time::Duration; -use thiserror::Error; -use futures::{FutureExt, TryFutureExt, SinkExt, StreamExt, TryStreamExt}; use futures::channel::mpsc; -use tokio::net::{TcpStream, TcpListener}; -use tokio_util::codec::Framed; +use futures::{FutureExt, SinkExt, StreamExt, TryFutureExt, TryStreamExt}; +use thiserror::Error; +use tokio::net::{TcpListener, TcpStream}; use tokio::time::error::Error as TimerError; +use tokio_util::codec::Framed; -use tox_crypto::*; -use crate::relay::codec::{DecodeError, EncodeError, Codec}; +use crate::relay::codec::{Codec, DecodeError, EncodeError}; use crate::relay::handshake::make_server_handshake; use crate::relay::server::{Client, Server}; use crate::stats::*; +use tox_crypto::*; /// Interval of time for Tcp Ping sender const TCP_PING_INTERVAL: Duration = Duration::from_secs(1); @@ -34,19 +34,19 @@ pub enum ServerRunError { #[error("Incoming IO error: {:?}", error)] Incoming { /// IO error - error: IoError + error: IoError, }, /// Ping wakeups timer error #[error("Ping wakeups timer error: {:?}", error)] PingWakeups { /// Timer error - error: TimerError + error: TimerError, }, /// Send pings error #[error("Send pings error: {:?}", error)] SendPings { /// Send pings error - error: IoError + error: IoError, }, } @@ -61,25 +61,21 @@ pub enum ConnectionError { }, /// Sending packet error #[error("Failed to send TCP packet: {}", error)] - SendPacket { - error: EncodeError - }, + SendPacket { error: EncodeError }, /// Decode incoming packet error #[error("Failed to decode incoming packet: {}", error)] - DecodePacket { - error: DecodeError - }, + DecodePacket { error: DecodeError }, /// Incoming IO error #[error("Incoming IO error: {:?}", error)] Incoming { /// IO error - error: IoError + error: IoError, }, /// Server handshake error #[error("Server handshake error: {:?}", error)] ServerHandshakeTimeout { /// Server handshake error - error: tokio::time::error::Elapsed + error: tokio::time::error::Elapsed, }, #[error("Server handshake error: {:?}", error)] ServerHandshakeIo { @@ -90,31 +86,40 @@ pub enum ConnectionError { #[error("Packet handling error: {:?}", error)] PacketHandling { /// Packet handling error - error: IoError + error: IoError, }, /// Insert client error #[error("Packet handling error: {:?}", error)] InsertClient { /// Insert client error - error: IoError + error: IoError, }, #[error("Packet handling error: {:?}", error)] Shutdown { /// Insert client error - error: IoError + error: IoError, }, } /// Running TCP ping sender and incoming `TcpStream`. This function uses /// `tokio::spawn` inside so it should be executed via tokio to be able to /// get tokio default executor. -pub async fn tcp_run(server: &Server, listener: TcpListener, dht_sk: SecretKey, stats: Stats, connections_limit: usize) -> Result<(), ServerRunError> { +pub async fn tcp_run( + server: &Server, + listener: TcpListener, + dht_sk: SecretKey, + stats: Stats, + connections_limit: usize, +) -> Result<(), ServerRunError> { let connections_count = Arc::new(AtomicUsize::new(0)); let connections_future = async { loop { - let (stream, _) = listener.accept().await.map_err(|error| ServerRunError::Incoming { error })?; + let (stream, _) = listener + .accept() + .await + .map_err(|error| ServerRunError::Incoming { error })?; if connections_count.load(Ordering::SeqCst) < connections_limit { connections_count.fetch_add(1, Ordering::SeqCst); let connections_count_c = connections_count.clone(); @@ -122,18 +127,16 @@ pub async fn tcp_run(server: &Server, listener: TcpListener, dht_sk: SecretKey, let stats = stats.clone(); let server = server.clone(); - tokio::spawn( - async move { - let res = tcp_run_connection(&server, stream, dht_sk, stats).await; - - if let Err(ref e) = res { - error!("Error while running tcp connection: {:?}", e) - } + tokio::spawn(async move { + let res = tcp_run_connection(&server, stream, dht_sk, stats).await; - connections_count_c.fetch_sub(1, Ordering::SeqCst); - res + if let Err(ref e) = res { + error!("Error while running tcp connection: {:?}", e) } - ); + + connections_count_c.fetch_sub(1, Ordering::SeqCst); + res + }); } else { trace!("Tcp server has reached the limit of {} connections", connections_limit); } @@ -146,7 +149,9 @@ pub async fn tcp_run(server: &Server, listener: TcpListener, dht_sk: SecretKey, wakeups.tick().await; trace!("Tcp server ping sender wake up"); - server.send_pings().await + server + .send_pings() + .await .map_err(|error| ServerRunError::SendPings { error })?; } }; @@ -158,28 +163,24 @@ pub async fn tcp_run(server: &Server, listener: TcpListener, dht_sk: SecretKey, } /// Running TCP server on incoming `TcpStream` -pub async fn tcp_run_connection(server: &Server, stream: TcpStream, dht_sk: SecretKey, stats: Stats) -> Result<(), ConnectionError> { +pub async fn tcp_run_connection( + server: &Server, + stream: TcpStream, + dht_sk: SecretKey, + stats: Stats, +) -> Result<(), ConnectionError> { let addr = match stream.peer_addr() { Ok(addr) => addr, - Err(error) => return Err(ConnectionError::PeerAddr { - error - }), + Err(error) => return Err(ConnectionError::PeerAddr { error }), }; debug!("A new TCP client connected from {}", addr); - let fut = tokio::time::timeout( - TCP_HANDSHAKE_TIMEOUT, - make_server_handshake(stream, dht_sk.clone()) - ); + let fut = tokio::time::timeout(TCP_HANDSHAKE_TIMEOUT, make_server_handshake(stream, dht_sk.clone())); let (stream, channel, client_pk) = match fut.await { - Err(error) => Err( - ConnectionError::ServerHandshakeTimeout { error } - ), - Ok(Err(error)) => Err( - ConnectionError::ServerHandshakeIo { error } - ), - Ok(Ok(res)) => Ok(res) + Err(error) => Err(ConnectionError::ServerHandshakeTimeout { error }), + Ok(Err(error)) => Err(ConnectionError::ServerHandshakeIo { error }), + Ok(Ok(res)) => Ok(res), }?; debug!("Handshake for TCP client {:?} is completed", client_pk); @@ -193,29 +194,27 @@ pub async fn tcp_run_connection(server: &Server, stream: TcpStream, dht_sk: Secr .map_err(|error| ConnectionError::DecodePacket { error }) .try_for_each(|packet| { debug!("Handle {:?} => {:?}", client_pk, packet); - server.handle_packet(&client_pk, packet) - .map_err(|error| ConnectionError::PacketHandling { error } ) + server + .handle_packet(&client_pk, packet) + .map_err(|error| ConnectionError::PacketHandling { error }) }); let writer = async { while let Some(packet) = to_client_rx.next().await { trace!("Sending TCP packet {:?} to {:?}", packet, client_pk); - to_client.send(packet).await - .map_err(|error| ConnectionError::SendPacket { - error - })?; + to_client + .send(packet) + .await + .map_err(|error| ConnectionError::SendPacket { error })?; } Ok(()) }; - let client = Client::new( - to_client_tx, - &client_pk, - addr.ip(), - addr.port() - ); - server.insert(client).await + let client = Client::new(to_client_tx, &client_pk, addr.ip(), addr.port()); + server + .insert(client) + .await .map_err(|error| ConnectionError::InsertClient { error })?; let r_processing = futures::select! { @@ -225,7 +224,8 @@ pub async fn tcp_run_connection(server: &Server, stream: TcpStream, dht_sk: Secr debug!("Shutdown a client with PK {:?}", &client_pk); - server.shutdown_client(&client_pk, addr.ip(), addr.port()) + server + .shutdown_client(&client_pk, addr.ip(), addr.port()) .await .map_err(|error| ConnectionError::Shutdown { error })?; @@ -237,8 +237,8 @@ mod tests { use super::*; use tox_binary_io::*; - use std::io::{Error, ErrorKind}; use rand::thread_rng; + use std::io::{Error, ErrorKind}; use crate::relay::codec::Codec; use crate::relay::handshake::make_client_handshake; @@ -264,25 +264,27 @@ mod tests { // take the first connection let (connection, _) = listener.accept().await.unwrap(); tcp_run_connection(&Server::new(), connection, server_sk, stats.clone()) - .map_err(|e| Error::new(ErrorKind::Other, e)).await + .map_err(|e| Error::new(ErrorKind::Other, e)) + .await }; let client = async { let socket = TcpStream::connect(&addr).map_err(Error::from).await?; let (stream, channel) = make_client_handshake(socket, &client_pk, &client_sk, &server_pk) - .map_err(Error::from).await?; + .map_err(Error::from) + .await?; let secure_socket = Framed::new(stream, Codec::new(channel, stats_c)); let (mut to_server, mut from_server) = secure_socket.split(); - let packet = Packet::PingRequest(PingRequest { - ping_id: 42 - }); + let packet = Packet::PingRequest(PingRequest { ping_id: 42 }); - to_server.send(packet).map_err(|e| Error::new(ErrorKind::Other, e)).await.unwrap(); + to_server + .send(packet) + .map_err(|e| Error::new(ErrorKind::Other, e)) + .await + .unwrap(); let packet = from_server.next().await.unwrap(); - assert_eq!(packet.unwrap(), Packet::PongResponse(PongResponse { - ping_id: 42 - })); + assert_eq!(packet.unwrap(), Packet::PongResponse(PongResponse { ping_id: 42 })); Ok(()) }; @@ -311,26 +313,27 @@ mod tests { let stats = Stats::new(); let server = async { - tcp_run(&Server::new(), listener, server_sk, stats.clone(), 1).await + tcp_run(&Server::new(), listener, server_sk, stats.clone(), 1) + .await .map_err(|e| Error::new(ErrorKind::Other, e)) }; let client = async { let socket = TcpStream::connect(&addr).map_err(Error::from).await?; let (stream, channel) = make_client_handshake(socket, &client_pk, &client_sk, &server_pk) - .map_err(Error::from).await?; + .map_err(Error::from) + .await?; let secure_socket = Framed::new(stream, Codec::new(channel, stats.clone())); let (mut to_server, mut from_server) = secure_socket.split(); - let packet = Packet::PingRequest(PingRequest { - ping_id: 42 - }); - to_server.send(packet).map_err(|e| Error::new(ErrorKind::Other, e)).await?; + let packet = Packet::PingRequest(PingRequest { ping_id: 42 }); + to_server + .send(packet) + .map_err(|e| Error::new(ErrorKind::Other, e)) + .await?; let packet = from_server.next().await.unwrap(); - assert_eq!(packet.unwrap(), Packet::PongResponse(PongResponse { - ping_id: 42 - })); + assert_eq!(packet.unwrap(), Packet::PongResponse(PongResponse { ping_id: 42 })); // Set time when the client should be pinged tokio::time::advance(TCP_PING_FREQUENCY + Duration::from_secs(1)).await; while let Some(packet) = from_server.next().await { diff --git a/tox_core/src/state_format/mod.rs b/tox_core/src/state_format/mod.rs index 7c12560c5..c2b1bf7d4 100644 --- a/tox_core/src/state_format/mod.rs +++ b/tox_core/src/state_format/mod.rs @@ -10,6 +10,5 @@ moved out of toxcore into a separate library and maintained there.* https://zetok.github.io/tox-spec/#state-format */ - // FIXME: use new dht code instead of old pub mod old; diff --git a/tox_core/src/state_format/old.rs b/tox_core/src/state_format/old.rs index caa6153a5..9a4f05c2c 100644 --- a/tox_core/src/state_format/old.rs +++ b/tox_core/src/state_format/old.rs @@ -1,22 +1,22 @@ //! Old **Tox State Format (TSF)**. *__Will be deprecated__ when something //! better will become available.* -use std::default::Default; use nom::{ - number::complete::{le_u16, be_u16, le_u8, le_u32, le_u64}, - combinator::{rest, success, verify, map_parser, map}, - bytes::complete::{take, tag}, - multi::{many0, length_data}, - error::{ErrorKind, make_error}, branch::alt, + bytes::complete::{tag, take}, + combinator::{map, map_parser, rest, success, verify}, + error::{make_error, ErrorKind}, + multi::{length_data, many0}, + number::complete::{be_u16, le_u16, le_u32, le_u64, le_u8}, }; use rand::{CryptoRng, Rng}; +use std::default::Default; use tox_binary_io::*; use tox_crypto::*; use tox_packet::dht::packed_node::*; -use tox_packet::toxid::{NoSpam, NOSPAMBYTES}; use tox_packet::packed_node::*; +use tox_packet::toxid::{NoSpam, NOSPAMBYTES}; const REQUEST_MSG_LEN: usize = 1024; @@ -47,7 +47,7 @@ impl NospamKeys { NospamKeys { nospam: rng.gen(), pk, - sk + sk, } } } @@ -58,20 +58,17 @@ impl NospamKeys { // NoSpam is defined in toxid.rs impl FromBytes for NospamKeys { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, _) = tag([0x01,0x00])(input)?; + let (input, _) = tag([0x01, 0x00])(input)?; let (input, _) = tag(SECTION_MAGIC)(input)?; let (input, nospam) = NoSpam::from_bytes(input)?; let (input, pk) = PublicKey::from_bytes(input)?; let (input, sk) = SecretKey::from_bytes(input)?; - Ok((input, NospamKeys { - nospam, - pk, - sk - })) + Ok((input, NospamKeys { nospam, pk, sk })) } } impl ToBytes for NospamKeys { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x0001) >> @@ -96,7 +93,7 @@ pub const NAME_LEN: usize = 128; */ impl FromBytes for Name { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, _) = tag([0x04,0x00])(input)?; + let (input, _) = tag([0x04, 0x00])(input)?; let (input, _) = tag(SECTION_MAGIC)(input)?; let (input, name_bytes) = rest(input)?; Ok((input, Name(name_bytes.to_vec()))) @@ -104,6 +101,7 @@ impl FromBytes for Name { } impl ToBytes for Name { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x0004) >> @@ -137,7 +135,7 @@ const DHT_2ND_MAGICAL: u16 = 0x11ce; impl FromBytes for DhtState { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, _) = tag([0x02,0x00])(input)?; + let (input, _) = tag([0x02, 0x00])(input)?; let (input, _) = tag(SECTION_MAGIC)(input)?; let (input, _) = verify(le_u32, |value| *value == DHT_MAGICAL)(input)?; // check whether beginning of the section matches DHT magic bytes let (input, num_of_bytes) = le_u32(input)?; @@ -149,6 +147,7 @@ impl FromBytes for DhtState { } impl ToBytes for DhtState { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { let start_idx = buf.1; @@ -176,16 +175,16 @@ https://zetok.github.io/tox-spec/#friends-0x03 #[derive(Copy, Clone, Debug, Eq, PartialEq)] pub enum FriendStatus { /// Not a friend. (When this can happen and what does it entail?) - NotFriend = 0, + NotFriend = 0, /// Friend was added. - Added = 1, + Added = 1, /// Friend request was sent to the friend. - FrSent = 2, + FrSent = 2, /// Friend confirmed. /// (Something like toxcore knowing that friend accepted FR?) - Confirmed = 3, + Confirmed = 3, /// Friend has come online. - Online = 4, + Online = 4, } impl FromBytes for FriendStatus { @@ -212,9 +211,9 @@ pub enum UserWorkingStatus { /// User is `Online`. Online = 0, /// User is `Away`. - Away = 1, + Away = 1, /// User is `Busy`. - Busy = 2, + Busy = 2, } /// Returns `UserWorkingStatus::Online`. @@ -245,7 +244,7 @@ pub struct UserStatus(UserWorkingStatus); impl FromBytes for UserStatus { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, _) = tag([0x06,0x00])(input)?; + let (input, _) = tag([0x06, 0x00])(input)?; let (input, _) = tag(SECTION_MAGIC)(input)?; let (input, user_status) = UserWorkingStatus::from_bytes(input)?; Ok((input, UserStatus(user_status))) @@ -253,6 +252,7 @@ impl FromBytes for UserStatus { } impl ToBytes for UserStatus { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x0006) >> @@ -274,6 +274,7 @@ pub struct StatusMsg(pub Vec); pub const STATUS_MSG_LEN: usize = 1007; impl ToBytes for StatusMsg { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x0005) >> @@ -285,7 +286,7 @@ impl ToBytes for StatusMsg { impl FromBytes for StatusMsg { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, _) = tag([0x05,0x00])(input)?; + let (input, _) = tag([0x05, 0x00])(input)?; let (input, _) = tag(SECTION_MAGIC)(input)?; let (input, status_msg_bytes) = rest(input)?; Ok((input, StatusMsg(status_msg_bytes.to_vec()))) @@ -306,6 +307,7 @@ impl FromBytes for TcpRelays { } impl ToBytes for TcpRelays { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x000a) >> @@ -329,6 +331,7 @@ impl FromBytes for PathNodes { } impl ToBytes for PathNodes { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x000b) >> @@ -389,7 +392,7 @@ impl FromBytes for FriendState { let (input, _) = take(1usize)(input)?; let (input, fr_msg_len) = be_u16(input)?; let (input, _) = verify(success(fr_msg_len), |len| *len <= REQUEST_MSG_LEN as u16)(input)?; - let fr_msg =fr_msg_bytes[..fr_msg_len as usize].to_vec(); + let fr_msg = fr_msg_bytes[..fr_msg_len as usize].to_vec(); let (input, name_bytes) = take(NAME_LEN)(input)?; let (input, name_len) = be_u16(input)?; let (input, _) = verify(success(name_len), |len| *len <= NAME_LEN as u16)(input)?; @@ -403,21 +406,25 @@ impl FromBytes for FriendState { let (input, _) = take(3usize)(input)?; let (input, nospam) = NoSpam::from_bytes(input)?; let (input, last_seen) = le_u64(input)?; - Ok((input, FriendState { - friend_status, - pk, - fr_msg, - name, - status_msg, - user_status, - nospam, - last_seen, - })) + Ok(( + input, + FriendState { + friend_status, + pk, + fr_msg, + name, + status_msg, + user_status, + nospam, + last_seen, + }, + )) } } impl ToBytes for FriendState { #[allow(clippy::cognitive_complexity)] + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { let mut fr_msg_pad = self.fr_msg.clone(); let mut name_pad = self.name.0.clone(); @@ -461,6 +468,7 @@ impl FromBytes for Friends { } impl ToBytes for Friends { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x0003) >> @@ -483,6 +491,7 @@ impl FromBytes for Eof { } impl ToBytes for Eof { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u16!(0x00ff) >> @@ -604,13 +613,17 @@ impl FromBytes for State { let (input, _) = tag(&[0; 4][..])(input)?; let (input, _) = tag(STATE_MAGIC)(input)?; let (input, sections) = many0(map_parser(length_data(map(le_u32, |len| len + 4)), Section::from_bytes))(input)?; - Ok((input, State { - sections: sections.to_vec(), - })) + Ok(( + input, + State { + sections: sections.to_vec(), + }, + )) } } impl ToBytes for State { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!([0; 4]) >> @@ -681,25 +694,13 @@ mod tests { } ); - encode_decode_test!( - name_encode_decode, - Name(vec![0,1,2,3,4]) - ); + encode_decode_test!(name_encode_decode, Name(vec![0, 1, 2, 3, 4])); - encode_decode_test!( - status_msg_encode_decode, - StatusMsg(vec![0,1,2,3,4,5]) - ); + encode_decode_test!(status_msg_encode_decode, StatusMsg(vec![0, 1, 2, 3, 4, 5])); - encode_decode_test!( - eof_encode_decode, - Eof - ); + encode_decode_test!(eof_encode_decode, Eof); - encode_decode_test!( - user_status_encode_decode, - UserStatus(UserWorkingStatus::Online) - ); + encode_decode_test!(user_status_encode_decode, UserStatus(UserWorkingStatus::Online)); encode_decode_test!( tcp_relays_encode_decode, diff --git a/tox_core/src/stats.rs b/tox_core/src/stats.rs index 6d57ef213..615540308 100644 --- a/tox_core/src/stats.rs +++ b/tox_core/src/stats.rs @@ -3,14 +3,14 @@ Statistics of incoming/outgoing packets This is used by both Udp codec and Tcp codec. */ -use std::sync::Arc; use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::Arc; /// Struct for various counters #[derive(Clone, Default)] pub struct Stats { /// incoming/outgoing counters - pub counters: Arc + pub counters: Arc, } impl Stats { diff --git a/tox_core/src/time.rs b/tox_core/src/time.rs index 040d36351..d9b4ef258 100644 --- a/tox_core/src/time.rs +++ b/tox_core/src/time.rs @@ -1,10 +1,11 @@ //! Functions to work with time -use std::time::{Duration, SystemTime, Instant, UNIX_EPOCH}; +use std::time::{Duration, Instant, SystemTime, UNIX_EPOCH}; /// Return number of seconds that have elapsed since Unix epoch. pub fn unix_time(time: SystemTime) -> u64 { - let since_the_epoch = time.duration_since(UNIX_EPOCH) + let since_the_epoch = time + .duration_since(UNIX_EPOCH) .expect("Current time is earlier than Unix epoch"); since_the_epoch.as_secs() } @@ -32,7 +33,7 @@ pub fn clock_elapsed(time: Instant) -> Duration { #[cfg(test)] pub mod tests { - use super::{clock_now, clock_elapsed}; + use super::{clock_elapsed, clock_now}; #[tokio::test] async fn const_elapsed() { diff --git a/tox_core/src/udp.rs b/tox_core/src/udp.rs index a4664255b..3154f4112 100644 --- a/tox_core/src/udp.rs +++ b/tox_core/src/udp.rs @@ -1,11 +1,11 @@ use crate::dht::ip_port::IsGlobal; -use crate::dht::server::Server as DhtServer; use crate::dht::server::errors::*; +use crate::dht::server::Server as DhtServer; use crate::net_crypto::NetCrypto; use crate::onion::client::OnionClient; +use std::net::SocketAddr; use tox_packet::dht::*; use tox_packet::onion::*; -use std::net::SocketAddr; /// UDP server that handles DHT, onion and net_crypto packets. Onion and /// net_crypro handlers are optional since appropriate packets are not handled @@ -37,55 +37,36 @@ impl Server { /// Function to handle incoming packets and send responses if necessary. pub async fn handle_packet(&self, packet: Packet, addr: SocketAddr) -> Result<(), HandlePacketError> { match packet { - Packet::PingRequest(packet) => - self.dht.handle_ping_req(packet, addr).await, - Packet::PingResponse(packet) => - self.dht.handle_ping_resp(packet, addr).await, - Packet::NodesRequest(packet) => - self.dht.handle_nodes_req(packet, addr).await, - Packet::NodesResponse(packet) => - self.dht.handle_nodes_resp(packet, addr).await, - Packet::CookieRequest(packet) => - self.handle_cookie_request(&packet, addr).await, - Packet::CookieResponse(packet) => - self.handle_cookie_response(&packet, addr).await, - Packet::CryptoHandshake(packet) => - self.handle_crypto_handshake(&packet, addr).await, - Packet::DhtRequest(packet) => - self.dht.handle_dht_req(packet, addr).await, - Packet::LanDiscovery(packet) => - self.dht.handle_lan_discovery(&packet, addr).await, - Packet::OnionRequest0(packet) => - self.dht.handle_onion_request_0(packet, addr).await, - Packet::OnionRequest1(packet) => - self.dht.handle_onion_request_1(packet, addr).await, - Packet::OnionRequest2(packet) => - self.dht.handle_onion_request_2(packet, addr).await, - Packet::OnionAnnounceRequest(packet) => - self.dht.handle_onion_announce_request(packet, addr).await, - Packet::OnionDataRequest(packet) => - self.dht.handle_onion_data_request(packet).await, - Packet::OnionResponse3(packet) => - self.dht.handle_onion_response_3(packet).await, - Packet::OnionResponse2(packet) => - self.dht.handle_onion_response_2(packet).await, - Packet::OnionResponse1(packet) => - self.dht.handle_onion_response_1(packet).await, - Packet::BootstrapInfo(packet) => - self.dht.handle_bootstrap_info(&packet, addr).await, - Packet::CryptoData(packet) => - self.handle_crypto_data(&packet, addr).await, - Packet::OnionDataResponse(packet) => - self.handle_onion_data_response(&packet).await, - Packet::OnionAnnounceResponse(packet) => - self.handle_onion_announce_response(&packet, addr).await, + Packet::PingRequest(packet) => self.dht.handle_ping_req(packet, addr).await, + Packet::PingResponse(packet) => self.dht.handle_ping_resp(packet, addr).await, + Packet::NodesRequest(packet) => self.dht.handle_nodes_req(packet, addr).await, + Packet::NodesResponse(packet) => self.dht.handle_nodes_resp(packet, addr).await, + Packet::CookieRequest(packet) => self.handle_cookie_request(&packet, addr).await, + Packet::CookieResponse(packet) => self.handle_cookie_response(&packet, addr).await, + Packet::CryptoHandshake(packet) => self.handle_crypto_handshake(&packet, addr).await, + Packet::DhtRequest(packet) => self.dht.handle_dht_req(packet, addr).await, + Packet::LanDiscovery(packet) => self.dht.handle_lan_discovery(&packet, addr).await, + Packet::OnionRequest0(packet) => self.dht.handle_onion_request_0(packet, addr).await, + Packet::OnionRequest1(packet) => self.dht.handle_onion_request_1(packet, addr).await, + Packet::OnionRequest2(packet) => self.dht.handle_onion_request_2(packet, addr).await, + Packet::OnionAnnounceRequest(packet) => self.dht.handle_onion_announce_request(packet, addr).await, + Packet::OnionDataRequest(packet) => self.dht.handle_onion_data_request(packet).await, + Packet::OnionResponse3(packet) => self.dht.handle_onion_response_3(packet).await, + Packet::OnionResponse2(packet) => self.dht.handle_onion_response_2(packet).await, + Packet::OnionResponse1(packet) => self.dht.handle_onion_response_1(packet).await, + Packet::BootstrapInfo(packet) => self.dht.handle_bootstrap_info(&packet, addr).await, + Packet::CryptoData(packet) => self.handle_crypto_data(&packet, addr).await, + Packet::OnionDataResponse(packet) => self.handle_onion_data_response(&packet).await, + Packet::OnionAnnounceResponse(packet) => self.handle_onion_announce_response(&packet, addr).await, } } /// Handle received `OnionDataResponse` packet and pass it to `onion_client` module. async fn handle_onion_data_response(&self, packet: &OnionDataResponse) -> Result<(), HandlePacketError> { if let Some(ref onion_client) = self.onion_client { - onion_client.handle_data_response(packet).await + onion_client + .handle_data_response(packet) + .await .map_err(HandlePacketError::HandleOnionClientData) } else { Err(HandlePacketError::OnionClient) @@ -93,9 +74,15 @@ impl Server { } /// Handle received `OnionAnnounceResponse` packet and pass it to `onion_client` module. - async fn handle_onion_announce_response(&self, packet: &OnionAnnounceResponse, addr: SocketAddr) -> Result<(), HandlePacketError> { + async fn handle_onion_announce_response( + &self, + packet: &OnionAnnounceResponse, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { if let Some(ref onion_client) = self.onion_client { - onion_client.handle_announce_response(packet, IsGlobal::is_global(&addr.ip())).await + onion_client + .handle_announce_response(packet, IsGlobal::is_global(&addr.ip())) + .await .map_err(HandlePacketError::HandleOnionClientAnnounce) } else { Err(HandlePacketError::OnionClient) @@ -109,10 +96,15 @@ impl Server { /// Handle received `CookieRequest` packet and pass it to `net_crypto` /// module. - pub async fn handle_cookie_request(&self, packet: &CookieRequest, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_cookie_request( + &self, + packet: &CookieRequest, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { if let Some(ref net_crypto) = self.net_crypto { - net_crypto.handle_udp_cookie_request(packet, addr).await + net_crypto + .handle_udp_cookie_request(packet, addr) + .await .map_err(HandlePacketError::HandleNetCrypto) } else { Err(HandlePacketError::NetCrypto) @@ -121,10 +113,15 @@ impl Server { /// Handle received `CookieResponse` packet and pass it to `net_crypto` /// module. - pub async fn handle_cookie_response(&self, packet: &CookieResponse, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_cookie_response( + &self, + packet: &CookieResponse, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { if let Some(ref net_crypto) = self.net_crypto { - net_crypto.handle_udp_cookie_response(packet, addr).await + net_crypto + .handle_udp_cookie_response(packet, addr) + .await .map_err(HandlePacketError::HandleNetCrypto) } else { Err(HandlePacketError::NetCrypto) @@ -133,10 +130,15 @@ impl Server { /// Handle received `CryptoHandshake` packet and pass it to `net_crypto` /// module. - pub async fn handle_crypto_handshake(&self, packet: &CryptoHandshake, addr: SocketAddr) - -> Result<(), HandlePacketError> { + pub async fn handle_crypto_handshake( + &self, + packet: &CryptoHandshake, + addr: SocketAddr, + ) -> Result<(), HandlePacketError> { if let Some(ref net_crypto) = self.net_crypto { - net_crypto.handle_udp_crypto_handshake(packet, addr).await + net_crypto + .handle_udp_crypto_handshake(packet, addr) + .await .map_err(HandlePacketError::HandleNetCrypto) } else { Err(HandlePacketError::NetCrypto) @@ -146,7 +148,9 @@ impl Server { /// Handle received `CryptoData` packet and pass it to `net_crypto` module. pub async fn handle_crypto_data(&self, packet: &CryptoData, addr: SocketAddr) -> Result<(), HandlePacketError> { if let Some(ref net_crypto) = self.net_crypto { - net_crypto.handle_udp_crypto_data(packet, addr).await + net_crypto + .handle_udp_crypto_data(packet, addr) + .await .map_err(HandlePacketError::HandleNetCrypto) } else { Err(HandlePacketError::NetCrypto) diff --git a/tox_crypto/src/lib.rs b/tox_crypto/src/lib.rs index dc1439da7..1a8b252fa 100644 --- a/tox_crypto/src/lib.rs +++ b/tox_crypto/src/lib.rs @@ -1,7 +1,7 @@ //! Functions for the core crypto. -use crypto_box::{SalsaBox, aead::generic_array::typenum::marker_traits::Unsigned}; use crypto_box::aead::AeadCore; +use crypto_box::{aead::generic_array::typenum::marker_traits::Unsigned, SalsaBox}; pub use crypto_box::{PublicKey, SecretKey}; pub type Nonce = [u8; ::NonceSize::USIZE]; @@ -37,7 +37,7 @@ pub fn increment_nonce(nonce: &mut Nonce) { /// Inrement given nonce by number `num`. pub fn increment_nonce_number(nonce: &mut Nonce, num: u16) { let mut c = num as u32; - for i in (0 .. NONCEBYTES).rev() { + for i in (0..NONCEBYTES).rev() { c += nonce[i] as u32; nonce[i] = c as u8; c >>= 8; @@ -50,9 +50,7 @@ pub mod tests { #[test] fn increment_nonce_test_zero_plus_one() { - let cmp_nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 1]; + let cmp_nonce = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]; let mut nonce = [0; NONCEBYTES]; increment_nonce(&mut nonce); @@ -61,26 +59,22 @@ pub mod tests { #[test] fn increment_nonce_test_0xf_plus_one() { - let cmp_nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0x10]; + let cmp_nonce = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10, + ]; - let mut nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xf]; + let mut nonce = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xf]; increment_nonce(&mut nonce); assert_eq!(nonce, cmp_nonce); } #[test] fn increment_nonce_test_0xff_plus_one() { - let cmp_nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 1, 0]; + let cmp_nonce = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]; - let mut nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0xff]; + let mut nonce = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, + ]; increment_nonce(&mut nonce); assert_eq!(nonce, cmp_nonce); } @@ -97,9 +91,9 @@ pub mod tests { #[test] fn increment_nonce_number_test_zero_plus_0xff00() { - let cmp_nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xff, 0]; + let cmp_nonce = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, + ]; let mut nonce = [0; NONCEBYTES]; increment_nonce_number(&mut nonce, 0xff00); @@ -108,13 +102,13 @@ pub mod tests { #[test] fn increment_nonce_number_test_0xff00_plus_0x0110() { - let cmp_nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 1, 0, 0x10]; + let cmp_nonce = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0x10, + ]; - let mut nonce = [0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0xff, 0]; + let mut nonce = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0, + ]; increment_nonce_number(&mut nonce, 0x01_10); assert_eq!(nonce, cmp_nonce); diff --git a/tox_encryptsave/src/lib.rs b/tox_encryptsave/src/lib.rs index b9a6652e7..a9b906e6d 100644 --- a/tox_encryptsave/src/lib.rs +++ b/tox_encryptsave/src/lib.rs @@ -23,10 +23,10 @@ assert_eq!(plaintext, use std::{convert::TryInto, ops::Deref}; -use thiserror::Error; -use rand::{Rng, thread_rng}; +use rand::{thread_rng, Rng}; use sha2::{Digest, Sha256}; -use xsalsa20poly1305::{XSalsa20Poly1305, KeyInit, aead::Aead}; +use thiserror::Error; +use xsalsa20poly1305::{aead::Aead, KeyInit, XSalsa20Poly1305}; use zeroize::Zeroizing; /// Length (in bytes) of [`MAGIC_NUMBER`](./constant.MAGIC_NUMBER.html). @@ -56,7 +56,7 @@ pub struct PassKey { // allocate stuff on heap to make sure that sensitive data is not moved // around on stack /// Key used to encrypt/decrypt data. **DO NOT SAVE**. - key: Box + key: Box, } impl PassKey { @@ -107,19 +107,16 @@ impl PassKey { ``` */ pub fn with_salt(passphrase: &[u8], salt: [u8; SALT_LENGTH]) -> Result { - if passphrase.is_empty() { return Err(KeyDerivationError::Null) }; + if passphrase.is_empty() { + return Err(KeyDerivationError::Null); + }; let passhash = Sha256::digest(passphrase); let mut key = Zeroizing::new([0; xsalsa20poly1305::KEY_SIZE]); // predefined params for tox encryptsave format let params = scrypt::Params::new(14, 8, 2, 32).unwrap(); - scrypt::scrypt( - &passhash, - &salt, - ¶ms, - &mut key[..], - ).or(Err(KeyDerivationError::Failed))?; + scrypt::scrypt(&passhash, &salt, ¶ms, &mut key[..]).or(Err(KeyDerivationError::Failed))?; let pass_key = PassKey { salt, @@ -151,7 +148,9 @@ impl PassKey { ``` */ pub fn encrypt(&self, data: &[u8]) -> Result, EncryptionError> { - if data.is_empty() { return Err(EncryptionError::Null) }; + if data.is_empty() { + return Err(EncryptionError::Null); + }; let mut output = Vec::with_capacity(EXTRA_LENGTH + data.len()); let nonce = XSalsa20Poly1305::generate_nonce(&mut thread_rng()); @@ -159,10 +158,7 @@ impl PassKey { output.extend_from_slice(MAGIC_NUMBER); output.extend_from_slice(&self.salt); output.extend_from_slice(&nonce); - output.append(&mut self.key.encrypt( - &nonce, - data - ).or(Err(EncryptionError::Null))?); + output.append(&mut self.key.encrypt(&nonce, data).or(Err(EncryptionError::Null))?); Ok(output) } @@ -195,14 +191,23 @@ impl PassKey { ``` */ pub fn decrypt(&self, data: &[u8]) -> Result, DecryptionError> { - if data.is_empty() { return Err(DecryptionError::Null) }; - if data.len() <= EXTRA_LENGTH { return Err(DecryptionError::InvalidLength) }; - if !is_encrypted(data) { return Err(DecryptionError::BadFormat) }; + if data.is_empty() { + return Err(DecryptionError::Null); + }; + if data.len() <= EXTRA_LENGTH { + return Err(DecryptionError::InvalidLength); + }; + if !is_encrypted(data) { + return Err(DecryptionError::BadFormat); + }; - let output = self.key.decrypt( - (&data[MAGIC_LENGTH+SALT_LENGTH..MAGIC_LENGTH+SALT_LENGTH+xsalsa20poly1305::NONCE_SIZE]).into(), - &data[MAGIC_LENGTH+SALT_LENGTH+xsalsa20poly1305::NONCE_SIZE..] - ).or(Err(DecryptionError::Failed))?; + let output = self + .key + .decrypt( + (&data[MAGIC_LENGTH + SALT_LENGTH..MAGIC_LENGTH + SALT_LENGTH + xsalsa20poly1305::NONCE_SIZE]).into(), + &data[MAGIC_LENGTH + SALT_LENGTH + xsalsa20poly1305::NONCE_SIZE..], + ) + .or(Err(DecryptionError::Failed))?; Ok(output) } @@ -297,9 +302,15 @@ for pos in 0..MAGIC_LENGTH { ``` */ pub fn pass_decrypt(data: &[u8], passphrase: &[u8]) -> Result, DecryptionError> { - if data.is_empty() { return Err(DecryptionError::Null) } - if data.len() <= EXTRA_LENGTH { return Err(DecryptionError::InvalidLength) } - if !is_encrypted(data) { return Err(DecryptionError::BadFormat) } + if data.is_empty() { + return Err(DecryptionError::Null); + } + if data.len() <= EXTRA_LENGTH { + return Err(DecryptionError::InvalidLength); + } + if !is_encrypted(data) { + return Err(DecryptionError::BadFormat); + } let salt = get_salt(data).ok_or(KeyDerivationError::Failed)?; PassKey::with_salt(passphrase, salt)?.decrypt(data) @@ -321,10 +332,8 @@ assert_eq!(get_salt(&[]), None); ``` */ pub fn get_salt(data: &[u8]) -> Option<[u8; SALT_LENGTH]> { - if is_encrypted(data) - && data.len() >= MAGIC_LENGTH + SALT_LENGTH - { - data[MAGIC_LENGTH..MAGIC_LENGTH+SALT_LENGTH].try_into().ok() + if is_encrypted(data) && data.len() >= MAGIC_LENGTH + SALT_LENGTH { + data[MAGIC_LENGTH..MAGIC_LENGTH + SALT_LENGTH].try_into().ok() } else { None } @@ -338,7 +347,7 @@ pub enum KeyDerivationError { Null, /// Failed to derive key, most likely due to OOM. #[error("Failed to derive key, most likely due to OOM")] - Failed + Failed, } /// Error encrypting data. @@ -386,7 +395,7 @@ pub enum DecryptionError { * some bytes that aren't encrypted were provided after encrypted bytes */ #[error("Failure due to encrypted data being invalid")] - Failed + Failed, } impl From for DecryptionError { @@ -395,7 +404,6 @@ impl From for DecryptionError { } } - // PassKey:: // PassKey::new() diff --git a/tox_encryptsave/tests/encryptsave_tests.rs b/tox_encryptsave/tests/encryptsave_tests.rs index d8f0d361d..24e7ee7d8 100644 --- a/tox_encryptsave/tests/encryptsave_tests.rs +++ b/tox_encryptsave/tests/encryptsave_tests.rs @@ -7,7 +7,6 @@ fn is_encrypted_test() { assert!(is_encrypted(include_bytes!("ciphertext"))); } - #[test] fn pass_encrypt_error_test() { // empty data @@ -26,7 +25,10 @@ fn pass_encrypt_test() { assert!(is_encrypted(&encrypted)); assert_eq!(plaintext.len() + EXTRA_LENGTH, encrypted.len()); - assert_eq!(&plaintext as &[u8], &pass_decrypt(&encrypted, &passphrase).unwrap() as &[u8]); + assert_eq!( + &plaintext as &[u8], + &pass_decrypt(&encrypted, &passphrase).unwrap() as &[u8] + ); let encrypted2 = pass_encrypt(&plaintext, &passphrase).unwrap(); assert_ne!(encrypted, encrypted2); @@ -68,7 +70,10 @@ fn pass_decrypt_error_failed_test() { let mut bad_ciphertext = Vec::with_capacity(EXTRA_LENGTH + 123); bad_ciphertext.extend_from_slice(&ciphertext[..EXTRA_LENGTH]); bad_ciphertext.extend_from_slice(&[42; 123]); - assert_eq!(pass_decrypt(&bad_ciphertext, b"encryptsave"), Err(DecryptionError::Failed)); + assert_eq!( + pass_decrypt(&bad_ciphertext, b"encryptsave"), + Err(DecryptionError::Failed) + ); } #[test] @@ -77,16 +82,13 @@ fn pass_decrypt_test() { let plaintext = b"Hello world.\n"; let ciphertext = include_bytes!("ciphertext"); - assert_eq!( - pass_decrypt(ciphertext, passphrase).unwrap(), - plaintext - ); + assert_eq!(pass_decrypt(ciphertext, passphrase).unwrap(), plaintext); } #[test] fn get_salt_test() { let ciphertext = include_bytes!("ciphertext"); - let salt = &ciphertext[MAGIC_LENGTH .. MAGIC_LENGTH + SALT_LENGTH]; + let salt = &ciphertext[MAGIC_LENGTH..MAGIC_LENGTH + SALT_LENGTH]; assert_eq!(get_salt(ciphertext).unwrap(), salt); } diff --git a/tox_node/src/main.rs b/tox_node/src/main.rs index 0184ff631..32dfa0a8d 100644 --- a/tox_node/src/main.rs +++ b/tox_node/src/main.rs @@ -1,12 +1,12 @@ -#![type_length_limit="65995950"] +#![type_length_limit = "65995950"] #[macro_use] extern crate clap; #[macro_use] extern crate log; -mod node_config; mod motd; +mod node_config; use std::convert::TryInto; use std::fs::File; @@ -15,25 +15,25 @@ use std::net::SocketAddr; use anyhow::Error; use futures::{channel::mpsc, StreamExt}; -use futures::{future, Future, TryFutureExt, FutureExt}; +use futures::{future, Future, FutureExt, TryFutureExt}; use itertools::Itertools; use rand::thread_rng; +#[cfg(unix)] +use syslog::Facility; use tokio::net::{TcpListener, UdpSocket}; use tokio::runtime; -use tox::crypto::*; +use tox::core::dht::lan_discovery::LanDiscoverySender; use tox::core::dht::server::Server as DhtServer; use tox::core::dht::server_ext::dht_run_socket; -use tox::core::dht::lan_discovery::LanDiscoverySender; +use tox::core::relay::server::{tcp_run, Server as TcpServer}; +use tox::core::stats::Stats; use tox::core::udp::Server as UdpServer; +use tox::crypto::*; use tox::packet::onion::InnerOnionResponse; use tox::packet::relay::OnionRequest; -use tox::core::relay::server::{Server as TcpServer, tcp_run}; -use tox::core::stats::Stats; -#[cfg(unix)] -use syslog::Facility; +use crate::motd::{Counters, Motd}; use crate::node_config::*; -use crate::motd::{Motd, Counters}; /// Channel size for onion messages between UDP and TCP relay. const ONION_CHANNEL_SIZE: usize = 32; @@ -59,7 +59,9 @@ async fn bind_socket(addr: SocketAddr) -> UdpSocket { let socket = UdpSocket::bind(&addr).await.expect("Failed to bind UDP socket"); socket.set_broadcast(true).expect("set_broadcast call failed"); if addr.is_ipv6() { - socket.set_multicast_loop_v6(true).expect("set_multicast_loop_v6 call failed"); + socket + .set_multicast_loop_v6(true) + .expect("set_multicast_loop_v6 call failed"); } socket } @@ -80,19 +82,29 @@ fn save_keys(keys_file: &str, pk: PublicKey, sk: &SecretKey) { .open(keys_file) .expect("Failed to create the keys file"); - file.write_all(pk.as_ref()).expect("Failed to save public key to the keys file"); - file.write_all(sk.as_bytes()).expect("Failed to save secret key to the keys file"); + file.write_all(pk.as_ref()) + .expect("Failed to save public key to the keys file"); + file.write_all(sk.as_bytes()) + .expect("Failed to save secret key to the keys file"); } /// Load DHT keys from a binary file. fn load_keys(mut file: File) -> (PublicKey, SecretKey) { let mut buf = [0; crypto_box::KEY_SIZE * 2]; - file.read_exact(&mut buf).expect("Failed to read keys from the keys file"); - let pk_bytes: [u8; crypto_box::KEY_SIZE] = buf[..crypto_box::KEY_SIZE].try_into().expect("Failed to read public key from the keys file"); - let sk_bytes: [u8; crypto_box::KEY_SIZE] = buf[crypto_box::KEY_SIZE..].try_into().expect("Failed to read secret key from the keys file"); + file.read_exact(&mut buf) + .expect("Failed to read keys from the keys file"); + let pk_bytes: [u8; crypto_box::KEY_SIZE] = buf[..crypto_box::KEY_SIZE] + .try_into() + .expect("Failed to read public key from the keys file"); + let sk_bytes: [u8; crypto_box::KEY_SIZE] = buf[crypto_box::KEY_SIZE..] + .try_into() + .expect("Failed to read secret key from the keys file"); let pk = PublicKey::from(pk_bytes); let sk = SecretKey::from(sk_bytes); - assert!(pk == sk.public_key(), "The loaded public key does not correspond to the loaded secret key"); + assert!( + pk == sk.public_key(), + "The loaded public key does not correspond to the loaded secret key" + ); (pk, sk) } @@ -107,14 +119,15 @@ fn load_or_gen_keys(keys_file: &str) -> (PublicKey, SecretKey) { let pk = sk.public_key(); save_keys(keys_file, pk.clone(), &sk); (pk, sk) - }, - Err(e) => panic!("Failed to read the keys file: {}", e) + } + Err(e) => panic!("Failed to read the keys file: {}", e), } } /// Run a future with the runtime specified by config. fn run(future: F, threads: Threads) - where F: Future> + 'static +where + F: Future> + 'static, { if threads == Threads::N(1) { let runtime = runtime::Runtime::new().expect("Failed to create runtime"); @@ -122,12 +135,12 @@ fn run(future: F, threads: Threads) } else { let mut builder = runtime::Builder::new_multi_thread(); match threads { - Threads::N(n) => { builder.worker_threads(n as usize); }, - Threads::Auto => { }, // builder will detect number of cores automatically + Threads::N(n) => { + builder.worker_threads(n as usize); + } + Threads::Auto => {} // builder will detect number of cores automatically } - let runtime = builder - .build() - .expect("Failed to create runtime"); + let runtime = builder.build().expect("Failed to create runtime"); runtime.block_on(future).expect("Execution was terminated with error"); }; } @@ -169,7 +182,7 @@ async fn run_tcp(config: &NodeConfig, dht_sk: SecretKey, mut tcp_onion: TcpOnion // all onion packets from DHT server while tcp_onion.rx.next().await.is_some() {} - return Ok(()) + return Ok(()); } let onion_tx = tcp_onion.tx; @@ -185,17 +198,20 @@ async fn run_tcp(config: &NodeConfig, dht_sk: SecretKey, mut tcp_onion: TcpOnion let dht_sk = dht_sk.clone(); async move { let listener = TcpListener::bind(&addr).await.expect("Failed to bind TCP listener"); - tcp_run(&tcp_server_c, listener, dht_sk, stats.clone(), config.tcp_connections_limit) - .await - .map_err(Error::from) - }.boxed() + tcp_run( + &tcp_server_c, + listener, + dht_sk, + stats.clone(), + config.tcp_connections_limit, + ) + .await + .map_err(Error::from) + } + .boxed() }); - let tcp_server_future = async { - future::select_all(tcp_server_futures) - .await - .0 - }; + let tcp_server_future = async { future::select_all(tcp_server_futures).await.0 }; // let tcp_onion_rx = tcp_onion.rx.clone() let tcp_onion_future = async { @@ -219,7 +235,13 @@ async fn run_tcp(config: &NodeConfig, dht_sk: SecretKey, mut tcp_onion: TcpOnion Ok(()) } -async fn run_udp(config: &NodeConfig, dht_pk: PublicKey, dht_sk: &SecretKey, mut udp_onion: UdpOnion, tcp_stats: Stats) -> Result<(), Error> { +async fn run_udp( + config: &NodeConfig, + dht_pk: PublicKey, + dht_sk: &SecretKey, + mut udp_onion: UdpOnion, + tcp_stats: Stats, +) -> Result<(), Error> { let udp_addr = if let Some(udp_addr) = config.udp_addr { udp_addr } else { @@ -227,7 +249,7 @@ async fn run_udp(config: &NodeConfig, dht_pk: PublicKey, dht_sk: &SecretKey, mut // all onion packets from TCP server while udp_onion.rx.next().await.is_some() {} - return Ok(()) + return Ok(()); }; let socket = bind_socket(udp_addr).await; @@ -244,8 +266,9 @@ async fn run_udp(config: &NodeConfig, dht_pk: PublicKey, dht_sk: &SecretKey, mut .run() .map_err(Error::from) .await + } else { + Ok(()) } - else { Ok(()) } }; let (onion_tx, mut onion_rx) = (udp_onion.tx, udp_onion.rx); @@ -261,9 +284,7 @@ async fn run_udp(config: &NodeConfig, dht_pk: PublicKey, dht_sk: &SecretKey, mut let dht_server_c = dht_server.clone(); let udp_onion_future = async move { while let Some((onion_request, addr)) = onion_rx.next().await { - let res = dht_server_c - .handle_tcp_onion_request(onion_request, addr) - .await; + let res = dht_server_c.handle_tcp_onion_request(onion_request, addr).await; if let Err(err) = res { warn!("Failed to handle TCP onion request: {:?}", err); @@ -297,24 +318,21 @@ fn main() { match config.log_type { LogType::Stderr => { - let env = env_logger::Env::default() - .filter_or("RUST_LOG", "info"); - env_logger::Builder::from_env(env) - .init(); - }, + let env = env_logger::Env::default().filter_or("RUST_LOG", "info"); + env_logger::Builder::from_env(env).init(); + } LogType::Stdout => { - let env = env_logger::Env::default() - .filter_or("RUST_LOG", "info"); + let env = env_logger::Env::default().filter_or("RUST_LOG", "info"); env_logger::Builder::from_env(env) .target(env_logger::fmt::Target::Stdout) .init(); - }, + } #[cfg(unix)] LogType::Syslog => { syslog::init(Facility::LOG_USER, log::LevelFilter::Info, None) .expect("Failed to initialize syslog backend."); - }, - LogType::None => { }, + } + LogType::None => {} } for key in config.unused.keys() { @@ -334,8 +352,10 @@ fn main() { } if config.sk_passed_as_arg { - warn!("You should not pass the secret key via arguments due to \ - security reasons. Use the environment variable instead"); + warn!( + "You should not pass the secret key via arguments due to \ + security reasons. Use the environment variable instead" + ); } info!("DHT public key: {}", hex::encode(dht_pk.as_ref()).to_uppercase()); @@ -347,15 +367,12 @@ fn main() { let udp_config = config.clone(); let udp_dht_sk = dht_sk.clone(); - let udp_server_future = async move { - run_udp(&udp_config, dht_pk, &udp_dht_sk, udp_onion, udp_tcp_stats.clone()).await - }; + let udp_server_future = + async move { run_udp(&udp_config, dht_pk, &udp_dht_sk, udp_onion, udp_tcp_stats.clone()).await }; let tcp_config = config.clone(); let tcp_dht_sk = dht_sk; - let tcp_server_future = async move { - run_tcp(&tcp_config, tcp_dht_sk, tcp_onion, tcp_tcp_stats).await - }; + let tcp_server_future = async move { run_tcp(&tcp_config, tcp_dht_sk, tcp_onion, tcp_tcp_stats).await }; let future = async move { futures::select! { diff --git a/tox_node/src/motd.rs b/tox_node/src/motd.rs index 2d74c1403..69964c95c 100644 --- a/tox_node/src/motd.rs +++ b/tox_node/src/motd.rs @@ -10,10 +10,7 @@ pub struct Counters { impl Counters { pub fn new(tcp: Stats, udp: Stats) -> Self { - Counters { - tcp, - udp, - } + Counters { tcp, udp } } } @@ -34,7 +31,7 @@ impl Motd { fn format_n(source: u64) -> String { match source { - 0..=999 => format!("{}",source), + 0..=999 => format!("{}", source), 1_000..=999_999 => format!("{0:.1}K", source as f32 / 1_000.0), 1_000_000..=999_999_999 => format!("{0:.1}M", source as f32 / 1_000_000.0), 1_000_000_000..=999_999_999_999 => format!("{0:.1}G", source as f32 / 1_000_000_000.0), @@ -44,9 +41,7 @@ impl Motd { pub fn format(&self) -> String { let start_date = { - let format = time::format_description::parse( - "[year]-[month]-[day] [hour]:[minute]:[second]", - ).unwrap(); + let format = time::format_description::parse("[year]-[month]-[day] [hour]:[minute]:[second]").unwrap(); self.start_date.format(&format).unwrap() }; @@ -55,12 +50,7 @@ impl Motd { let days = uptime.whole_days(); let hours = uptime.whole_hours() - uptime.whole_days() * 24; let minutes = uptime.whole_minutes() / 60 - uptime.whole_hours() * 60; - format!( - "{:0>#2} days {:0>#2} hours {:0>#2} minutes", - days, - hours, - minutes - ) + format!("{:0>#2} days {:0>#2} hours {:0>#2} minutes", days, hours, minutes) }; let tcp_packets_in = Self::format_n(self.counters.tcp.counters.incoming()); diff --git a/tox_node/src/node_config.rs b/tox_node/src/node_config.rs index c65d28175..3cbb99885 100644 --- a/tox_node/src/node_config.rs +++ b/tox_node/src/node_config.rs @@ -1,15 +1,18 @@ +use std::collections::HashMap; use std::convert::TryInto; use std::net::{SocketAddr, ToSocketAddrs}; use std::num::ParseIntError; use std::str::FromStr; -use std::collections::HashMap; +use clap::{ + builder::{ArgPredicate, PossibleValue}, + value_parser, Arg, ArgAction, ArgGroup, ArgMatches, Command, ValueEnum, +}; use config::{Config, File as CfgFile, FileFormat as CfgFileFormat}; -use serde::{de, Deserialize, Deserializer}; -use serde_yaml::Value; -use clap::{Arg, ArgAction, ArgGroup, ArgMatches, builder::{ArgPredicate, PossibleValue}, Command, ValueEnum, value_parser}; use hex::FromHex; use itertools::Itertools; +use serde::{de, Deserialize, Deserializer}; +use serde_yaml::Value; use tox::crypto::*; use tox::packet::dht::packed_node::PackedNode; use tox::packet::dht::BOOSTRAP_SERVER_MAX_MOTD_LENGTH; @@ -20,7 +23,7 @@ pub enum Threads { /// Detect number of threads automatically by the number of CPU cores. Auto, /// Exact number of threads. - N(u16) + N(u16), } impl FromStr for Threads { @@ -89,25 +92,30 @@ impl BootstrapNode { Err(e) => { warn!("Failed to resolve bootstrap node address '{}': {}", self.addr, e); Vec::new().into_iter() - }, + } }; addrs.map(move |addr| PackedNode::new(addr, pk.clone())) } } -fn de_from_hex<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { +fn de_from_hex<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ let s = String::deserialize(deserializer)?; - let bootstrap_pk_bytes: [u8; 32] = FromHex::from_hex(s) - .map_err(|e| de::Error::custom(format!("Can't make bytes from hex string {:?}", e)))?; + let bootstrap_pk_bytes: [u8; 32] = + FromHex::from_hex(s).map_err(|e| de::Error::custom(format!("Can't make bytes from hex string {:?}", e)))?; Ok(PublicKey::from(bootstrap_pk_bytes)) } -fn de_threads<'de, D>(deserializer: D) -> Result where D: Deserializer<'de> { +fn de_threads<'de, D>(deserializer: D) -> Result +where + D: Deserializer<'de>, +{ let s = String::deserialize(deserializer)?; - Threads::from_str(&s) - .map_err(|e| de::Error::custom(format!("threads: {:?}", e))) + Threads::from_str(&s).map_err(|e| de::Error::custom(format!("threads: {:?}", e))) } /// Config parsed from command line arguments. @@ -160,10 +168,12 @@ fn create_sk_arg() -> Arg { Arg::new("secret-key") .short('s') .long("secret-key") - .help("DHT secret key. Note that you should not pass the key via \ + .help( + "DHT secret key. Note that you should not pass the key via \ arguments due to security reasons. Use this argument for \ test purposes only. In the real world use the environment \ - variable instead") + variable instead", + ) .num_args(1) .conflicts_with("keys-file") .env("TOX_SECRET_KEY") @@ -285,11 +295,16 @@ pub fn cli_parse() -> NodeConfig { /// Parse settings from a saved file. fn parse_config(config_path: &str) -> NodeConfig { let config_builder = Config::builder() - .set_default("log-type", "Stderr").expect("Can't set default value for `log-type`") - .set_default("motd", "This is tox-rs").expect("Can't set default value for `motd`") - .set_default("lan-discovery", "False").expect("Can't set default value for `lan-discovery`") - .set_default("threads", "1").expect("Can't set default value for `threads`") - .set_default("tcp-connections-limit", "512").expect("Can't set default value for `tcp-connections-limit`") + .set_default("log-type", "Stderr") + .expect("Can't set default value for `log-type`") + .set_default("motd", "This is tox-rs") + .expect("Can't set default value for `motd`") + .set_default("lan-discovery", "False") + .expect("Can't set default value for `lan-discovery`") + .set_default("threads", "1") + .expect("Can't set default value for `threads`") + .set_default("tcp-connections-limit", "512") + .expect("Can't set default value for `tcp-connections-limit`") .add_source(CfgFile::new(config_path, CfgFileFormat::Yaml)); let config_file = match config_builder.build() { @@ -309,8 +324,10 @@ fn parse_config(config_path: &str) -> NodeConfig { fn run_derive_pk(matches: &ArgMatches) -> ! { let sk_passed_as_arg = matches.contains_id("secret-key"); if sk_passed_as_arg { - panic!("You should not pass the secret key via arguments due to \ - security reasons. Use the environment variable instead"); + panic!( + "You should not pass the secret key via arguments due to \ + security reasons. Use the environment variable instead" + ); } let pk_from_arg = matches.get_one::("secret-key").map(|s| { @@ -322,12 +339,20 @@ fn run_derive_pk(matches: &ArgMatches) -> ! { let mut buf = [0; crypto_box::KEY_SIZE * 2]; use std::io::Read; - file.read_exact(&mut buf).expect("Failed to read keys from the keys file"); - let pk_bytes: [u8; crypto_box::KEY_SIZE] = buf[..crypto_box::KEY_SIZE].try_into().expect("Failed to read public key from the keys file"); - let sk_bytes: [u8; crypto_box::KEY_SIZE] = buf[crypto_box::KEY_SIZE..].try_into().expect("Failed to read secret key from the keys file"); + file.read_exact(&mut buf) + .expect("Failed to read keys from the keys file"); + let pk_bytes: [u8; crypto_box::KEY_SIZE] = buf[..crypto_box::KEY_SIZE] + .try_into() + .expect("Failed to read public key from the keys file"); + let sk_bytes: [u8; crypto_box::KEY_SIZE] = buf[crypto_box::KEY_SIZE..] + .try_into() + .expect("Failed to read secret key from the keys file"); let pk = PublicKey::from(pk_bytes); let sk = SecretKey::from(sk_bytes); - assert!(pk == sk.public_key(), "The loaded public key does not correspond to the loaded secret key"); + assert!( + pk == sk.public_key(), + "The loaded public key does not correspond to the loaded secret key" + ); pk }); @@ -351,7 +376,9 @@ fn run_args(matches: &ArgMatches) -> NodeConfig { let tcp_addrs: Vec = matches.get_many("tcp-address").unwrap_or_default().copied().collect(); - let tcp_connections_limit = matches.get_one::("tcp-connections-limit").copied() + let tcp_connections_limit = matches + .get_one::("tcp-connections-limit") + .copied() .unwrap_or(512); let sk = matches.get_one::("secret-key").map(|s| { @@ -412,13 +439,7 @@ mod tests { #[test] fn args_udp_only() { let saddr = "127.0.0.1:33445"; - let matches = app().get_matches_from(vec![ - "tox-node", - "--keys-file", - "./keys", - "--udp-address", - saddr, - ]); + let matches = app().get_matches_from(vec!["tox-node", "--keys-file", "./keys", "--udp-address", saddr]); let config = run_args(&matches); assert_eq!(config.keys_file.unwrap(), "./keys"); assert_eq!(config.udp_addr.unwrap(), saddr.parse().unwrap()); @@ -442,10 +463,10 @@ mod tests { let config = run_args(&matches); assert_eq!(config.keys_file.unwrap(), "./keys"); assert!(config.udp_addr.is_none()); - assert_eq!(config.tcp_addrs, vec![ - saddr_1.parse().unwrap(), - saddr_2.parse().unwrap() - ]); + assert_eq!( + config.tcp_addrs, + vec![saddr_1.parse().unwrap(), saddr_2.parse().unwrap()] + ); assert!(!config.lan_discovery_enabled); } @@ -492,21 +513,13 @@ mod tests { #[test] fn args_udp_or_tcp_required() { - let matches = app().try_get_matches_from(vec![ - "tox-node", - "--keys-file", - "./keys", - ]); + let matches = app().try_get_matches_from(vec!["tox-node", "--keys-file", "./keys"]); assert!(matches.is_err()); } #[test] fn args_keys_file_or_secret_key_required() { - let matches = app().try_get_matches_from(vec![ - "tox-node", - "--udp-address", - "127.0.0.1:33445", - ]); + let matches = app().try_get_matches_from(vec!["tox-node", "--udp-address", "127.0.0.1:33445"]); assert!(matches.is_err()); } @@ -615,7 +628,7 @@ mod tests { "--udp-address", "127.0.0.1:33445", "--log-type", - "None" + "None", ]); let config = run_args(&matches); assert_eq!(config.log_type, LogType::None); @@ -630,7 +643,7 @@ mod tests { "--tcp-address", "127.0.0.1:33445", "--tcp-connections-limit", - "42" + "42", ]); let config = run_args(&matches); assert_eq!(config.tcp_connections_limit, 42); @@ -645,7 +658,7 @@ mod tests { "--udp-address", "127.0.0.1:33445", "--tcp-connections-limit", - "42" + "42", ]); assert!(matches.is_err()); } @@ -659,7 +672,7 @@ mod tests { "--udp-address", "127.0.0.1:33445", "--threads", - "42" + "42", ]); let config = run_args(&matches); assert_eq!(config.threads, Threads::N(42)); @@ -667,12 +680,7 @@ mod tests { #[test] fn args_derive_pk_keys_file() { - let matches = app().get_matches_from(vec![ - "tox-node", - "derive-pk", - "--keys-file", - "./keys", - ]); + let matches = app().get_matches_from(vec!["tox-node", "derive-pk", "--keys-file", "./keys"]); let matches = matches.subcommand_matches("derive-pk").unwrap(); assert_eq!("./keys", matches.get_one::("keys-file").unwrap()); } @@ -680,12 +688,7 @@ mod tests { #[test] fn args_derive_pk_secret_key() { let sk_str = "d7f04a6db2c12f1eae0229c72e6bc429ca894541acc5f292da0e4d9a47827774"; - let matches = app().get_matches_from(vec![ - "tox-node", - "derive-pk", - "--secret-key", - sk_str - ]); + let matches = app().get_matches_from(vec!["tox-node", "derive-pk", "--secret-key", sk_str]); let matches = matches.subcommand_matches("derive-pk").unwrap(); assert_eq!(sk_str, matches.get_one::("secret-key").unwrap()); } diff --git a/tox_packet/src/dht/bootstrap_info.rs b/tox_packet/src/dht/bootstrap_info.rs index f3bd0c521..f6e3c324d 100644 --- a/tox_packet/src/dht/bootstrap_info.rs +++ b/tox_packet/src/dht/bootstrap_info.rs @@ -3,14 +3,11 @@ use super::*; -use nom::{ - number::complete::be_u32, - combinator::rest -}; +use nom::{combinator::rest, number::complete::be_u32}; -use tox_binary_io::*; -use nom::combinator::verify; use nom::bytes::complete::tag; +use nom::combinator::verify; +use tox_binary_io::*; /** Sent by both client and server, only server will respond. When server receives this packet it may respond with the version of the library @@ -49,6 +46,7 @@ pub const BOOSTRAP_SERVER_MAX_MOTD_LENGTH: usize = 256; pub const BOOSTRAP_CLIENT_MAX_MOTD_LENGTH: usize = 73; impl ToBytes for BootstrapInfo { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0xf0) >> @@ -63,7 +61,13 @@ impl FromBytes for BootstrapInfo { let (input, _) = tag(&[0xf0][..])(input)?; let (input, version) = be_u32(input)?; let (input, motd) = verify(rest, |motd: &[u8]| motd.len() <= BOOSTRAP_SERVER_MAX_MOTD_LENGTH)(input)?; - Ok((input, BootstrapInfo { version, motd: motd.to_vec() })) + Ok(( + input, + BootstrapInfo { + version, + motd: motd.to_vec(), + }, + )) } } @@ -75,7 +79,7 @@ mod tests { bootstrap_info_encode_decode, BootstrapInfo { version: 1717, - motd: vec![1,2,3,4], + motd: vec![1, 2, 3, 4], } ); } diff --git a/tox_packet/src/dht/cookie.rs b/tox_packet/src/dht/cookie.rs index 294d023ed..18a8b8447 100644 --- a/tox_packet/src/dht/cookie.rs +++ b/tox_packet/src/dht/cookie.rs @@ -2,20 +2,23 @@ */ use super::*; -use nom::number::complete::be_u64; -use nom::combinator::eof; use nom::bytes::complete::take; -use sha2::{Digest, Sha512}; +use nom::combinator::eof; +use nom::number::complete::be_u64; +use rand::{CryptoRng, Rng}; use sha2::digest::typenum::Unsigned; use sha2::digest::OutputSizeUser; -use xsalsa20poly1305::{XSalsa20Poly1305, aead::{Aead, Error as AeadError}}; -use rand::{CryptoRng, Rng}; +use sha2::{Digest, Sha512}; +use xsalsa20poly1305::{ + aead::{Aead, Error as AeadError}, + XSalsa20Poly1305, +}; use std::{convert::TryInto, time::SystemTime}; +use crate::dht::errors::*; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::errors::*; /// Number of seconds that generated cookie is valid pub const COOKIE_TIMEOUT: u64 = 15; @@ -88,6 +91,7 @@ impl FromBytes for Cookie { } impl ToBytes for Cookie { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u64!(self.time) >> @@ -119,11 +123,18 @@ impl FromBytes for EncryptedCookie { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, nonce) = <[u8; xsalsa20poly1305::NONCE_SIZE]>::from_bytes(input)?; let (input, payload) = take(88usize)(input)?; - Ok((input, EncryptedCookie { nonce, payload: payload.to_vec() })) + Ok(( + input, + EncryptedCookie { + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for EncryptedCookie { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.nonce.as_ref()) >> @@ -153,17 +164,12 @@ impl EncryptedCookie { - fails to parse `Cookie` */ pub fn get_payload(&self, symmetric_key: &XSalsa20Poly1305) -> Result { - let decrypted = symmetric_key.decrypt(&self.nonce.into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = symmetric_key + .decrypt(&self.nonce.into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match Cookie::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } /// Calculate SHA512 hash of encrypted cookie together with nonce @@ -178,8 +184,11 @@ impl EncryptedCookie { #[cfg(test)] mod tests { use super::*; + use nom::{ + error::{Error, ErrorKind}, + Err, + }; use rand::thread_rng; - use nom::{Err, error::{Error, ErrorKind}}; use xsalsa20poly1305::KeyInit; encode_decode_test!( @@ -203,7 +212,10 @@ mod tests { fn cookie_encrypt_decrypt() { let mut rng = thread_rng(); let symmetric_key = XSalsa20Poly1305::new(&XSalsa20Poly1305::generate_key(&mut rng)); - let payload = Cookie::new(SecretKey::generate(&mut rng).public_key(), SecretKey::generate(&mut rng).public_key()); + let payload = Cookie::new( + SecretKey::generate(&mut rng).public_key(), + SecretKey::generate(&mut rng).public_key(), + ); // encode payload with symmetric key let encrypted_cookie = EncryptedCookie::new(&mut rng, &symmetric_key, &payload); // decode payload with symmetric key @@ -217,7 +229,10 @@ mod tests { let mut rng = thread_rng(); let symmetric_key = XSalsa20Poly1305::new(&XSalsa20Poly1305::generate_key(&mut rng)); let eve_symmetric_key = XSalsa20Poly1305::new(&XSalsa20Poly1305::generate_key(&mut rng)); - let payload = Cookie::new(SecretKey::generate(&mut rng).public_key(), SecretKey::generate(&mut rng).public_key()); + let payload = Cookie::new( + SecretKey::generate(&mut rng).public_key(), + SecretKey::generate(&mut rng).public_key(), + ); // encode payload with symmetric key let encrypted_cookie = EncryptedCookie::new(&mut rng, &symmetric_key, &payload); // try to decode payload with eve's symmetric key @@ -236,33 +251,42 @@ mod tests { let invalid_payload_encoded = symmetric_key.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_encrypted_cookie = EncryptedCookie { nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_encrypted_cookie.get_payload(&symmetric_key); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Error(Error::new(vec![42; 51], ErrorKind::Eof)), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Error(Error::new(vec![42; 51], ErrorKind::Eof)), + payload: invalid_payload.to_vec() + } + ); // Try short incomplete array let invalid_payload = []; let invalid_payload_encoded = symmetric_key.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_encrypted_cookie = EncryptedCookie { nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_encrypted_cookie.get_payload(&symmetric_key); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Error(Error::new(vec![], ErrorKind::Eof)), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Error(Error::new(vec![], ErrorKind::Eof)), + payload: invalid_payload.to_vec() + } + ); } #[test] fn cookie_timed_out() { let mut rng = thread_rng(); - let mut cookie = Cookie::new(SecretKey::generate(&mut rng).public_key(), SecretKey::generate(&mut rng).public_key()); + let mut cookie = Cookie::new( + SecretKey::generate(&mut rng).public_key(), + SecretKey::generate(&mut rng).public_key(), + ); assert!(!cookie.is_timed_out()); cookie.time -= COOKIE_TIMEOUT + 1; assert!(cookie.is_timed_out()); @@ -274,16 +298,16 @@ mod tests { let payload = vec![42; 88]; let cookie = EncryptedCookie { nonce, - payload: payload.clone() + payload: payload.clone(), }; let cookie_1 = EncryptedCookie { nonce, - payload: vec![43; 88] + payload: vec![43; 88], }; let cookie_2 = EncryptedCookie { nonce: [43; xsalsa20poly1305::NONCE_SIZE], - payload + payload, }; assert_ne!(cookie.hash(), cookie_1.hash()); diff --git a/tox_packet/src/dht/cookie_request.rs b/tox_packet/src/dht/cookie_request.rs index ddaf5a9a2..9821d07cb 100644 --- a/tox_packet/src/dht/cookie_request.rs +++ b/tox_packet/src/dht/cookie_request.rs @@ -5,13 +5,13 @@ use super::*; use aead::{Aead, AeadCore, Error as AeadError}; use crypto_box::SalsaBox; -use nom::number::complete::be_u64; use nom::bytes::complete::{tag, take}; use nom::combinator::eof; +use nom::number::complete::be_u64; +use crate::dht::errors::*; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::errors::*; /** CookieRequest packet struct. According to https://zetok.github.io/tox-spec/#net-crypto @@ -50,6 +50,7 @@ pub struct CookieRequest { } impl ToBytes for CookieRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x18) >> @@ -66,7 +67,14 @@ impl FromBytes for CookieRequest { let (input, pk) = PublicKey::from_bytes(input)?; let (input, nonce) = Nonce::from_bytes(input)?; let (input, payload) = take(88usize)(input)?; - Ok((input, CookieRequest { pk, nonce, payload: payload.to_vec() })) + Ok(( + input, + CookieRequest { + pk, + nonce, + payload: payload.to_vec(), + }, + )) } } @@ -92,17 +100,12 @@ impl CookieRequest { - fails to parse `CookieRequestPayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match CookieRequestPayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -128,6 +131,7 @@ pub struct CookieRequestPayload { } impl ToBytes for CookieRequestPayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.pk.as_ref()) >> @@ -150,7 +154,7 @@ impl FromBytes for CookieRequestPayload { #[cfg(test)] mod tests { use crate::dht::cookie_request::*; - use crypto_box::aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}; + use crypto_box::aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}; use rand::thread_rng; encode_decode_test!( @@ -173,13 +177,19 @@ mod tests { dht_packet_encrypt_decrypt!( cookie_request_payload_encrypt_decrypt, CookieRequest, - CookieRequestPayload { pk: SecretKey::generate(&mut thread_rng()).public_key(), id: 42 } + CookieRequestPayload { + pk: SecretKey::generate(&mut thread_rng()).public_key(), + id: 42 + } ); dht_packet_encrypt_decrypt_invalid_key!( cookie_request_payload_encrypt_decrypt_invalid_key, CookieRequest, - CookieRequestPayload { pk: SecretKey::generate(&mut thread_rng()).public_key(), id: 42 } + CookieRequestPayload { + pk: SecretKey::generate(&mut thread_rng()).public_key(), + id: 42 + } ); dht_packet_decode_invalid!(cookie_request_decode_invalid, CookieRequest); diff --git a/tox_packet/src/dht/cookie_response.rs b/tox_packet/src/dht/cookie_response.rs index cbfbc3ebf..6e0af57f3 100644 --- a/tox_packet/src/dht/cookie_response.rs +++ b/tox_packet/src/dht/cookie_response.rs @@ -1,19 +1,20 @@ /*! CookieResponse packet */ -use crypto_box::{SalsaBox, aead::{Aead, AeadCore, Error as AeadError}}; -use nom::number::complete::be_u64; +use crypto_box::{ + aead::{Aead, AeadCore, Error as AeadError}, + SalsaBox, +}; use nom::bytes::complete::{tag, take}; use nom::combinator::eof; +use nom::number::complete::be_u64; -use cookie_factory::{ - do_gen, gen_slice, gen_be_u8, gen_call, gen_be_u64 -}; +use cookie_factory::{do_gen, gen_be_u64, gen_be_u8, gen_call, gen_slice}; -use tox_binary_io::*; -use tox_crypto::*; use crate::dht::cookie::EncryptedCookie; use crate::dht::errors::*; +use tox_binary_io::*; +use tox_crypto::*; /** Response to a `CookieRequest` packet. @@ -43,11 +44,18 @@ impl FromBytes for CookieResponse { let (input, nonce) = Nonce::from_bytes(input)?; let (input, payload) = take(136usize)(input)?; let (input, _) = eof(input)?; - Ok((input, CookieResponse { nonce, payload: payload.to_vec() })) + Ok(( + input, + CookieResponse { + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for CookieResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x19) >> @@ -78,17 +86,12 @@ impl CookieResponse { - fails to parse `CookieResponsePayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match CookieResponsePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -125,9 +128,9 @@ impl FromBytes for CookieResponsePayload { impl ToBytes for CookieResponsePayload { fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { - do_gen!(buf, - gen_call!(|buf, cookie| EncryptedCookie::to_bytes(cookie, buf), &self.cookie) >> - gen_be_u64!(self.id) + do_gen!( + buf, + gen_call!(|buf, cookie| EncryptedCookie::to_bytes(cookie, buf), &self.cookie) >> gen_be_u64!(self.id) ) } } @@ -137,8 +140,11 @@ mod tests { use std::num::NonZeroUsize; use super::*; - use nom::{Needed, Err, error::{Error, ErrorKind}}; - use crypto_box::aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}; + use crypto_box::aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}; + use nom::{ + error::{Error, ErrorKind}, + Err, Needed, + }; use rand::thread_rng; encode_decode_test!( @@ -216,26 +222,32 @@ mod tests { let invalid_payload_encoded = shared_secret.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_packet = CookieResponse { nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Error(Error::new(vec![42; 3], ErrorKind::Eof)), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Error(Error::new(vec![42; 3], ErrorKind::Eof)), + payload: invalid_payload.to_vec() + } + ); // Try short incomplete array let invalid_payload = []; let invalid_payload_encoded = shared_secret.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_packet = CookieResponse { nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Incomplete(Needed::Size(NonZeroUsize::new(24).unwrap())), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Incomplete(Needed::Size(NonZeroUsize::new(24).unwrap())), + payload: invalid_payload.to_vec() + } + ); } } diff --git a/tox_packet/src/dht/crypto_data.rs b/tox_packet/src/dht/crypto_data.rs index 119db14a2..0a63cbd04 100644 --- a/tox_packet/src/dht/crypto_data.rs +++ b/tox_packet/src/dht/crypto_data.rs @@ -2,20 +2,23 @@ */ use super::*; -use crypto_box::{SalsaBox, aead::{ - {Aead, AeadCore, Error as AeadError}, - generic_array::typenum::marker_traits::Unsigned, -}}; +use crypto_box::{ + aead::{ + generic_array::typenum::marker_traits::Unsigned, + {Aead, AeadCore, Error as AeadError}, + }, + SalsaBox, +}; use nom::{ - bytes::complete::{take_while, tag}, - number::complete::{be_u16, be_u32}, + bytes::complete::{tag, take_while}, combinator::{rest, rest_len, verify}, + number::complete::{be_u16, be_u32}, }; use std::convert::TryInto; +use crate::dht::errors::*; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::errors::*; /// The maximum size of `CryptoData` packet including two bytes of nonce and /// packet kind byte. @@ -44,7 +47,7 @@ pub struct CryptoData { /// format pub nonce_last_bytes: u16, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for CryptoData { @@ -53,11 +56,18 @@ impl FromBytes for CryptoData { let (input, _) = tag("\x1b")(input)?; let (input, nonce_last_bytes) = be_u16(input)?; let (input, payload) = rest(input)?; - Ok((input, CryptoData { nonce_last_bytes, payload: payload.to_vec() })) + Ok(( + input, + CryptoData { + nonce_last_bytes, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for CryptoData { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x1b) >> @@ -94,20 +104,15 @@ impl CryptoData { - fails to parse `CryptoDataPayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox, nonce: &Nonce) -> Result { - let decrypted = shared_secret.decrypt(nonce.into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::Decrypt - })?; + let decrypted = shared_secret + .decrypt(nonce.into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::Decrypt)?; match CryptoDataPayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::Deserialize { - error: error.to_owned(), - payload: decrypted.clone(), - }) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::Deserialize { + error: error.to_owned(), + payload: decrypted.clone(), + }), + Ok((_, payload)) => Ok(payload), } } } @@ -130,7 +135,7 @@ pub struct CryptoDataPayload { /// Packet number used by the receiver to know if any packets have been lost pub packet_number: u32, /// Data of `CryptoData` packet - pub data: Vec + pub data: Vec, } impl FromBytes for CryptoDataPayload { @@ -139,11 +144,19 @@ impl FromBytes for CryptoDataPayload { let (input, packet_number) = be_u32(input)?; let (input, _) = take_while(|b| b == 0)(input)?; let (input, data) = rest(input)?; - Ok((input, CryptoDataPayload { buffer_start, packet_number, data: data.to_vec() })) + Ok(( + input, + CryptoDataPayload { + buffer_start, + packet_number, + data: data.to_vec(), + }, + )) } } impl ToBytes for CryptoDataPayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u32!(self.buffer_start) >> @@ -157,7 +170,10 @@ impl ToBytes for CryptoDataPayload { #[cfg(test)] mod tests { use super::*; - use nom::{Err, error::{Error, ErrorKind}}; + use nom::{ + error::{Error, ErrorKind}, + Err, + }; use rand::thread_rng; encode_decode_test!( @@ -251,10 +267,16 @@ mod tests { let invalid_payload_encoded = shared_secret.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_packet = CryptoData { nonce_last_bytes, - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret, &nonce.into()); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { error: Err::Error(Error::new(vec![], ErrorKind::Eof)), payload: invalid_payload.to_vec() }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Error(Error::new(vec![], ErrorKind::Eof)), + payload: invalid_payload.to_vec() + } + ); } } diff --git a/tox_packet/src/dht/crypto_handshake.rs b/tox_packet/src/dht/crypto_handshake.rs index 0d4cac88b..698c21632 100644 --- a/tox_packet/src/dht/crypto_handshake.rs +++ b/tox_packet/src/dht/crypto_handshake.rs @@ -3,16 +3,19 @@ use super::*; -use crypto_box::{SalsaBox, aead::{Aead, AeadCore, Error as AeadError}}; -use sha2::Sha512; +use crate::dht::cookie::EncryptedCookie; +use crate::dht::errors::*; +use crypto_box::{ + aead::{Aead, AeadCore, Error as AeadError}, + SalsaBox, +}; +use nom::bytes::complete::{tag, take}; +use nom::combinator::eof; use sha2::digest::typenum::Unsigned; use sha2::digest::OutputSizeUser; +use sha2::Sha512; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::cookie::EncryptedCookie; -use crate::dht::errors::*; -use nom::bytes::complete::{take, tag}; -use nom::combinator::eof; /** Packet used to establish `net_crypto` connection between two peers. @@ -40,7 +43,7 @@ pub struct CryptoHandshake { /// Nonce for the current encrypted payload pub nonce: Nonce, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for CryptoHandshake { @@ -50,15 +53,19 @@ impl FromBytes for CryptoHandshake { let (input, nonce) = Nonce::from_bytes(input)?; let (input, payload) = take(248usize)(input)?; let (input, _) = eof(input)?; - Ok((input, CryptoHandshake { - cookie, - nonce, - payload: payload.to_vec() - })) + Ok(( + input, + CryptoHandshake { + cookie, + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for CryptoHandshake { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x1a) >> @@ -92,17 +99,12 @@ impl CryptoHandshake { - fails to parse `CryptoHandshakePayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match CryptoHandshakePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -136,7 +138,7 @@ pub struct CryptoHandshakePayload { /// Encrypted cookie of sender of `CryptoHandshake` packet. When node /// receives `CryptoHandshake` it can take this cookie instead of sending /// `CookieRequest` to obtain one. - pub cookie: EncryptedCookie + pub cookie: EncryptedCookie, } impl FromBytes for CryptoHandshakePayload { @@ -146,16 +148,20 @@ impl FromBytes for CryptoHandshakePayload { let (input, cookie_hash) = <[u8; ::OutputSize::USIZE]>::from_bytes(input)?; let (input, cookie) = EncryptedCookie::from_bytes(input)?; let (input, _) = eof(input)?; - Ok((input, CryptoHandshakePayload { - base_nonce, - session_pk, - cookie_hash, - cookie - })) + Ok(( + input, + CryptoHandshakePayload { + base_nonce, + session_pk, + cookie_hash, + cookie, + }, + )) } } impl ToBytes for CryptoHandshakePayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.base_nonce.as_ref()) >> @@ -171,8 +177,8 @@ mod tests { use std::num::NonZeroUsize; use super::*; - use nom::{Needed, Err}; - use crypto_box::aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}; + use crypto_box::aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}; + use nom::{Err, Needed}; use rand::thread_rng; encode_decode_test!( @@ -273,27 +279,33 @@ mod tests { let invalid_packet = CryptoHandshake { cookie: cookie.clone(), nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Incomplete(Needed::Size(NonZeroUsize::new(21).unwrap())), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Incomplete(Needed::Size(NonZeroUsize::new(21).unwrap())), + payload: invalid_payload.to_vec() + } + ); // Try short incomplete array let invalid_payload = []; let invalid_payload_encoded = shared_secret.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_packet = CryptoHandshake { cookie, nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Incomplete(Needed::Size(NonZeroUsize::new(24).unwrap())), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Incomplete(Needed::Size(NonZeroUsize::new(24).unwrap())), + payload: invalid_payload.to_vec() + } + ); } } diff --git a/tox_packet/src/dht/dht_request.rs b/tox_packet/src/dht/dht_request.rs index ab632dc59..93073eb65 100644 --- a/tox_packet/src/dht/dht_request.rs +++ b/tox_packet/src/dht/dht_request.rs @@ -2,18 +2,21 @@ */ use super::*; -use crypto_box::{SalsaBox, aead::{Aead, AeadCore, Error as AeadError}}; +use crypto_box::{ + aead::{Aead, AeadCore, Error as AeadError}, + SalsaBox, +}; use nom::{ - number::complete::be_u64, - combinator::{rest, eof, cond}, bytes::complete::tag, + combinator::{cond, eof, rest}, multi::many0, + number::complete::be_u64, }; -use tox_binary_io::*; -use tox_crypto::*; use crate::dht::errors::*; use crate::packed_node::*; +use tox_binary_io::*; +use tox_crypto::*; /** DHT Request packet struct. DHT Request packet consists of NatPingRequest and NatPingResponse. @@ -48,6 +51,7 @@ pub struct DhtRequest { } impl ToBytes for DhtRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x20) >> @@ -65,8 +69,16 @@ impl FromBytes for DhtRequest { let (input, rpk) = PublicKey::from_bytes(input)?; let (input, spk) = PublicKey::from_bytes(input)?; let (input, nonce) = Nonce::from_bytes(input)?; - let (input, payload) = map(rest, |bytes: &[u8]| bytes.to_vec() )(input)?; - Ok((input, DhtRequest { rpk, spk, nonce, payload })) + let (input, payload) = map(rest, |bytes: &[u8]| bytes.to_vec())(input)?; + Ok(( + input, + DhtRequest { + rpk, + spk, + nonce, + payload, + }, + )) } } @@ -95,18 +107,13 @@ impl DhtRequest { - fails to parse as given packet type */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match DhtRequestPayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -179,6 +186,7 @@ impl FromBytes for NatPingRequest { } impl ToBytes for NatPingRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0xfe) >> @@ -214,6 +222,7 @@ impl FromBytes for NatPingResponse { } impl ToBytes for NatPingResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0xfe) >> @@ -244,7 +253,7 @@ pub struct DhtPkAnnounce { /// Nonce for the current encrypted payload pub nonce: Nonce, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for DhtPkAnnounce { @@ -253,11 +262,19 @@ impl FromBytes for DhtPkAnnounce { let (input, real_pk) = PublicKey::from_bytes(input)?; let (input, nonce) = Nonce::from_bytes(input)?; let (input, payload) = rest(input)?; - Ok((input, DhtPkAnnounce { real_pk, nonce, payload: payload.to_vec() })) + Ok(( + input, + DhtPkAnnounce { + real_pk, + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for DhtPkAnnounce { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x9c) >> @@ -292,17 +309,12 @@ impl DhtPkAnnounce { - fails to parse as `DhtPkAnnouncePayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match DhtPkAnnouncePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -339,15 +351,19 @@ impl FromBytes for DhtPkAnnouncePayload { let (input, dht_pk) = PublicKey::from_bytes(input)?; let (input, nodes) = many0(TcpUdpPackedNode::from_bytes)(input)?; let (input, _) = cond(nodes.len() <= 4, eof)(input)?; - Ok((input, DhtPkAnnouncePayload { - no_reply, - dht_pk, - nodes, - })) + Ok(( + input, + DhtPkAnnouncePayload { + no_reply, + dht_pk, + nodes, + }, + )) } } impl ToBytes for DhtPkAnnouncePayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x9c) >> @@ -398,6 +414,7 @@ impl FromBytes for HardeningRequest { } impl ToBytes for HardeningRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x30) >> @@ -431,6 +448,7 @@ impl FromBytes for HardeningResponse { } impl ToBytes for HardeningResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x30) >> @@ -443,8 +461,11 @@ impl ToBytes for HardeningResponse { mod tests { use super::*; - use nom::{Err, error::{ErrorKind, Error}}; - use crypto_box::aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}; + use crypto_box::aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}; + use nom::{ + error::{Error, ErrorKind}, + Err, + }; use rand::thread_rng; use crate::ip_port::*; @@ -537,7 +558,7 @@ mod tests { payload: vec![42; 123], }), DhtRequestPayload::HardeningRequest(HardeningRequest), - DhtRequestPayload::HardeningResponse(HardeningResponse) + DhtRequestPayload::HardeningResponse(HardeningResponse), ]; for payload in test_payloads { @@ -568,7 +589,7 @@ mod tests { payload: vec![42; 123], }), DhtRequestPayload::HardeningRequest(HardeningRequest), - DhtRequestPayload::HardeningResponse(HardeningResponse) + DhtRequestPayload::HardeningResponse(HardeningResponse), ]; for payload in test_payloads { // encode payload with shared secret @@ -597,17 +618,20 @@ mod tests { rpk: bob_pk.clone(), spk: alice_pk.clone(), nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let precomputed_key = SalsaBox::new(&alice_pk, &bob_sk); let decoded_payload = invalid_packet.get_payload(&precomputed_key); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Error(Error::new(invalid_payload.to_vec(), ErrorKind::Tag)), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Error(Error::new(invalid_payload.to_vec(), ErrorKind::Tag)), + payload: invalid_payload.to_vec() + } + ); // Try short incomplete let invalid_payload = [0xfe]; let invalid_payload_encoded = shared_secret.encrypt(&nonce, &invalid_payload[..]).unwrap(); @@ -615,14 +639,17 @@ mod tests { rpk: bob_pk, spk: alice_pk, nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&precomputed_key); let error = decoded_payload.err().unwrap(); - assert_eq!(error, GetPayloadError::Deserialize { - error: Err::Error(Error::new(invalid_payload.to_vec(), ErrorKind::Tag)), - payload: invalid_payload.to_vec() - }); + assert_eq!( + error, + GetPayloadError::Deserialize { + error: Err::Error(Error::new(invalid_payload.to_vec(), ErrorKind::Tag)), + payload: invalid_payload.to_vec() + } + ); } #[test] @@ -634,16 +661,14 @@ mod tests { let shared_secret = SalsaBox::new(&bob_pk, &alice_sk); let payload = DhtPkAnnouncePayload::new( SecretKey::generate(&mut rng).public_key(), - vec![ - TcpUdpPackedNode { - ip_port: IpPort { - protocol: ProtocolType::Udp, - ip_addr: "127.0.0.1".parse().unwrap(), - port: 12345, - }, - pk: SecretKey::generate(&mut rng).public_key(), + vec![TcpUdpPackedNode { + ip_port: IpPort { + protocol: ProtocolType::Udp, + ip_addr: "127.0.0.1".parse().unwrap(), + port: 12345, }, - ], + pk: SecretKey::generate(&mut rng).public_key(), + }], ); // encode payload with shared secret let packet = DhtPkAnnounce::new(&shared_secret, alice_pk, &payload); @@ -664,16 +689,14 @@ mod tests { let shared_secret_invalid = SalsaBox::new(&bob_pk, &eve_sk); let payload = DhtPkAnnouncePayload::new( SecretKey::generate(&mut rng).public_key(), - vec![ - TcpUdpPackedNode { - ip_port: IpPort { - protocol: ProtocolType::Udp, - ip_addr: "127.0.0.1".parse().unwrap(), - port: 12345, - }, - pk: SecretKey::generate(&mut rng).public_key(), + vec![TcpUdpPackedNode { + ip_port: IpPort { + protocol: ProtocolType::Udp, + ip_addr: "127.0.0.1".parse().unwrap(), + port: 12345, }, - ], + pk: SecretKey::generate(&mut rng).public_key(), + }], ); // encode payload with shared secret let packet = DhtPkAnnounce::new(&shared_secret, alice_pk, &payload); @@ -696,7 +719,7 @@ mod tests { let invalid_packet = DhtPkAnnounce { real_pk: alice_pk.clone(), nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); assert!(decoded_payload.is_err()); @@ -706,7 +729,7 @@ mod tests { let invalid_packet = DhtPkAnnounce { real_pk: alice_pk, nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); assert!(decoded_payload.is_err()); diff --git a/tox_packet/src/dht/errors.rs b/tox_packet/src/dht/errors.rs index bd9c90b53..6465b4d0b 100644 --- a/tox_packet/src/dht/errors.rs +++ b/tox_packet/src/dht/errors.rs @@ -1,8 +1,8 @@ /*! Errors enum for DHT packets. */ -use thiserror::Error; use nom::{error::Error as NomError, Err}; +use thiserror::Error; use std::convert::From; use std::io::Error as IoError; @@ -21,7 +21,7 @@ pub enum GetPayloadError { error: Err>>, /// Received payload of packet payload: Vec, - } + }, } impl GetPayloadError { @@ -30,14 +30,20 @@ impl GetPayloadError { } pub(crate) fn deserialize(e: Err>, payload: Vec) -> GetPayloadError { - GetPayloadError::Deserialize { error: e.to_owned(), payload } + GetPayloadError::Deserialize { + error: e.to_owned(), + payload, + } } } /// From trait for temporary use during transition from io:Error to custom enum error of failure crate impl From for IoError { fn from(item: GetPayloadError) -> Self { - IoError::new(IoErrorKind::Other, format!("GetPayloadError occured. error: {:?}", item)) + IoError::new( + IoErrorKind::Other, + format!("GetPayloadError occured. error: {:?}", item), + ) } } @@ -46,17 +52,32 @@ mod tests { use std::num::NonZeroUsize; use super::*; - use nom::{Needed, error::{Error, ErrorKind}}; + use nom::{ + error::{Error, ErrorKind}, + Needed, + }; #[test] fn get_payload_error_kind() { let decrypt = GetPayloadError::Decrypt; assert_eq!(format!("{}", decrypt), "Decrypt payload error".to_owned()); - let incomplete = GetPayloadError::Deserialize { error: Err::Incomplete(Needed::Size(NonZeroUsize::new(5).unwrap())), payload: vec![1, 2, 3, 4] }; - assert_eq!(format!("{}", incomplete), "Deserialize payload error: Incomplete(Size(5)), data: [1, 2, 3, 4]".to_owned()); + let incomplete = GetPayloadError::Deserialize { + error: Err::Incomplete(Needed::Size(NonZeroUsize::new(5).unwrap())), + payload: vec![1, 2, 3, 4], + }; + assert_eq!( + format!("{}", incomplete), + "Deserialize payload error: Incomplete(Size(5)), data: [1, 2, 3, 4]".to_owned() + ); - let deserialize = GetPayloadError::Deserialize { error: Err::Error(Error::new(vec![], ErrorKind::Eof)), payload: vec![1, 2, 3, 4] }; - assert_eq!(format!("{}", deserialize), "Deserialize payload error: Error(Error { input: [], code: Eof }), data: [1, 2, 3, 4]".to_owned()); + let deserialize = GetPayloadError::Deserialize { + error: Err::Error(Error::new(vec![], ErrorKind::Eof)), + payload: vec![1, 2, 3, 4], + }; + assert_eq!( + format!("{}", deserialize), + "Deserialize payload error: Error(Error { input: [], code: Eof }), data: [1, 2, 3, 4]".to_owned() + ); } } diff --git a/tox_packet/src/dht/lan_discovery.rs b/tox_packet/src/dht/lan_discovery.rs index 5217706b2..92d86c74c 100644 --- a/tox_packet/src/dht/lan_discovery.rs +++ b/tox_packet/src/dht/lan_discovery.rs @@ -29,6 +29,7 @@ pub struct LanDiscovery { } impl ToBytes for LanDiscovery { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x21) >> diff --git a/tox_packet/src/dht/mod.rs b/tox_packet/src/dht/mod.rs index b892325bc..ba7a497b6 100644 --- a/tox_packet/src/dht/mod.rs +++ b/tox_packet/src/dht/mod.rs @@ -5,55 +5,48 @@ #[cfg(test)] #[macro_use] mod macros; -pub mod packed_node; -mod ping_request; -mod ping_response; -mod nodes_request; -mod nodes_response; -mod dht_request; +mod bootstrap_info; +mod cookie; mod cookie_request; mod cookie_response; -mod bootstrap_info; -mod lan_discovery; -mod crypto_handshake; mod crypto_data; -mod cookie; +mod crypto_handshake; +mod dht_request; mod errors; +mod lan_discovery; +mod nodes_request; +mod nodes_response; +pub mod packed_node; +mod ping_request; +mod ping_response; -pub use self::ping_request::*; -pub use self::ping_response::*; -pub use self::nodes_request::*; -pub use self::nodes_response::*; -pub use self::dht_request::*; +pub use self::bootstrap_info::*; +pub use self::cookie::*; pub use self::cookie_request::*; pub use self::cookie_response::*; -pub use self::bootstrap_info::*; -pub use self::lan_discovery::*; -pub use self::crypto_handshake::*; pub use self::crypto_data::*; -pub use self::cookie::*; +pub use self::crypto_handshake::*; +pub use self::dht_request::*; pub use self::errors::*; +pub use self::lan_discovery::*; +pub use self::nodes_request::*; +pub use self::nodes_response::*; +pub use self::ping_request::*; +pub use self::ping_response::*; use nom::branch::alt; use nom::combinator::map; use cookie_factory::{ - do_gen, - gen_slice, - gen_call, - gen_cond, - gen_be_u8, - gen_be_u16, - gen_be_u32, - gen_be_u64, - gen_many_ref + do_gen, gen_be_u16, gen_be_u32, gen_be_u64, gen_be_u8, gen_call, gen_cond, gen_many_ref, gen_slice, }; -use tox_binary_io::*; use crate::onion::*; +use tox_binary_io::*; pub fn unix_time(time: std::time::SystemTime) -> u64 { - let since_the_epoch = time.duration_since(std::time::UNIX_EPOCH) + let since_the_epoch = time + .duration_since(std::time::UNIX_EPOCH) .expect("Current time is earlier than Unix epoch"); since_the_epoch.as_secs() @@ -107,7 +100,7 @@ pub enum Packet { /// [`OnionResponse1`](../onion/struct.OnionResponse1.html) structure. OnionResponse1(OnionResponse1), /// [`BootstrapInfo`](./struct.BootstrapInfo.html) structure. - BootstrapInfo(BootstrapInfo) + BootstrapInfo(BootstrapInfo), } impl ToBytes for Packet { @@ -133,7 +126,7 @@ impl ToBytes for Packet { Packet::OnionResponse3(ref p) => p.to_bytes(buf), Packet::OnionResponse2(ref p) => p.to_bytes(buf), Packet::OnionResponse1(ref p) => p.to_bytes(buf), - Packet::BootstrapInfo(ref p) => p.to_bytes(buf) + Packet::BootstrapInfo(ref p) => p.to_bytes(buf), } } } diff --git a/tox_packet/src/dht/nodes_request.rs b/tox_packet/src/dht/nodes_request.rs index 720a52de9..d73db1fbc 100644 --- a/tox_packet/src/dht/nodes_request.rs +++ b/tox_packet/src/dht/nodes_request.rs @@ -5,14 +5,14 @@ use super::*; use aead::{Aead, AeadCore, Error as AeadError}; use crypto_box::SalsaBox; use nom::{ - number::complete::be_u64, - combinator::{rest, eof}, bytes::complete::tag, + combinator::{eof, rest}, + number::complete::be_u64, }; +use crate::dht::errors::*; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::errors::*; /** Nodes request packet struct. It's used to get up to 4 closest nodes to requested public key. Every 20 seconds DHT node sends `NodesRequest` packet to @@ -41,6 +41,7 @@ pub struct NodesRequest { } impl ToBytes for NodesRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x02) >> @@ -83,18 +84,13 @@ impl NodesRequest { - fails to parse as given packet type */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match NodesRequestPayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -120,6 +116,7 @@ pub struct NodesRequestPayload { } impl ToBytes for NodesRequestPayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.pk.as_ref()) >> @@ -146,7 +143,10 @@ mod tests { encode_decode_test!( nodes_request_payload_encode_decode, - NodesRequestPayload { pk: SecretKey::generate(&mut thread_rng()).public_key(), id: 42 } + NodesRequestPayload { + pk: SecretKey::generate(&mut thread_rng()).public_key(), + id: 42 + } ); dht_packet_encode_decode!(nodes_request_encode_decode, NodesRequest); @@ -154,13 +154,19 @@ mod tests { dht_packet_encrypt_decrypt!( nodes_request_payload_encrypt_decrypt, NodesRequest, - NodesRequestPayload { pk: SecretKey::generate(&mut thread_rng()).public_key(), id: 42 } + NodesRequestPayload { + pk: SecretKey::generate(&mut thread_rng()).public_key(), + id: 42 + } ); dht_packet_encrypt_decrypt_invalid_key!( nodes_request_payload_encrypt_decrypt_invalid_key, NodesRequest, - NodesRequestPayload { pk: SecretKey::generate(&mut thread_rng()).public_key(), id: 42 } + NodesRequestPayload { + pk: SecretKey::generate(&mut thread_rng()).public_key(), + id: 42 + } ); dht_packet_decode_invalid!(nodes_request_decode_invalid, NodesRequest); diff --git a/tox_packet/src/dht/nodes_response.rs b/tox_packet/src/dht/nodes_response.rs index 258a51d8a..2fa9b6264 100644 --- a/tox_packet/src/dht/nodes_response.rs +++ b/tox_packet/src/dht/nodes_response.rs @@ -5,16 +5,16 @@ use super::*; use aead::{Aead, AeadCore, Error as AeadError}; use crypto_box::SalsaBox; use nom::{ - multi::count, - number::complete::{le_u8, be_u64}, - combinator::{rest, eof, verify}, bytes::complete::tag, + combinator::{eof, rest, verify}, + multi::count, + number::complete::{be_u64, le_u8}, }; +use crate::dht::errors::*; +use crate::dht::packed_node::PackedNode; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::packed_node::PackedNode; -use crate::dht::errors::*; /** Nodes response packet struct. When DHT node receives `NodesRequest` it should respond with `NodesResponse` that contains up to to 4 closest nodes to @@ -44,6 +44,7 @@ pub struct NodesResponse { } impl ToBytes for NodesResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x04) >> @@ -86,18 +87,13 @@ impl NodesResponse { - fails to parse as given packet type */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match NodesResponsePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -131,6 +127,7 @@ pub struct NodesResponsePayload { } impl ToBytes for NodesResponsePayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_cond!(self.nodes.len() > 4, |buf| gen_error(buf, 0)) >> @@ -155,14 +152,18 @@ impl FromBytes for NodesResponsePayload { mod tests { use crate::dht::nodes_response::*; use crate::dht::Packet; - use std::net::SocketAddr; use rand::thread_rng; + use std::net::SocketAddr; encode_decode_test!( nodes_response_payload_encode_decode, - NodesResponsePayload { nodes: vec![ - PackedNode::new(SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), SecretKey::generate(&mut thread_rng()).public_key()) - ], id: 42 } + NodesResponsePayload { + nodes: vec![PackedNode::new( + SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), + SecretKey::generate(&mut thread_rng()).public_key() + )], + id: 42 + } ); dht_packet_encode_decode!(nodes_response_encode_decode, NodesResponse); @@ -170,17 +171,25 @@ mod tests { dht_packet_encrypt_decrypt!( nodes_response_payload_encrypt_decrypt, NodesResponse, - NodesResponsePayload { nodes: vec![ - PackedNode::new(SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), SecretKey::generate(&mut thread_rng()).public_key()) - ], id: 42 } + NodesResponsePayload { + nodes: vec![PackedNode::new( + SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), + SecretKey::generate(&mut thread_rng()).public_key() + )], + id: 42 + } ); dht_packet_encrypt_decrypt_invalid_key!( nodes_response_payload_encrypt_decrypt_invalid_key, NodesResponse, - NodesResponsePayload { nodes: vec![ - PackedNode::new(SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), SecretKey::generate(&mut thread_rng()).public_key()) - ], id: 42 } + NodesResponsePayload { + nodes: vec![PackedNode::new( + SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), + SecretKey::generate(&mut thread_rng()).public_key() + )], + id: 42 + } ); dht_packet_decode_invalid!(nodes_response_decode_invalid, NodesResponse); diff --git a/tox_packet/src/dht/packed_node.rs b/tox_packet/src/dht/packed_node.rs index 16bcb67e8..89b6cf193 100644 --- a/tox_packet/src/dht/packed_node.rs +++ b/tox_packet/src/dht/packed_node.rs @@ -2,18 +2,12 @@ */ use super::*; -use nom::number::complete::{le_u8, be_u16}; -use nom::combinator::flat_map; -use nom::error::{ErrorKind, make_error}; use cookie_factory::gen_if_else; +use nom::combinator::flat_map; +use nom::error::{make_error, ErrorKind}; +use nom::number::complete::{be_u16, le_u8}; -use std::net::{ - IpAddr, - Ipv4Addr, - Ipv6Addr, - SocketAddr, - SocketAddrV4 -}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4}; use tox_binary_io::*; use tox_crypto::*; @@ -51,6 +45,7 @@ pub struct PackedNode { } impl ToBytes for PackedNode { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_if_else!(self.saddr.is_ipv4(), gen_be_u8!(2), gen_be_u8!(10)) >> @@ -77,10 +72,12 @@ address. impl FromBytes for PackedNode { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, addr) = flat_map(le_u8, |b| move |input| match b { - 2 => map(Ipv4Addr::from_bytes, IpAddr::V4)(input), - 10 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), - _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + let (input, addr) = flat_map(le_u8, |b| { + move |input| match b { + 2 => map(Ipv4Addr::from_bytes, IpAddr::V4)(input), + 10 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), + _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + } })(input)?; let (input, port) = be_u16(input)?; let saddr = SocketAddr::new(addr, port); @@ -93,7 +90,10 @@ impl PackedNode { /// Create new `PackedNode`. The IPv6 address will be converted to IPv4 if /// it's IPv4-compatible or IPv4-mapped. pub fn new(saddr: SocketAddr, pk: PublicKey) -> Self { - PackedNode { saddr: PackedNode::ipv6_to_ipv4(saddr), pk } + PackedNode { + saddr: PackedNode::ipv6_to_ipv4(saddr), + pk, + } } /// Convert IPv6 address to IPv4 if it's IPv4-compatible or IPv4-mapped. @@ -107,12 +107,13 @@ impl PackedNode { } else { SocketAddr::V6(v6) } - }, + } } } /// to_bytes for TCP #[allow(clippy::wrong_self_convention)] + #[rustfmt::skip] pub fn to_tcp_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_if_else!(self.saddr.is_ipv4(), gen_be_u8!(130), gen_be_u8!(138)) >> @@ -124,10 +125,12 @@ impl PackedNode { /// from_bytes for TCP pub fn from_tcp_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, addr) = flat_map(le_u8, |b| move |input| match b { - 130 => map(Ipv4Addr::from_bytes, IpAddr::V4)(input), - 138 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), - _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + let (input, addr) = flat_map(le_u8, |b| { + move |input| match b { + 130 => map(Ipv4Addr::from_bytes, IpAddr::V4)(input), + 138 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), + _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + } })(input)?; let (input, port) = be_u16(input)?; let saddr = SocketAddr::new(addr, port); @@ -139,8 +142,7 @@ impl PackedNode { pub fn ip_type(&self) -> u8 { if self.saddr.is_ipv4() { 2 - } - else { + } else { 10 } } @@ -156,7 +158,6 @@ impl PackedNode { } } - #[cfg(test)] mod tests { use super::*; @@ -168,10 +169,7 @@ mod tests { let saddr = "1.2.3.4:12345".parse().unwrap(); let a = PackedNode::new(saddr, pk.clone()); - let b = PackedNode { - saddr, - pk, - }; + let b = PackedNode { saddr, pk }; assert_eq!(a, b); } @@ -182,10 +180,7 @@ mod tests { let saddr_v4 = "1.2.3.4:12345".parse().unwrap(); let a = PackedNode::new(saddr_v6, pk.clone()); - let b = PackedNode { - saddr: saddr_v4, - pk, - }; + let b = PackedNode { saddr: saddr_v4, pk }; assert_eq!(a, b); } diff --git a/tox_packet/src/dht/ping_request.rs b/tox_packet/src/dht/ping_request.rs index 2b51f5977..2f6cb84e8 100644 --- a/tox_packet/src/dht/ping_request.rs +++ b/tox_packet/src/dht/ping_request.rs @@ -2,16 +2,19 @@ */ use super::*; -use crypto_box::{SalsaBox, aead::{Aead, AeadCore, Error as AeadError}}; +use crypto_box::{ + aead::{Aead, AeadCore, Error as AeadError}, + SalsaBox, +}; use nom::{ - number::complete::be_u64, - combinator::{eof, rest}, bytes::complete::tag, + combinator::{eof, rest}, + number::complete::be_u64, }; +use crate::dht::errors::*; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::errors::*; /** Ping request packet struct. Every 60 seconds DHT node sends `PingRequest` packet to peers to check whether it is alive. When `PingRequest` is received @@ -43,6 +46,7 @@ pub struct PingRequest { } impl ToBytes for PingRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x00) >> @@ -86,18 +90,13 @@ impl PingRequest { - fails to parse as given packet type */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match PingRequestPayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -140,6 +139,7 @@ impl FromBytes for PingRequestPayload { } impl ToBytes for PingRequestPayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x00) >> @@ -153,10 +153,7 @@ mod tests { use crate::dht::ping_request::*; use crate::dht::Packet; - encode_decode_test!( - ping_request_payload_encode_decode, - PingRequestPayload { id: 42 } - ); + encode_decode_test!(ping_request_payload_encode_decode, PingRequestPayload { id: 42 }); dht_packet_encode_decode!(ping_request_encode_decode, PingRequest); diff --git a/tox_packet/src/dht/ping_response.rs b/tox_packet/src/dht/ping_response.rs index 89f79e92f..782639589 100644 --- a/tox_packet/src/dht/ping_response.rs +++ b/tox_packet/src/dht/ping_response.rs @@ -2,17 +2,17 @@ */ use super::*; -use nom::{ - number::complete::be_u64, - combinator::rest, +use crypto_box::{ + aead::{Aead, AeadCore, Error as AeadError}, + SalsaBox, }; -use crypto_box::{SalsaBox, aead::{Aead, AeadCore, Error as AeadError}}; +use nom::{combinator::rest, number::complete::be_u64}; -use tox_binary_io::*; -use tox_crypto::*; use crate::dht::errors::*; -use nom::combinator::eof; use nom::bytes::complete::tag; +use nom::combinator::eof; +use tox_binary_io::*; +use tox_crypto::*; /** Ping response packet struct. When `PingRequest` is received DHT node should respond with `PingResponse` that contains the same ping id inside it's encrypted @@ -41,6 +41,7 @@ pub struct PingResponse { } impl ToBytes for PingResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x01) >> @@ -83,18 +84,13 @@ impl PingResponse { - fails to parse as given packet type */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match PingResponsePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, payload)) => { - Ok(payload) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, payload)) => Ok(payload), } } } @@ -137,6 +133,7 @@ impl FromBytes for PingResponsePayload { } impl ToBytes for PingResponsePayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x01) >> @@ -150,10 +147,7 @@ mod tests { use crate::dht::ping_response::*; use crate::dht::Packet; - encode_decode_test!( - ping_response_payload_encode_decode, - PingResponsePayload { id: 42 } - ); + encode_decode_test!(ping_response_payload_encode_decode, PingResponsePayload { id: 42 }); dht_packet_encode_decode!(ping_response_encode_decode, PingResponse); diff --git a/tox_packet/src/friend_connection/alive.rs b/tox_packet/src/friend_connection/alive.rs index 8c405ff7c..478c8e622 100644 --- a/tox_packet/src/friend_connection/alive.rs +++ b/tox_packet/src/friend_connection/alive.rs @@ -36,9 +36,5 @@ impl ToBytes for Alive { mod tests { use super::*; - encode_decode_test!( - alive_encode_decode, - Alive - ); - + encode_decode_test!(alive_encode_decode, Alive); } diff --git a/tox_packet/src/friend_connection/friend_requests.rs b/tox_packet/src/friend_connection/friend_requests.rs index 859bf6443..335182cd2 100644 --- a/tox_packet/src/friend_connection/friend_requests.rs +++ b/tox_packet/src/friend_connection/friend_requests.rs @@ -3,17 +3,24 @@ use super::*; -use crate::onion::*; -use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; use crate::ip_port::SIZE_IPPORT; +use crate::onion::*; use crate::toxid::NoSpam; -use nom::combinator::{rest, verify}; +use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, +}; use nom::bytes::complete::tag; +use nom::combinator::{rest, verify}; -const ONION_SEND_BASE: usize = crypto_box::KEY_SIZE + SIZE_IPPORT + ::TagSize::USIZE; +const ONION_SEND_BASE: usize = crypto_box::KEY_SIZE + SIZE_IPPORT + ::TagSize::USIZE; const ONION_SEND_1: usize = xsalsa20poly1305::NONCE_SIZE + ONION_SEND_BASE * 3; const MAX_ONION_DATA_SIZE: usize = ONION_MAX_PACKET_SIZE - (ONION_SEND_1 + 1); // 1 is for packet_id -const MIN_ONION_DATA_REQUEST_SIZE: usize = 1 + crypto_box::KEY_SIZE + xsalsa20poly1305::NONCE_SIZE + crypto_box::KEY_SIZE + ::TagSize::USIZE; // 1 is for packet_id +const MIN_ONION_DATA_REQUEST_SIZE: usize = 1 + + crypto_box::KEY_SIZE + + xsalsa20poly1305::NONCE_SIZE + + crypto_box::KEY_SIZE + + ::TagSize::USIZE; // 1 is for packet_id /// Maximum size in butes of Onion Data Request packet pub const MAX_DATA_REQUEST_SIZE: usize = MAX_ONION_DATA_SIZE - MIN_ONION_DATA_REQUEST_SIZE; /// Minimum size in bytes of Onion Data Response packet @@ -42,11 +49,18 @@ impl FromBytes for FriendRequests { let (input, _) = tag("\x12")(input)?; let (input, nospam) = NoSpam::from_bytes(input)?; let (input, message) = verify(rest, |message: &[u8]| message.len() <= MAX_ONION_CLIENT_DATA_SIZE)(input)?; - Ok((input, FriendRequests { nospam, message: message.to_vec() })) + Ok(( + input, + FriendRequests { + nospam, + message: message.to_vec(), + }, + )) } } impl ToBytes for FriendRequests { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x12) >> @@ -71,6 +85,6 @@ mod tests { encode_decode_test!( friend_requests_encode_decode, - FriendRequests::new(NoSpam([42; NOSPAMBYTES]), vec![1,2,3,4]) + FriendRequests::new(NoSpam([42; NOSPAMBYTES]), vec![1, 2, 3, 4]) ); } diff --git a/tox_packet/src/friend_connection/mod.rs b/tox_packet/src/friend_connection/mod.rs index 3e325df38..5fe61a1cd 100644 --- a/tox_packet/src/friend_connection/mod.rs +++ b/tox_packet/src/friend_connection/mod.rs @@ -4,24 +4,17 @@ use tox_binary_io::*; mod alive; -mod share_relays; mod friend_requests; +mod share_relays; pub use self::alive::*; -pub use self::share_relays::*; pub use self::friend_requests::*; +pub use self::share_relays::*; use nom::branch::alt; use nom::combinator::map; -use cookie_factory::{ - do_gen, - gen_slice, - gen_call, - gen_cond, - gen_be_u8, - gen_many_ref -}; +use cookie_factory::{do_gen, gen_be_u8, gen_call, gen_cond, gen_many_ref, gen_slice}; /** Friend connection packet enum that encapsulates all types of Friend connection packets. */ @@ -61,17 +54,14 @@ mod tests { use rand::thread_rng; use super::*; - use crate::toxid::{NoSpam, NOSPAMBYTES}; use crate::dht::packed_node::*; + use crate::toxid::{NoSpam, NOSPAMBYTES}; - encode_decode_test!( - packet_alive_encode_decode, - Packet::Alive(Alive) - ); + encode_decode_test!(packet_alive_encode_decode, Packet::Alive(Alive)); encode_decode_test!( packet_friend_requests_encode_decode, - Packet::FriendRequests(FriendRequests::new(NoSpam([42; NOSPAMBYTES]), vec![1,2,3,4])) + Packet::FriendRequests(FriendRequests::new(NoSpam([42; NOSPAMBYTES]), vec![1, 2, 3, 4])) ); encode_decode_test!( diff --git a/tox_packet/src/friend_connection/share_relays.rs b/tox_packet/src/friend_connection/share_relays.rs index 51b2a21a8..2db866a1c 100644 --- a/tox_packet/src/friend_connection/share_relays.rs +++ b/tox_packet/src/friend_connection/share_relays.rs @@ -4,8 +4,8 @@ use super::*; use crate::dht::packed_node::*; use nom::bytes::complete::tag; -use nom::multi::many0; use nom::combinator::{success, verify}; +use nom::multi::many0; /// Id of the `ShareRelays` packet. pub const PACKET_ID_SHARE_RELAYS: u8 = 0x11; @@ -36,13 +36,12 @@ impl FromBytes for ShareRelays { let (input, _) = tag(&[PACKET_ID_SHARE_RELAYS][..])(input)?; let (input, relays) = many0(PackedNode::from_tcp_bytes)(input)?; let (input, _) = verify(success(relays.len()), |len| *len <= MAX_SHARED_RELAYS)(input)?; - Ok((input, ShareRelays { - relays, - })) + Ok((input, ShareRelays { relays })) } } impl ToBytes for ShareRelays { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(PACKET_ID_SHARE_RELAYS) >> diff --git a/tox_packet/src/ip_port.rs b/tox_packet/src/ip_port.rs index 030653231..dc62e1001 100644 --- a/tox_packet/src/ip_port.rs +++ b/tox_packet/src/ip_port.rs @@ -1,22 +1,17 @@ //! `IpAddr` with a port number. -use std::net::{ - IpAddr, - Ipv4Addr, - Ipv6Addr, - SocketAddr, -}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; +use cookie_factory::{do_gen, gen_be_u16, gen_be_u8, gen_call, gen_cond, gen_slice}; use nom::{ - IResult, branch::alt, - combinator::{map, flat_map, cond}, - error::{ErrorKind, make_error}, + bytes::complete::take, + combinator::{cond, flat_map, map}, + error::{make_error, ErrorKind}, number::complete::{be_u16, le_u8}, sequence::terminated, - bytes::complete::take + IResult, }; -use cookie_factory::{do_gen, gen_slice, gen_cond, gen_call, gen_be_u8, gen_be_u16}; use tox_binary_io::*; @@ -49,7 +44,7 @@ pub enum ProtocolType { /// `UDP` type if the least significant bit is 0. Udp, /// `TCP` type if the least significant bit is 1. - Tcp + Tcp, } /** `IpAddr` with a port number. IPv4 can be padded with 12 bytes of zeros @@ -72,7 +67,7 @@ pub struct IpPort { /// IP address pub ip_addr: IpAddr, /// Port number - pub port: u16 + pub port: u16, } impl IpPort { @@ -105,30 +100,48 @@ impl IpPort { /// Parse `IpPort` with UDP protocol type with optional padding. pub fn from_udp_bytes(input: &[u8], padding: IpPortPadding) -> IResult<&[u8], IpPort> { - let (input, ip_addr) = flat_map(le_u8, |b| move |input| match b { - 2 => terminated( - map(Ipv4Addr::from_bytes, IpAddr::V4), - cond(padding == IpPortPadding::WithPadding, take(IPV4_PADDING_SIZE)) - )(input), - 10 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), - _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + let (input, ip_addr) = flat_map(le_u8, |b| { + move |input| match b { + 2 => terminated( + map(Ipv4Addr::from_bytes, IpAddr::V4), + cond(padding == IpPortPadding::WithPadding, take(IPV4_PADDING_SIZE)), + )(input), + 10 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), + _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + } })(input)?; let (input, port) = be_u16(input)?; - Ok((input, IpPort { protocol: ProtocolType::Udp, ip_addr, port })) + Ok(( + input, + IpPort { + protocol: ProtocolType::Udp, + ip_addr, + port, + }, + )) } /// Parse `IpPort` with TCP protocol type with optional padding. pub fn from_tcp_bytes(input: &[u8], padding: IpPortPadding) -> IResult<&[u8], IpPort> { - let (input, ip_addr) = flat_map(le_u8, |b| move |input| match b { - 130 => terminated( - map(Ipv4Addr::from_bytes, IpAddr::V4), - cond(padding == IpPortPadding::WithPadding, take(IPV4_PADDING_SIZE)) - )(input), - 138 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), - _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + let (input, ip_addr) = flat_map(le_u8, |b| { + move |input| match b { + 130 => terminated( + map(Ipv4Addr::from_bytes, IpAddr::V4), + cond(padding == IpPortPadding::WithPadding, take(IPV4_PADDING_SIZE)), + )(input), + 138 => map(Ipv6Addr::from_bytes, IpAddr::V6)(input), + _ => Err(nom::Err::Error(make_error(input, ErrorKind::Switch))), + } })(input)?; let (input, port) = be_u16(input)?; - Ok((input, IpPort { protocol: ProtocolType::Tcp, ip_addr, port })) + Ok(( + input, + IpPort { + protocol: ProtocolType::Tcp, + ip_addr, + port, + }, + )) } /// Parse `IpPort` with optional padding. @@ -140,6 +153,7 @@ impl IpPort { } /// Write `IpPort` with UDP protocol type with optional padding. + #[rustfmt::skip] pub fn to_udp_bytes<'a>(&self, buf: (&'a mut [u8], usize), padding: IpPortPadding) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_cond!(self.protocol == ProtocolType::Tcp, |buf| gen_error(buf, 0)) >> @@ -148,6 +162,7 @@ impl IpPort { } /// Write `IpPort` with TCP protocol type with optional padding. + #[rustfmt::skip] pub fn to_tcp_bytes<'a>(&self, buf: (&'a mut [u8], usize), padding: IpPortPadding) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_cond!(self.protocol == ProtocolType::Udp, |buf| gen_error(buf, 0)) >> @@ -156,6 +171,7 @@ impl IpPort { } /// Write `IpPort` with optional padding. + #[rustfmt::skip] pub fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize), padding: IpPortPadding) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(self.ip_type()) >> @@ -170,7 +186,7 @@ impl IpPort { IpPort { protocol: ProtocolType::Udp, ip_addr: saddr.ip(), - port: saddr.port() + port: saddr.port(), } } @@ -179,7 +195,7 @@ impl IpPort { IpPort { protocol: ProtocolType::Tcp, ip_addr: saddr.ip(), - port: saddr.port() + port: saddr.port(), } } @@ -242,7 +258,7 @@ mod tests { let ip_port_1 = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let ip_port_2 = IpPort::from_udp_saddr(ip_port_1.to_saddr()); assert_eq!(ip_port_2, ip_port_1); @@ -253,7 +269,7 @@ mod tests { let ip_port_1 = IpPort { protocol: ProtocolType::Tcp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let ip_port_2 = IpPort::from_tcp_saddr(ip_port_1.to_saddr()); assert_eq!(ip_port_2, ip_port_1); diff --git a/tox_packet/src/lib.rs b/tox_packet/src/lib.rs index 5ae3f541f..8b6977d0c 100644 --- a/tox_packet/src/lib.rs +++ b/tox_packet/src/lib.rs @@ -1,8 +1,8 @@ -pub mod toxid; -pub mod ip_port; -pub mod packed_node; pub mod dht; -pub mod onion; pub mod friend_connection; -pub mod relay; +pub mod ip_port; pub mod messenger; +pub mod onion; +pub mod packed_node; +pub mod relay; +pub mod toxid; diff --git a/tox_packet/src/messenger/action.rs b/tox_packet/src/messenger/action.rs index 01c79b1c9..554ab56ad 100644 --- a/tox_packet/src/messenger/action.rs +++ b/tox_packet/src/messenger/action.rs @@ -3,9 +3,9 @@ use super::*; -use std::str; -use nom::combinator::{map_res, rest, verify}; use nom::bytes::complete::tag; +use nom::combinator::{map_res, rest, verify}; +use std::str; /// Maximum size in bytes of action message string of action packet const MAX_ACTION_MESSAGE_DATA_SIZE: usize = 1372; @@ -31,12 +31,16 @@ pub struct Action { impl FromBytes for Action { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, _) = tag("\x41")(input)?; - let (input, msg) = map_res(verify(rest, |msg: &[u8]| msg.len() <= MAX_ACTION_MESSAGE_DATA_SIZE), str::from_utf8)(input)?; + let (input, msg) = map_res( + verify(rest, |msg: &[u8]| msg.len() <= MAX_ACTION_MESSAGE_DATA_SIZE), + str::from_utf8, + )(input)?; Ok((input, Action { msg: msg.to_string() })) } } impl ToBytes for Action { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x41) >> @@ -57,10 +61,7 @@ impl Action { mod tests { use super::*; - encode_decode_test!( - action_encode_decode, - Action::new("1234".to_string()) - ); + encode_decode_test!(action_encode_decode, Action::new("1234".to_string())); #[test] fn action_from_bytes_encoding_error() { diff --git a/tox_packet/src/messenger/conference/action.rs b/tox_packet/src/messenger/conference/action.rs index d6c561464..9680128fa 100644 --- a/tox_packet/src/messenger/conference/action.rs +++ b/tox_packet/src/messenger/conference/action.rs @@ -3,12 +3,12 @@ use super::*; -use std::str; use nom::{ - number::complete::{be_u16, be_u32}, - combinator::{rest, map_res}, bytes::complete::tag, + combinator::{map_res, rest}, + number::complete::{be_u16, be_u32}, }; +use std::str; /** Action is the struct that holds info to send action to a conference. @@ -47,16 +47,20 @@ impl FromBytes for Action { let (input, message_id) = be_u32(input)?; let (input, _) = tag("\x41")(input)?; let (input, action) = map_res(rest, str::from_utf8)(input)?; - Ok((input, Action { - conference_id, - peer_id, - message_id, - action: action.to_string(), - })) + Ok(( + input, + Action { + conference_id, + peer_id, + message_id, + action: action.to_string(), + }, + )) } } impl ToBytes for Action { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> @@ -85,10 +89,7 @@ impl Action { mod tests { use super::*; - encode_decode_test!( - conference_action_encode_decode, - Action::new(1, 2, 3, "1234".to_owned()) - ); + encode_decode_test!(conference_action_encode_decode, Action::new(1, 2, 3, "1234".to_owned())); #[test] fn conference_action_from_bytes_encoding_error() { diff --git a/tox_packet/src/messenger/conference/change_name.rs b/tox_packet/src/messenger/conference/change_name.rs index 70eced737..9731d520b 100644 --- a/tox_packet/src/messenger/conference/change_name.rs +++ b/tox_packet/src/messenger/conference/change_name.rs @@ -3,12 +3,12 @@ use super::*; -use std::str; use nom::{ - number::complete::{be_u16, be_u32}, - combinator::{rest, map_res, verify}, bytes::complete::tag, + combinator::{map_res, rest, verify}, + number::complete::{be_u16, be_u32}, }; +use std::str; use super::MAX_NAME_LENGTH_IN_CONFERENCE; @@ -47,17 +47,24 @@ impl FromBytes for ChangeName { let (input, peer_id) = be_u16(input)?; let (input, message_id) = be_u32(input)?; let (input, _) = tag("\x30")(input)?; - let (input, name) = map_res(verify(rest, |name: &[u8]| name.len() <= MAX_NAME_LENGTH_IN_CONFERENCE), str::from_utf8)(input)?; - Ok((input, ChangeName { - conference_id, - peer_id, - message_id, - name: name.to_string(), - })) + let (input, name) = map_res( + verify(rest, |name: &[u8]| name.len() <= MAX_NAME_LENGTH_IN_CONFERENCE), + str::from_utf8, + )(input)?; + Ok(( + input, + ChangeName { + conference_id, + peer_id, + message_id, + name: name.to_string(), + }, + )) } } impl ToBytes for ChangeName { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> @@ -87,10 +94,7 @@ impl ChangeName { mod tests { use super::*; - encode_decode_test!( - change_name_encode_decode, - ChangeName::new(1, 2, 3, "1234".to_owned()) - ); + encode_decode_test!(change_name_encode_decode, ChangeName::new(1, 2, 3, "1234".to_owned())); #[test] fn change_name_from_bytes_encoding_error() { @@ -111,7 +115,7 @@ mod tests { #[test] fn change_name_to_bytes_overflow() { let large_string = String::from_utf8(vec![32u8; MAX_NAME_LENGTH_IN_CONFERENCE + 1]).unwrap(); - let large_name = ChangeName::new(1,2, 3, large_string); + let large_name = ChangeName::new(1, 2, 3, large_string); let mut buf = [0; MAX_NAME_LENGTH_IN_CONFERENCE + 1 + 2 + 2 + 4 + 1]; // packet id + conference id + peer id + message id + message kind. assert!(large_name.to_bytes((&mut buf, 0)).is_err()); } diff --git a/tox_packet/src/messenger/conference/change_title.rs b/tox_packet/src/messenger/conference/change_title.rs index 7631c82d3..7b4967adb 100644 --- a/tox_packet/src/messenger/conference/change_title.rs +++ b/tox_packet/src/messenger/conference/change_title.rs @@ -3,12 +3,12 @@ use super::*; -use std::str; use nom::{ - number::complete::{be_u16, be_u32}, - combinator::{rest, map_res, verify}, bytes::complete::tag, + combinator::{map_res, rest, verify}, + number::complete::{be_u16, be_u32}, }; +use std::str; use super::MAX_NAME_LENGTH_IN_CONFERENCE; @@ -48,17 +48,24 @@ impl FromBytes for ChangeTitle { let (input, peer_id) = be_u16(input)?; let (input, message_id) = be_u32(input)?; let (input, _) = tag("\x31")(input)?; - let (input, title) = map_res(verify(rest, |title: &[u8]| title.len() <= MAX_NAME_LENGTH_IN_CONFERENCE), str::from_utf8)(input)?; - Ok((input, ChangeTitle { - conference_id, - peer_id, - message_id, - title: title.to_string(), - })) + let (input, title) = map_res( + verify(rest, |title: &[u8]| title.len() <= MAX_NAME_LENGTH_IN_CONFERENCE), + str::from_utf8, + )(input)?; + Ok(( + input, + ChangeTitle { + conference_id, + peer_id, + message_id, + title: title.to_string(), + }, + )) } } impl ToBytes for ChangeTitle { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> @@ -88,10 +95,7 @@ impl ChangeTitle { mod tests { use super::*; - encode_decode_test!( - change_title_encode_decode, - ChangeTitle::new(1, 2, 3, "1234".to_owned()) - ); + encode_decode_test!(change_title_encode_decode, ChangeTitle::new(1, 2, 3, "1234".to_owned())); #[test] fn change_title_from_bytes_encoding_error() { @@ -112,7 +116,7 @@ mod tests { #[test] fn change_title_to_bytes_overflow() { let large_string = String::from_utf8(vec![32u8; MAX_NAME_LENGTH_IN_CONFERENCE + 1]).unwrap(); - let large_title = ChangeTitle::new(1,2, 3, large_string); + let large_title = ChangeTitle::new(1, 2, 3, large_string); let mut buf = [0; MAX_NAME_LENGTH_IN_CONFERENCE + 1 + 2 + 2 + 4 + 1]; // packet id + conference id + peer id + message id + message kind. assert!(large_title.to_bytes((&mut buf, 0)).is_err()); } diff --git a/tox_packet/src/messenger/conference/freeze_peer.rs b/tox_packet/src/messenger/conference/freeze_peer.rs index 7ed739e59..bc0de7fec 100644 --- a/tox_packet/src/messenger/conference/freeze_peer.rs +++ b/tox_packet/src/messenger/conference/freeze_peer.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::{be_u16, be_u32}; use nom::bytes::complete::tag; +use nom::number::complete::{be_u16, be_u32}; /** Freeze peer is a struct that holds info to send freeze peer message to a conference. @@ -42,16 +42,20 @@ impl FromBytes for FreezePeer { let (input, message_id) = be_u32(input)?; let (input, _) = tag("\x12")(input)?; let (input, freeze_peer_id) = be_u16(input)?; - Ok((input, FreezePeer { - conference_id, - peer_id, - message_id, - freeze_peer_id, - })) + Ok(( + input, + FreezePeer { + conference_id, + peer_id, + message_id, + freeze_peer_id, + }, + )) } } impl ToBytes for FreezePeer { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> @@ -80,8 +84,5 @@ impl FreezePeer { mod tests { use super::*; - encode_decode_test!( - freeze_peer_encode_decode, - FreezePeer::new(1, 2, 3, 4) - ); + encode_decode_test!(freeze_peer_encode_decode, FreezePeer::new(1, 2, 3, 4)); } diff --git a/tox_packet/src/messenger/conference/invite.rs b/tox_packet/src/messenger/conference/invite.rs index 4b1971b93..63fcbb245 100644 --- a/tox_packet/src/messenger/conference/invite.rs +++ b/tox_packet/src/messenger/conference/invite.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::be_u16; use nom::bytes::complete::tag; +use nom::number::complete::be_u16; /** Invite is a struct that holds info to invite a peer to a conference. @@ -36,15 +36,19 @@ impl FromBytes for Invite { let (input, conference_id) = be_u16(input)?; let (input, conference_type) = ConferenceType::from_bytes(input)?; let (input, unique_id) = ConferenceUid::from_bytes(input)?; - Ok((input, Invite { - conference_id, - conference_type, - unique_id, - })) + Ok(( + input, + Invite { + conference_id, + conference_type, + unique_id, + }, + )) } } impl ToBytes for Invite { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x60) >> diff --git a/tox_packet/src/messenger/conference/invite_response.rs b/tox_packet/src/messenger/conference/invite_response.rs index 83df4e337..fcce310a1 100644 --- a/tox_packet/src/messenger/conference/invite_response.rs +++ b/tox_packet/src/messenger/conference/invite_response.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::be_u16; use nom::bytes::complete::tag; +use nom::number::complete::be_u16; /** InviteResponse is a struct that holds info to response to invite message from a peer. @@ -40,16 +40,20 @@ impl FromBytes for InviteResponse { let (input, conference_id_join) = be_u16(input)?; let (input, conference_type) = ConferenceType::from_bytes(input)?; let (input, unique_id) = ConferenceUid::from_bytes(input)?; - Ok((input, InviteResponse { - conference_id_local, - conference_id_join, - conference_type, - unique_id, - })) + Ok(( + input, + InviteResponse { + conference_id_local, + conference_id_join, + conference_type, + unique_id, + }, + )) } } impl ToBytes for InviteResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x60) >> @@ -64,7 +68,12 @@ impl ToBytes for InviteResponse { impl InviteResponse { /// Create new InviteResponse object. - pub fn new(conference_id_local: u16, conference_id_join: u16, conference_type: ConferenceType, unique_id: ConferenceUid) -> Self { + pub fn new( + conference_id_local: u16, + conference_id_join: u16, + conference_type: ConferenceType, + unique_id: ConferenceUid, + ) -> Self { InviteResponse { conference_id_local, conference_id_join, diff --git a/tox_packet/src/messenger/conference/kill_peer.rs b/tox_packet/src/messenger/conference/kill_peer.rs index 3a628c9e2..c41422a96 100644 --- a/tox_packet/src/messenger/conference/kill_peer.rs +++ b/tox_packet/src/messenger/conference/kill_peer.rs @@ -2,8 +2,8 @@ */ use super::*; -use nom::number::complete::{be_u16, be_u32}; use nom::bytes::complete::tag; +use nom::number::complete::{be_u16, be_u32}; /** KillPeer is a struct that holds info to send kill peer message to a conference. @@ -41,16 +41,20 @@ impl FromBytes for KillPeer { let (input, message_id) = be_u32(input)?; let (input, _) = tag("\x11")(input)?; let (input, kill_peer_id) = be_u16(input)?; - Ok((input, KillPeer { - conference_id, - peer_id, - message_id, - kill_peer_id, - })) + Ok(( + input, + KillPeer { + conference_id, + peer_id, + message_id, + kill_peer_id, + }, + )) } } impl ToBytes for KillPeer { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> @@ -79,8 +83,5 @@ impl KillPeer { mod tests { use super::*; - encode_decode_test!( - kill_peer_encode_decode, - KillPeer::new(1, 2, 3, 4) - ); + encode_decode_test!(kill_peer_encode_decode, KillPeer::new(1, 2, 3, 4)); } diff --git a/tox_packet/src/messenger/conference/message.rs b/tox_packet/src/messenger/conference/message.rs index c2e165b27..f04c94052 100644 --- a/tox_packet/src/messenger/conference/message.rs +++ b/tox_packet/src/messenger/conference/message.rs @@ -3,12 +3,12 @@ use super::*; -use std::str; use nom::{ - number::complete::{be_u16, be_u32}, - combinator::{rest, map_res}, bytes::complete::tag, + combinator::{map_res, rest}, + number::complete::{be_u16, be_u32}, }; +use std::str; /** Message is the struct that holds info to send chat message to a conference. @@ -47,16 +47,20 @@ impl FromBytes for Message { let (input, message_id) = be_u32(input)?; let (input, _) = tag("\x40")(input)?; let (input, message) = map_res(rest, str::from_utf8)(input)?; - Ok((input, Message { - conference_id, - peer_id, - message_id, - message: message.to_string(), - })) + Ok(( + input, + Message { + conference_id, + peer_id, + message_id, + message: message.to_string(), + }, + )) } } impl ToBytes for Message { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> diff --git a/tox_packet/src/messenger/conference/mod.rs b/tox_packet/src/messenger/conference/mod.rs index 960ccf314..4c292215b 100644 --- a/tox_packet/src/messenger/conference/mod.rs +++ b/tox_packet/src/messenger/conference/mod.rs @@ -1,54 +1,48 @@ /*! The implementation of conference packets. */ +mod action; +mod change_name; +mod change_title; +mod freeze_peer; mod invite; mod invite_response; -mod peer_online; +mod kill_peer; +mod message; +mod new_peer; mod peer_leave; +mod peer_online; +mod ping; mod query; mod query_response; mod title; -mod ping; -mod new_peer; -mod kill_peer; -mod freeze_peer; -mod change_name; -mod change_title; -mod message; -mod action; +pub use self::action::*; +pub use self::change_name::*; +pub use self::change_title::*; +pub use self::freeze_peer::*; pub use self::invite::*; pub use self::invite_response::*; -pub use self::peer_online::*; +pub use self::kill_peer::*; +pub use self::message::*; +pub use self::new_peer::*; pub use self::peer_leave::*; +pub use self::peer_online::*; +pub use self::ping::*; pub use self::query::*; pub use self::query_response::*; pub use self::title::*; -pub use self::ping::*; -pub use self::new_peer::*; -pub use self::kill_peer::*; -pub use self::freeze_peer::*; -pub use self::change_name::*; -pub use self::change_title::*; -pub use self::message::*; -pub use self::action::*; -use cookie_factory::{ - do_gen, - gen_slice, - gen_call, - gen_cond, - gen_be_u8, - gen_be_u16, - gen_be_u32, - gen_many_ref -}; -use rand::{Rng, distributions::{Distribution, Standard}}; -use nom::number::complete::be_u8; -use nom::combinator::{map_opt, map}; -use nom::bytes::complete::take; +use cookie_factory::{do_gen, gen_be_u16, gen_be_u32, gen_be_u8, gen_call, gen_cond, gen_many_ref, gen_slice}; use nom::branch::alt; -use nom::error::{ErrorKind, make_error}; +use nom::bytes::complete::take; +use nom::combinator::{map, map_opt}; +use nom::error::{make_error, ErrorKind}; +use nom::number::complete::be_u8; +use rand::{ + distributions::{Distribution, Standard}, + Rng, +}; use tox_binary_io::*; @@ -72,7 +66,7 @@ impl ConferenceUid { /// Custom from_slice function of ConferenceUID pub fn from_slice(bs: &[u8]) -> Option { if bs.len() != CONFERENCE_UID_BYTES { - return None + return None; } let mut n = ConferenceUid([0; CONFERENCE_UID_BYTES]); for (ni, &bsi) in n.0.iter_mut().zip(bs.iter()) { @@ -90,9 +84,7 @@ impl FromBytes for ConferenceUid { impl ToBytes for ConferenceUid { fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { - do_gen!(buf, - gen_slice!(self.0) - ) + do_gen!(buf, gen_slice!(self.0)) } } @@ -203,10 +195,7 @@ mod tests { use super::*; - encode_decode_test!( - conference_uid_encode_decode, - ConferenceUid([42; CONFERENCE_UID_BYTES]) - ); + encode_decode_test!(conference_uid_encode_decode, ConferenceUid([42; CONFERENCE_UID_BYTES])); #[test] fn conference_type_from_bytes() { @@ -217,35 +206,55 @@ mod tests { encode_decode_test!( packet_invite_encode_decode, - Packet::Invite(Invite::new(1, ConferenceType::Audio, ConferenceUid([42; CONFERENCE_UID_BYTES]))) + Packet::Invite(Invite::new( + 1, + ConferenceType::Audio, + ConferenceUid([42; CONFERENCE_UID_BYTES]) + )) ); encode_decode_test!( packet_invite_response_encode_decode, - Packet::InviteResponse(InviteResponse::new(1, 2, ConferenceType::Text, ConferenceUid([42; CONFERENCE_UID_BYTES]))) + Packet::InviteResponse(InviteResponse::new( + 1, + 2, + ConferenceType::Text, + ConferenceUid([42; CONFERENCE_UID_BYTES]) + )) ); encode_decode_test!( packet_peer_noline_encode_decode, - Packet::PeerOnline(PeerOnline::new(1, ConferenceType::Text, ConferenceUid([42; CONFERENCE_UID_BYTES]))) + Packet::PeerOnline(PeerOnline::new( + 1, + ConferenceType::Text, + ConferenceUid([42; CONFERENCE_UID_BYTES]) + )) ); - encode_decode_test!( - packet_peer_leave_encode_decode, - Packet::PeerLeave(PeerLeave::new(1)) - ); + encode_decode_test!(packet_peer_leave_encode_decode, Packet::PeerLeave(PeerLeave::new(1))); - encode_decode_test!( - packet_query_encode_decode, - Packet::Query(Query::new(1)) - ); + encode_decode_test!(packet_query_encode_decode, Packet::Query(Query::new(1))); encode_decode_test!( packet_query_response_encode_decode, - Packet::QueryResponse(QueryResponse::new(1, vec![ - PeerInfo::new(1, SecretKey::generate(&mut thread_rng()).public_key(), SecretKey::generate(&mut thread_rng()).public_key(), "1234".to_owned()), - PeerInfo::new(2, SecretKey::generate(&mut thread_rng()).public_key(), SecretKey::generate(&mut thread_rng()).public_key(), "56789".to_owned()), - ])) + Packet::QueryResponse(QueryResponse::new( + 1, + vec![ + PeerInfo::new( + 1, + SecretKey::generate(&mut thread_rng()).public_key(), + SecretKey::generate(&mut thread_rng()).public_key(), + "1234".to_owned() + ), + PeerInfo::new( + 2, + SecretKey::generate(&mut thread_rng()).public_key(), + SecretKey::generate(&mut thread_rng()).public_key(), + "56789".to_owned() + ), + ] + )) ); encode_decode_test!( @@ -253,14 +262,18 @@ mod tests { Packet::Title(Title::new(1, "1234".to_owned())) ); - encode_decode_test!( - packet_ping_encode_decode, - Packet::Ping(Ping::new(1, 2, 3)) - ); + encode_decode_test!(packet_ping_encode_decode, Packet::Ping(Ping::new(1, 2, 3))); encode_decode_test!( packet_new_peer_encode_decode, - Packet::NewPeer(NewPeer::new(1, 2, 3, 4, SecretKey::generate(&mut thread_rng()).public_key(), SecretKey::generate(&mut thread_rng()).public_key())) + Packet::NewPeer(NewPeer::new( + 1, + 2, + 3, + 4, + SecretKey::generate(&mut thread_rng()).public_key(), + SecretKey::generate(&mut thread_rng()).public_key() + )) ); encode_decode_test!( diff --git a/tox_packet/src/messenger/conference/new_peer.rs b/tox_packet/src/messenger/conference/new_peer.rs index fbc90b65a..7975901ea 100644 --- a/tox_packet/src/messenger/conference/new_peer.rs +++ b/tox_packet/src/messenger/conference/new_peer.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::{be_u16, be_u32}; use nom::bytes::complete::tag; +use nom::number::complete::{be_u16, be_u32}; use tox_crypto::*; @@ -53,18 +53,22 @@ impl FromBytes for NewPeer { let (input, new_peer_id) = be_u16(input)?; let (input, long_term_pk) = PublicKey::from_bytes(input)?; let (input, dht_pk) = PublicKey::from_bytes(input)?; - Ok((input, NewPeer { - conference_id, - peer_id, - message_id, - new_peer_id, - long_term_pk, - dht_pk, - })) + Ok(( + input, + NewPeer { + conference_id, + peer_id, + message_id, + new_peer_id, + long_term_pk, + dht_pk, + }, + )) } } impl ToBytes for NewPeer { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> @@ -81,7 +85,14 @@ impl ToBytes for NewPeer { impl NewPeer { /// Create new NewPeer object. - pub fn new(conference_id: u16, peer_id: u16, message_id: u32, new_peer_id: u16, long_term_pk: PublicKey, dht_pk: PublicKey) -> Self { + pub fn new( + conference_id: u16, + peer_id: u16, + message_id: u32, + new_peer_id: u16, + long_term_pk: PublicKey, + dht_pk: PublicKey, + ) -> Self { NewPeer { conference_id, peer_id, @@ -101,6 +112,13 @@ mod tests { encode_decode_test!( new_peer_encode_decode, - NewPeer::new(1, 2, 3, 4, SecretKey::generate(&mut thread_rng()).public_key(), SecretKey::generate(&mut thread_rng()).public_key()) + NewPeer::new( + 1, + 2, + 3, + 4, + SecretKey::generate(&mut thread_rng()).public_key(), + SecretKey::generate(&mut thread_rng()).public_key() + ) ); } diff --git a/tox_packet/src/messenger/conference/peer_leave.rs b/tox_packet/src/messenger/conference/peer_leave.rs index faec4c1d1..56c9b9dfa 100644 --- a/tox_packet/src/messenger/conference/peer_leave.rs +++ b/tox_packet/src/messenger/conference/peer_leave.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::be_u16; use nom::bytes::complete::tag; +use nom::number::complete::be_u16; /** PeerLeave is a struct that holds info to notify a peer quit a conference. @@ -30,6 +30,7 @@ impl FromBytes for PeerLeave { } impl ToBytes for PeerLeave { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x62) >> @@ -50,8 +51,5 @@ impl PeerLeave { mod tests { use super::*; - encode_decode_test!( - peer_leave_encode_decode, - PeerLeave::new(1) - ); + encode_decode_test!(peer_leave_encode_decode, PeerLeave::new(1)); } diff --git a/tox_packet/src/messenger/conference/peer_online.rs b/tox_packet/src/messenger/conference/peer_online.rs index 62d8d2d7c..8cc3738ed 100644 --- a/tox_packet/src/messenger/conference/peer_online.rs +++ b/tox_packet/src/messenger/conference/peer_online.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::be_u16; use nom::bytes::complete::tag; +use nom::number::complete::be_u16; /** PeerOnline is a struct that holds info to notify adding new peer to a conference. @@ -35,15 +35,19 @@ impl FromBytes for PeerOnline { let (input, conference_id) = be_u16(input)?; let (input, conference_type) = ConferenceType::from_bytes(input)?; let (input, unique_id) = ConferenceUid::from_bytes(input)?; - Ok((input, PeerOnline { - conference_id, - conference_type, - unique_id, - })) + Ok(( + input, + PeerOnline { + conference_id, + conference_type, + unique_id, + }, + )) } } impl ToBytes for PeerOnline { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x61) >> diff --git a/tox_packet/src/messenger/conference/ping.rs b/tox_packet/src/messenger/conference/ping.rs index e96142dad..b37c4aa8f 100644 --- a/tox_packet/src/messenger/conference/ping.rs +++ b/tox_packet/src/messenger/conference/ping.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::{be_u16, be_u32}; use nom::bytes::complete::tag; +use nom::number::complete::{be_u16, be_u32}; /** Ping is a struct that holds info to send ping message to a conference. @@ -36,15 +36,19 @@ impl FromBytes for Ping { let (input, peer_id) = be_u16(input)?; let (input, message_id) = be_u32(input)?; let (input, _) = tag("\x00")(input)?; - Ok((input, Ping { - conference_id, - peer_id, - message_id, - })) + Ok(( + input, + Ping { + conference_id, + peer_id, + message_id, + }, + )) } } impl ToBytes for Ping { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x63) >> @@ -71,8 +75,5 @@ impl Ping { mod tests { use super::*; - encode_decode_test!( - ping_encode_decode, - Ping::new(1, 2, 3) - ); + encode_decode_test!(ping_encode_decode, Ping::new(1, 2, 3)); } diff --git a/tox_packet/src/messenger/conference/query.rs b/tox_packet/src/messenger/conference/query.rs index d6ba2ecb1..80f6c1191 100644 --- a/tox_packet/src/messenger/conference/query.rs +++ b/tox_packet/src/messenger/conference/query.rs @@ -3,8 +3,8 @@ use super::*; -use nom::number::complete::be_u16; use nom::bytes::complete::tag; +use nom::number::complete::be_u16; /** Query is a struct that holds info to query a peer in a conference. @@ -30,6 +30,7 @@ impl FromBytes for Query { } impl ToBytes for Query { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x62) >> @@ -50,8 +51,5 @@ impl Query { mod tests { use super::*; - encode_decode_test!( - peer_query_encode_decode, - Query::new(1) - ); + encode_decode_test!(peer_query_encode_decode, Query::new(1)); } diff --git a/tox_packet/src/messenger/conference/query_response.rs b/tox_packet/src/messenger/conference/query_response.rs index 759d5a44e..ce85def7a 100644 --- a/tox_packet/src/messenger/conference/query_response.rs +++ b/tox_packet/src/messenger/conference/query_response.rs @@ -3,10 +3,10 @@ use super::*; -use nom::number::complete::{be_u8, be_u16}; use nom::bytes::complete::tag; -use nom::multi::many0; use nom::combinator::map_res; +use nom::multi::many0; +use nom::number::complete::{be_u16, be_u8}; use std::str; use tox_crypto::*; @@ -40,14 +40,18 @@ impl FromBytes for QueryResponse { let (input, conference_id) = be_u16(input)?; let (input, _) = tag("\x09")(input)?; let (input, peer_infos) = many0(PeerInfo::from_bytes)(input)?; - Ok((input, QueryResponse { - conference_id, - peer_infos: peer_infos.to_vec() - })) + Ok(( + input, + QueryResponse { + conference_id, + peer_infos: peer_infos.to_vec(), + }, + )) } } impl ToBytes for QueryResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x62) >> @@ -96,16 +100,20 @@ impl FromBytes for PeerInfo { let (input, temp_pk) = PublicKey::from_bytes(input)?; let (input, length) = be_u8(input)?; let (input, nickname) = map_res(take(length), str::from_utf8)(input)?; - Ok((input, PeerInfo { - peer_id, - real_pk, - temp_pk, - nickname: nickname.to_string(), - })) + Ok(( + input, + PeerInfo { + peer_id, + real_pk, + temp_pk, + nickname: nickname.to_string(), + }, + )) } } impl ToBytes for PeerInfo { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u16!(self.peer_id) >> @@ -138,19 +146,23 @@ mod tests { encode_decode_test!( query_response_encode_decode, - QueryResponse::new(1, vec![ - PeerInfo { - peer_id: 1, - real_pk: SecretKey::generate(&mut thread_rng()).public_key(), - temp_pk: SecretKey::generate(&mut thread_rng()).public_key(), - nickname: "1234".to_owned(), - }, - PeerInfo { - peer_id: 2, - real_pk: SecretKey::generate(&mut thread_rng()).public_key(), - temp_pk: SecretKey::generate(&mut thread_rng()).public_key(), - nickname: "56789".to_owned(), - }]) + QueryResponse::new( + 1, + vec![ + PeerInfo { + peer_id: 1, + real_pk: SecretKey::generate(&mut thread_rng()).public_key(), + temp_pk: SecretKey::generate(&mut thread_rng()).public_key(), + nickname: "1234".to_owned(), + }, + PeerInfo { + peer_id: 2, + real_pk: SecretKey::generate(&mut thread_rng()).public_key(), + temp_pk: SecretKey::generate(&mut thread_rng()).public_key(), + nickname: "56789".to_owned(), + } + ] + ) ); #[test] @@ -178,7 +190,7 @@ mod tests { temp_pk: SecretKey::generate(&mut rng).public_key(), nickname: large_string, }; - let mut buf = [0; MAX_NAME_LENGTH_IN_CONFERENCE + 2 + 32 + 32+ 1]; // peer_id(2) + real_pk(32) + temp_pk(32) + length(1) + let mut buf = [0; MAX_NAME_LENGTH_IN_CONFERENCE + 2 + 32 + 32 + 1]; // peer_id(2) + real_pk(32) + temp_pk(32) + length(1) assert!(peer_info.to_bytes((&mut buf, 0)).is_err()); } } diff --git a/tox_packet/src/messenger/conference/title.rs b/tox_packet/src/messenger/conference/title.rs index 58967d0e4..5b9c4d7bb 100644 --- a/tox_packet/src/messenger/conference/title.rs +++ b/tox_packet/src/messenger/conference/title.rs @@ -3,12 +3,12 @@ use super::*; -use std::str; use nom::{ - number::complete::be_u16, - combinator::{rest, map_res, verify}, bytes::complete::tag, + combinator::{map_res, rest, verify}, + number::complete::be_u16, }; +use std::str; use super::MAX_NAME_LENGTH_IN_CONFERENCE; @@ -37,15 +37,22 @@ impl FromBytes for Title { let (input, _) = tag("\x62")(input)?; let (input, conference_id) = be_u16(input)?; let (input, _) = tag("\x0a")(input)?; - let (input, title) = map_res(verify(rest, |title: &[u8]| title.len() <= MAX_NAME_LENGTH_IN_CONFERENCE), str::from_utf8)(input)?; - Ok((input, Title { - conference_id, - title: title.to_string(), - })) + let (input, title) = map_res( + verify(rest, |title: &[u8]| title.len() <= MAX_NAME_LENGTH_IN_CONFERENCE), + str::from_utf8, + )(input)?; + Ok(( + input, + Title { + conference_id, + title: title.to_string(), + }, + )) } } impl ToBytes for Title { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x62) >> @@ -60,10 +67,7 @@ impl ToBytes for Title { impl Title { /// Create new Title object. pub fn new(conference_id: u16, title: String) -> Self { - Title { - conference_id, - title, - } + Title { conference_id, title } } } @@ -71,10 +75,7 @@ impl Title { mod tests { use super::*; - encode_decode_test!( - title_encode_decode, - Title::new(1, "1234".to_owned()) - ); + encode_decode_test!(title_encode_decode, Title::new(1, "1234".to_owned())); #[test] fn title_from_bytes_encoding_error() { @@ -95,7 +96,7 @@ mod tests { #[test] fn title_to_bytes_overflow() { let large_string = String::from_utf8(vec![32u8; MAX_NAME_LENGTH_IN_CONFERENCE + 1]).unwrap(); - let large_title = Title::new(1,large_string); + let large_title = Title::new(1, large_string); let mut buf = [0; MAX_NAME_LENGTH_IN_CONFERENCE + 1 + 2 + 1]; // packet id + conference id + packet kind. assert!(large_title.to_bytes((&mut buf, 0)).is_err()); } diff --git a/tox_packet/src/messenger/file_transfer/file_control.rs b/tox_packet/src/messenger/file_transfer/file_control.rs index 3b1df2f3f..cb19a180a 100644 --- a/tox_packet/src/messenger/file_transfer/file_control.rs +++ b/tox_packet/src/messenger/file_transfer/file_control.rs @@ -3,8 +3,8 @@ It is used to control transferring file to a friend. */ use super::*; -use nom::number::complete::le_u8; use nom::bytes::complete::tag; +use nom::number::complete::le_u8; /** FileControl is a struct that holds info to handle transferring file to a friend. @@ -36,15 +36,19 @@ impl FromBytes for FileControl { let (input, transfer_direction) = TransferDirection::from_bytes(input)?; let (input, file_id) = le_u8(input)?; let (input, control_type) = ControlType::from_bytes(input)?; - Ok((input, FileControl { - transfer_direction, - file_id, - control_type, - })) + Ok(( + input, + FileControl { + transfer_direction, + file_id, + control_type, + }, + )) } } impl ToBytes for FileControl { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x51) >> diff --git a/tox_packet/src/messenger/file_transfer/file_data.rs b/tox_packet/src/messenger/file_transfer/file_data.rs index 6f614b9d8..a0b100b17 100644 --- a/tox_packet/src/messenger/file_transfer/file_data.rs +++ b/tox_packet/src/messenger/file_transfer/file_data.rs @@ -3,10 +3,10 @@ It is used to transfer chunk of file data to a friend. */ use nom::{ - AsBytes, - number::complete::le_u8, - combinator::{rest, rest_len, verify}, bytes::complete::tag, + combinator::{rest, rest_len, verify}, + number::complete::le_u8, + AsBytes, }; use super::*; @@ -39,11 +39,18 @@ impl FromBytes for FileData { let (input, file_id) = le_u8(input)?; let (input, _) = verify(rest_len, |len| *len <= MAX_FILE_DATA_SIZE)(input)?; let (input, data) = rest(input)?; - Ok((input, FileData { file_id, data: data.to_vec() })) + Ok(( + input, + FileData { + file_id, + data: data.to_vec(), + }, + )) } } impl ToBytes for FileData { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x52) >> @@ -65,10 +72,7 @@ impl FileData { mod tests { use super::*; - encode_decode_test!( - file_data_encode_decode, - FileData::new(1, vec![1,2,3,4]) - ); + encode_decode_test!(file_data_encode_decode, FileData::new(1, vec![1, 2, 3, 4])); #[test] fn file_data_from_bytes_too_long() { diff --git a/tox_packet/src/messenger/file_transfer/file_send_request.rs b/tox_packet/src/messenger/file_transfer/file_send_request.rs index 393ac908c..5cbea623e 100644 --- a/tox_packet/src/messenger/file_transfer/file_send_request.rs +++ b/tox_packet/src/messenger/file_transfer/file_send_request.rs @@ -3,9 +3,9 @@ It is used to start transferring file to a friend. */ use nom::{ - combinator::{rest, map_res, verify}, - number::complete::le_u8, bytes::complete::tag, + combinator::{map_res, rest, verify}, + number::complete::le_u8, }; use std::str; @@ -45,18 +45,25 @@ impl FromBytes for FileSendRequest { let (input, file_type) = FileType::from_bytes(input)?; let (input, file_size) = be_u64(input)?; let (input, file_unique_id) = FileUid::from_bytes(input)?; - let (input, file_name) = map_res(verify(rest, |file_name: &[u8]| file_name.len() <= MAX_FILESEND_FILENAME_LENGTH), str::from_utf8)(input)?; - Ok((input, FileSendRequest { - file_id, - file_type, - file_size, - file_unique_id, - file_name: file_name.to_string(), - })) + let (input, file_name) = map_res( + verify(rest, |file_name: &[u8]| file_name.len() <= MAX_FILESEND_FILENAME_LENGTH), + str::from_utf8, + )(input)?; + Ok(( + input, + FileSendRequest { + file_id, + file_type, + file_size, + file_unique_id, + file_name: file_name.to_string(), + }, + )) } } impl ToBytes for FileSendRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x50) >> @@ -93,7 +100,9 @@ mod tests { #[test] fn file_send_request_from_bytes_encoding_error() { - let mut packet = vec![0x50, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff]; + let mut packet = vec![ + 0x50, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + ]; packet.extend_from_slice(&[42; FILE_UID_BYTES]); let err_string = vec![0, 159, 146, 150]; // not UTF8 bytes. packet.extend_from_slice(&err_string); @@ -102,7 +111,9 @@ mod tests { #[test] fn file_send_request_from_bytes_overflow() { - let mut packet = vec![0x50, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff]; + let mut packet = vec![ + 0x50, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, + ]; packet.extend_from_slice(&[42; FILE_UID_BYTES]); let large_string = vec![32; MAX_FILESEND_FILENAME_LENGTH + 1]; packet.extend_from_slice(&large_string); @@ -112,7 +123,7 @@ mod tests { #[test] fn file_send_request_to_bytes_overflow() { let large_string = String::from_utf8(vec![32u8; MAX_FILESEND_FILENAME_LENGTH + 1]).unwrap(); - let large_msg = FileSendRequest::new(1,FileType::Data,0xff00, FileUid([42; FILE_UID_BYTES]), large_string); + let large_msg = FileSendRequest::new(1, FileType::Data, 0xff00, FileUid([42; FILE_UID_BYTES]), large_string); let mut buf = [0; MAX_FILESEND_FILENAME_LENGTH + 1 + 4 + 8 + FILE_UID_BYTES]; // provide needed space for serialize. assert!(large_msg.to_bytes((&mut buf, 0)).is_err()); } diff --git a/tox_packet/src/messenger/file_transfer/mod.rs b/tox_packet/src/messenger/file_transfer/mod.rs index 6112a4393..ff0d4db6e 100644 --- a/tox_packet/src/messenger/file_transfer/mod.rs +++ b/tox_packet/src/messenger/file_transfer/mod.rs @@ -1,12 +1,15 @@ /*! File transfer packets */ -use nom::number::complete::{le_u8, be_u32, be_u64}; -use nom::error::{ErrorKind, make_error}; -use nom::combinator::{map, map_opt}; use nom::branch::alt; use nom::bytes::complete::take; -use rand::{Rng, distributions::{Distribution, Standard}}; +use nom::combinator::{map, map_opt}; +use nom::error::{make_error, ErrorKind}; +use nom::number::complete::{be_u32, be_u64, le_u8}; +use rand::{ + distributions::{Distribution, Standard}, + Rng, +}; use tox_binary_io::*; @@ -18,15 +21,7 @@ pub use self::file_control::*; pub use self::file_data::*; pub use self::file_send_request::*; -use cookie_factory::{ - do_gen, - gen_slice, - gen_call, - gen_cond, - gen_be_u8, - gen_be_u32, - gen_be_u64, -}; +use cookie_factory::{do_gen, gen_be_u32, gen_be_u64, gen_be_u8, gen_call, gen_cond, gen_slice}; /// Maximum size in bytes of chunk of file data const MAX_FILE_DATA_SIZE: usize = 1371; @@ -37,7 +32,7 @@ pub enum TransferDirection { /// I am a sender Send = 0, /// I am a receiver - Receive + Receive, } impl FromBytes for TransferDirection { @@ -57,11 +52,11 @@ pub enum ControlType { /// Accept a request of transferring file from a peer Accept, /// Pause transferring - Pause , + Pause, /// Stop transferring and quit session Kill, /// Seek to position of file stream and holds seek parameter - Seek(u64) + Seek(u64), } impl ToBytes for ControlType { @@ -70,9 +65,7 @@ impl ToBytes for ControlType { ControlType::Accept => do_gen!(buf, gen_be_u8!(0x00)), ControlType::Pause => do_gen!(buf, gen_be_u8!(0x01)), ControlType::Kill => do_gen!(buf, gen_be_u8!(0x02)), - ControlType::Seek(seek_param) => do_gen!(buf, - gen_be_u8!(0x03) >> - gen_be_u64!(*seek_param)) + ControlType::Seek(seek_param) => do_gen!(buf, gen_be_u8!(0x03) >> gen_be_u64!(*seek_param)), } } } @@ -128,7 +121,7 @@ impl Distribution for Standard { impl FileUid { fn from_slice(bs: &[u8]) -> Option { if bs.len() != FILE_UID_BYTES { - return None + return None; } let mut n = [0; FILE_UID_BYTES]; n.clone_from_slice(bs); @@ -186,11 +179,17 @@ mod tests { encode_decode_test!( packet_file_data_encode_decode, - Packet::FileData(FileData::new(1, vec![1,2,3,4])) + Packet::FileData(FileData::new(1, vec![1, 2, 3, 4])) ); encode_decode_test!( packet_file_send_request_encode_decode, - Packet::FileSendRequest(FileSendRequest::new(1, FileType::Avatar, 4, FileUid([42; FILE_UID_BYTES]), "data".to_string())) + Packet::FileSendRequest(FileSendRequest::new( + 1, + FileType::Avatar, + 4, + FileUid([42; FILE_UID_BYTES]), + "data".to_string() + )) ); } diff --git a/tox_packet/src/messenger/message.rs b/tox_packet/src/messenger/message.rs index 56a004d6c..0e1b55b0d 100644 --- a/tox_packet/src/messenger/message.rs +++ b/tox_packet/src/messenger/message.rs @@ -3,9 +3,9 @@ use super::*; -use std::str; -use nom::combinator::{map_res, rest, verify}; use nom::bytes::complete::tag; +use nom::combinator::{map_res, rest, verify}; +use std::str; /// Maximum size in bytes of message string of message packet const MAX_MESSAGE_DATA_SIZE: usize = 1372; @@ -30,12 +30,16 @@ pub struct Message { impl FromBytes for Message { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, _) = tag("\x40")(input)?; - let (input, msg) = map_res(verify(rest, |msg: &[u8]| msg.len() <= MAX_MESSAGE_DATA_SIZE), str::from_utf8)(input)?; + let (input, msg) = map_res( + verify(rest, |msg: &[u8]| msg.len() <= MAX_MESSAGE_DATA_SIZE), + str::from_utf8, + )(input)?; Ok((input, Message { msg: msg.to_string() })) } } impl ToBytes for Message { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x40) >> @@ -56,10 +60,7 @@ impl Message { mod tests { use super::*; - encode_decode_test!( - message_encode_decode, - Message::new("1234".to_string()) - ); + encode_decode_test!(message_encode_decode, Message::new("1234".to_string())); #[test] fn message_from_bytes_encoding_error() { diff --git a/tox_packet/src/messenger/mod.rs b/tox_packet/src/messenger/mod.rs index be9ff7e30..1eaf18961 100644 --- a/tox_packet/src/messenger/mod.rs +++ b/tox_packet/src/messenger/mod.rs @@ -6,25 +6,25 @@ use tox_binary_io::*; mod conference; mod file_transfer; -mod online; mod action; -mod offline; mod message; -mod nickname; mod msi; +mod nickname; +mod offline; +mod online; +mod status_message; mod typing; mod user_status; -mod status_message; -pub use self::online::*; pub use self::action::*; -pub use self::offline::*; pub use self::message::*; -pub use self::nickname::*; pub use self::msi::*; +pub use self::nickname::*; +pub use self::offline::*; +pub use self::online::*; +pub use self::status_message::*; pub use self::typing::*; pub use self::user_status::*; -pub use self::status_message::*; pub use crate::messenger::conference::Packet as ConferencePacket; pub use crate::messenger::file_transfer::Packet as FileTransferPacket; @@ -32,14 +32,7 @@ pub use crate::messenger::file_transfer::Packet as FileTransferPacket; use nom::branch::alt; use nom::combinator::map; -use cookie_factory::{ - do_gen, - gen_slice, - gen_call, - gen_cond, - gen_be_u8, - gen_le_u8, -}; +use cookie_factory::{do_gen, gen_be_u8, gen_call, gen_cond, gen_le_u8, gen_slice}; /** Messenger packet enum that encapsulates all types of Messenger packets. */ @@ -107,26 +100,20 @@ impl FromBytes for Packet { #[cfg(test)] mod tests { - use rand::{Rng, thread_rng}; + use rand::{thread_rng, Rng}; use super::*; use crate::messenger::conference::{ConferenceType, Invite}; - use crate::messenger::file_transfer::{FileControl, TransferDirection, ControlType}; + use crate::messenger::file_transfer::{ControlType, FileControl, TransferDirection}; - encode_decode_test!( - packet_online_encode_decode, - Packet::Online(Online) - ); + encode_decode_test!(packet_online_encode_decode, Packet::Online(Online)); encode_decode_test!( packet_action_encode_decode, Packet::Action(Action::new("1234".to_string())) ); - encode_decode_test!( - packet_offline_encode_decode, - Packet::Offline(Offline) - ); + encode_decode_test!(packet_offline_encode_decode, Packet::Offline(Offline)); encode_decode_test!( packet_message_encode_decode, @@ -161,11 +148,19 @@ mod tests { encode_decode_test!( packet_conference_encode_decode, - Packet::Conference(ConferencePacket::Invite(Invite::new(1, ConferenceType::Text, thread_rng().gen()))) + Packet::Conference(ConferencePacket::Invite(Invite::new( + 1, + ConferenceType::Text, + thread_rng().gen() + ))) ); encode_decode_test!( packet_file_transfer_encode_decode, - Packet::FileTransfer(FileTransferPacket::FileControl(FileControl::new(TransferDirection::Send, 1, ControlType::Seek(100)))) + Packet::FileTransfer(FileTransferPacket::FileControl(FileControl::new( + TransferDirection::Send, + 1, + ControlType::Seek(100) + ))) ); } diff --git a/tox_packet/src/messenger/msi.rs b/tox_packet/src/messenger/msi.rs index c2a4b89a1..1872d8bf6 100644 --- a/tox_packet/src/messenger/msi.rs +++ b/tox_packet/src/messenger/msi.rs @@ -3,15 +3,15 @@ use super::*; +use bitflags::*; use nom::{ - Err, bytes::complete::tag, combinator::{rest_len, verify}, - error::{Error, ErrorKind, make_error}, + error::{make_error, Error, ErrorKind}, multi::many_till, - number::complete::le_u8 + number::complete::le_u8, + Err, }; -use bitflags::*; /// Maximum size in bytes of msi message packet const MAX_MSI_PAYLOAD_SIZE: usize = 256; @@ -81,6 +81,7 @@ impl FromBytes for Request { } impl ToBytes for Request { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u8!(0x01) >> // Request @@ -99,6 +100,7 @@ impl FromBytes for MsiError { } impl ToBytes for MsiError { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u8!(0x02) >> // MsiError @@ -124,6 +126,7 @@ impl FromBytes for Capabilities { } impl ToBytes for Capabilities { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u8!(0x03) >> // Capabilities @@ -242,9 +245,15 @@ impl Msi { let mut capabilities = None; for sub in sub_packets { match sub { - MsiSubPacket::Request(req) => { request = Some(req); }, - MsiSubPacket::MsiError(err) => { error = Some(err); }, - MsiSubPacket::Capabilities(capa) => { capabilities = Some(capa); }, + MsiSubPacket::Request(req) => { + request = Some(req); + } + MsiSubPacket::MsiError(err) => { + error = Some(err); + } + MsiSubPacket::Capabilities(capa) => { + capabilities = Some(capa); + } }; } let request = if let Some(request) = request { @@ -277,6 +286,7 @@ impl FromBytes for Msi { } impl ToBytes for Msi { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_le_u8!(0x45) >> @@ -294,14 +304,16 @@ mod tests { encode_decode_test!( msi_encode_decode, - Msi::new(RequestKind::Init, Some(MsiErrorKind::MsiNone), CapabilitiesKind::SEND_AUDIO) + Msi::new( + RequestKind::Init, + Some(MsiErrorKind::MsiNone), + CapabilitiesKind::SEND_AUDIO + ) ); #[test] fn msi_from_bytes_too_long() { - let mut input = vec![0x45, - 1, 1, 1, - ]; + let mut input = vec![0x45, 1, 1, 1]; let too_long = [47; MAX_MSI_PAYLOAD_SIZE]; input.extend_from_slice(&too_long); assert!(Msi::from_bytes(&input).is_err()); @@ -309,8 +321,8 @@ mod tests { #[test] fn msi_redundant() { - let input = [0x45, - 1, 1, 1, // request + let input = [ + 0x45, 1, 1, 1, // request 1, 1, 2, // redundant request 2, 1, 1, // last error 3, 1, 4, // last capabilities @@ -320,11 +332,12 @@ mod tests { let (_rest, value) = Msi::from_bytes(&input).unwrap(); let mut buf = [0; MAX_MSI_PAYLOAD_SIZE]; let (after_value, size) = value.to_bytes((&mut buf, 0)).unwrap(); - assert_eq!(after_value[..size], [0x45, - 1, 1, 3, // last request of input - 2, 1, 1, - 3, 1, 4, - 0, - ]) + assert_eq!( + after_value[..size], + [ + 0x45, 1, 1, 3, // last request of input + 2, 1, 1, 3, 1, 4, 0, + ] + ) } } diff --git a/tox_packet/src/messenger/nickname.rs b/tox_packet/src/messenger/nickname.rs index 6b7171050..f4a797ea1 100644 --- a/tox_packet/src/messenger/nickname.rs +++ b/tox_packet/src/messenger/nickname.rs @@ -3,9 +3,9 @@ use super::*; -use std::str; -use nom::combinator::{rest, map_res, verify}; use nom::bytes::complete::tag; +use nom::combinator::{map_res, rest, verify}; +use std::str; /// Maximum size in bytes of nickname string of nickname packet const MAX_NICKNAME_DATA_SIZE: usize = 128; @@ -32,12 +32,21 @@ pub struct Nickname { impl FromBytes for Nickname { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, _) = tag("\x30")(input)?; - let (input, nickname) = map_res(verify(rest, |nickname: &[u8]| nickname.len() <= MAX_NICKNAME_DATA_SIZE), str::from_utf8)(input)?; - Ok((input, Nickname { nickname: nickname.to_string() })) + let (input, nickname) = map_res( + verify(rest, |nickname: &[u8]| nickname.len() <= MAX_NICKNAME_DATA_SIZE), + str::from_utf8, + )(input)?; + Ok(( + input, + Nickname { + nickname: nickname.to_string(), + }, + )) } } impl ToBytes for Nickname { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x30) >> @@ -58,10 +67,7 @@ impl Nickname { mod tests { use super::*; - encode_decode_test!( - nickname_encode_decode, - Nickname::new("1234".to_string()) - ); + encode_decode_test!(nickname_encode_decode, Nickname::new("1234".to_string())); #[test] fn nickname_from_bytes_encoding_error() { diff --git a/tox_packet/src/messenger/offline.rs b/tox_packet/src/messenger/offline.rs index 64b7a6f2b..a454141c1 100644 --- a/tox_packet/src/messenger/offline.rs +++ b/tox_packet/src/messenger/offline.rs @@ -24,6 +24,7 @@ impl FromBytes for Offline { } impl ToBytes for Offline { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x19) @@ -35,9 +36,5 @@ impl ToBytes for Offline { mod tests { use super::*; - encode_decode_test!( - offline_encode_decode, - Offline - ); - + encode_decode_test!(offline_encode_decode, Offline); } diff --git a/tox_packet/src/messenger/online.rs b/tox_packet/src/messenger/online.rs index 1d1f5a220..047ddec35 100644 --- a/tox_packet/src/messenger/online.rs +++ b/tox_packet/src/messenger/online.rs @@ -23,6 +23,7 @@ impl FromBytes for Online { } impl ToBytes for Online { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x18) @@ -34,9 +35,5 @@ impl ToBytes for Online { mod tests { use super::*; - encode_decode_test!( - online_encode_decode, - Online - ); - + encode_decode_test!(online_encode_decode, Online); } diff --git a/tox_packet/src/messenger/status_message.rs b/tox_packet/src/messenger/status_message.rs index f8fa59609..ce9d24d07 100644 --- a/tox_packet/src/messenger/status_message.rs +++ b/tox_packet/src/messenger/status_message.rs @@ -5,9 +5,9 @@ This packet is sent to my friends every time they become online, or whenever my use super::*; -use std::str; -use nom::combinator::{rest, map_res, verify}; use nom::bytes::complete::tag; +use nom::combinator::{map_res, rest, verify}; +use std::str; /// Maximum size in bytes of status message string const MAX_STATUS_MESSAGE_DATA_SIZE: usize = 1007; @@ -32,12 +32,16 @@ pub struct StatusMessage(String); impl FromBytes for StatusMessage { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, _) = tag("\x31")(input)?; - let (input, message) = map_res(verify(rest, |message: &[u8]| message.len() <= MAX_STATUS_MESSAGE_DATA_SIZE), str::from_utf8)(input)?; + let (input, message) = map_res( + verify(rest, |message: &[u8]| message.len() <= MAX_STATUS_MESSAGE_DATA_SIZE), + str::from_utf8, + )(input)?; Ok((input, StatusMessage(message.to_string()))) } } impl ToBytes for StatusMessage { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x31) >> @@ -58,10 +62,7 @@ impl StatusMessage { mod tests { use super::*; - encode_decode_test!( - status_message_encode_decode, - StatusMessage::new("Happy!".to_string()) - ); + encode_decode_test!(status_message_encode_decode, StatusMessage::new("Happy!".to_string())); #[test] fn status_message_from_bytes_encoding_error() { diff --git a/tox_packet/src/messenger/typing.rs b/tox_packet/src/messenger/typing.rs index 1fcedac9e..c1063c673 100644 --- a/tox_packet/src/messenger/typing.rs +++ b/tox_packet/src/messenger/typing.rs @@ -3,9 +3,9 @@ use super::*; -use nom::number::complete::le_u8; use nom::bytes::complete::tag; -use nom::error::{ErrorKind, make_error}; +use nom::error::{make_error, ErrorKind}; +use nom::number::complete::le_u8; /// Typing status of user #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -51,6 +51,7 @@ impl FromBytes for Typing { } impl ToBytes for Typing { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x33) >> @@ -70,8 +71,5 @@ impl Typing { mod tests { use super::*; - encode_decode_test!( - typing_encode_decode, - Typing::new(TypingStatus::Typing) - ); + encode_decode_test!(typing_encode_decode, Typing::new(TypingStatus::Typing)); } diff --git a/tox_packet/src/messenger/user_status.rs b/tox_packet/src/messenger/user_status.rs index 20980ed81..3c3afc547 100644 --- a/tox_packet/src/messenger/user_status.rs +++ b/tox_packet/src/messenger/user_status.rs @@ -3,9 +3,9 @@ use super::*; -use nom::number::complete::le_u8; use nom::bytes::complete::tag; -use nom::error::{ErrorKind, make_error}; +use nom::error::{make_error, ErrorKind}; +use nom::number::complete::le_u8; /// Status of user #[derive(Clone, Copy, Debug, Eq, PartialEq)] @@ -56,6 +56,7 @@ impl FromBytes for UserStatus { } impl ToBytes for UserStatus { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x32) >> @@ -75,8 +76,5 @@ impl UserStatus { mod tests { use super::*; - encode_decode_test!( - user_status_encode_decode, - UserStatus::new(PeerStatus::Online) - ); + encode_decode_test!(user_status_encode_decode, UserStatus::new(PeerStatus::Online)); } diff --git a/tox_packet/src/onion/friend_request.rs b/tox_packet/src/onion/friend_request.rs index 5115264e6..28e5ce3f6 100644 --- a/tox_packet/src/onion/friend_request.rs +++ b/tox_packet/src/onion/friend_request.rs @@ -2,10 +2,10 @@ */ use super::*; -use std::str; use crate::toxid::{NoSpam, NOSPAMBYTES}; use nom::bytes::complete::tag; use nom::combinator::{map_res, verify}; +use std::str; const MAX_FRIEND_REQUEST_MSG_SIZE: usize = MAX_ONION_CLIENT_DATA_SIZE - (1 + NOSPAMBYTES); @@ -28,14 +28,12 @@ pub struct FriendRequest { impl FriendRequest { /// Create new object pub fn new(nospam: NoSpam, msg: String) -> Self { - FriendRequest { - nospam, - msg, - } + FriendRequest { nospam, msg } } } impl ToBytes for FriendRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x20) >> @@ -50,11 +48,19 @@ impl FromBytes for FriendRequest { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, _) = tag(&[0x20][..])(input)?; let (input, nospam) = NoSpam::from_bytes(input)?; - let (input, msg) = map_res(verify(rest, |msg: &[u8]| msg.len() <= MAX_FRIEND_REQUEST_MSG_SIZE && !msg.is_empty()), str::from_utf8)(input)?; - Ok((input, FriendRequest { - nospam, - msg: msg.to_string(), - })) + let (input, msg) = map_res( + verify(rest, |msg: &[u8]| { + msg.len() <= MAX_FRIEND_REQUEST_MSG_SIZE && !msg.is_empty() + }), + str::from_utf8, + )(input)?; + Ok(( + input, + FriendRequest { + nospam, + msg: msg.to_string(), + }, + )) } } @@ -98,7 +104,7 @@ mod tests { let large_string = String::from_utf8(vec![32u8; MAX_FRIEND_REQUEST_MSG_SIZE + 1]).unwrap(); let friend_req = FriendRequest { nospam: NoSpam([42; NOSPAMBYTES]), - msg: large_string + msg: large_string, }; let mut buf = [0; MAX_ONION_CLIENT_DATA_SIZE + 1]; // `1` is to provide enough space for success of serializing assert!(friend_req.to_bytes((&mut buf, 0)).is_err()); diff --git a/tox_packet/src/onion/inner_onion_request.rs b/tox_packet/src/onion/inner_onion_request.rs index 0c87a29b2..acdb60bad 100644 --- a/tox_packet/src/onion/inner_onion_request.rs +++ b/tox_packet/src/onion/inner_onion_request.rs @@ -3,9 +3,9 @@ use super::*; -use tox_binary_io::*; use nom::branch::alt; use nom::combinator::map; +use tox_binary_io::*; /** Onion requests that can be enclosed in onion packets and sent through onion path. @@ -18,7 +18,7 @@ pub enum InnerOnionRequest { /// [`InnerOnionAnnounceRequest`](./struct.InnerOnionAnnounceRequest.html) structure. InnerOnionAnnounceRequest(InnerOnionAnnounceRequest), /// [`InnerOnionDataRequest`](./struct.InnerOnionDataRequest.html) structure. - InnerOnionDataRequest(InnerOnionDataRequest) + InnerOnionDataRequest(InnerOnionDataRequest), } impl ToBytes for InnerOnionRequest { @@ -33,8 +33,14 @@ impl ToBytes for InnerOnionRequest { impl FromBytes for InnerOnionRequest { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { alt(( - map(InnerOnionAnnounceRequest::from_bytes, InnerOnionRequest::InnerOnionAnnounceRequest), - map(InnerOnionDataRequest::from_bytes, InnerOnionRequest::InnerOnionDataRequest), + map( + InnerOnionAnnounceRequest::from_bytes, + InnerOnionRequest::InnerOnionAnnounceRequest, + ), + map( + InnerOnionDataRequest::from_bytes, + InnerOnionRequest::InnerOnionDataRequest, + ), ))(input) } } diff --git a/tox_packet/src/onion/inner_onion_response.rs b/tox_packet/src/onion/inner_onion_response.rs index 3e9fd4ae2..4c1a2cfa9 100644 --- a/tox_packet/src/onion/inner_onion_response.rs +++ b/tox_packet/src/onion/inner_onion_response.rs @@ -18,7 +18,7 @@ pub enum InnerOnionResponse { /// [`OnionAnnounceResponse`](./struct.OnionAnnounceResponse.html) structure. OnionAnnounceResponse(OnionAnnounceResponse), /// [`OnionDataResponse`](./struct.OnionDataResponse.html) structure. - OnionDataResponse(OnionDataResponse) + OnionDataResponse(OnionDataResponse), } impl ToBytes for InnerOnionResponse { @@ -33,7 +33,10 @@ impl ToBytes for InnerOnionResponse { impl FromBytes for InnerOnionResponse { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { alt(( - map(OnionAnnounceResponse::from_bytes, InnerOnionResponse::OnionAnnounceResponse), + map( + OnionAnnounceResponse::from_bytes, + InnerOnionResponse::OnionAnnounceResponse, + ), map(OnionDataResponse::from_bytes, InnerOnionResponse::OnionDataResponse), ))(input) } diff --git a/tox_packet/src/onion/mod.rs b/tox_packet/src/onion/mod.rs index a8d0a1885..b69088777 100644 --- a/tox_packet/src/onion/mod.rs +++ b/tox_packet/src/onion/mod.rs @@ -1,10 +1,11 @@ /*! Onion UDP Packets */ -mod onion_announce_request; -mod onion_announce_response; +mod friend_request; mod inner_onion_request; mod inner_onion_response; +mod onion_announce_request; +mod onion_announce_response; mod onion_data_request; mod onion_data_response; mod onion_request_0; @@ -13,12 +14,12 @@ mod onion_request_2; mod onion_response_1; mod onion_response_2; mod onion_response_3; -mod friend_request; -pub use self::onion_announce_request::*; -pub use self::onion_announce_response::*; +pub use self::friend_request::*; pub use self::inner_onion_request::*; pub use self::inner_onion_response::*; +pub use self::onion_announce_request::*; +pub use self::onion_announce_response::*; pub use self::onion_data_request::*; pub use self::onion_data_response::*; pub use self::onion_request_0::*; @@ -27,40 +28,41 @@ pub use self::onion_request_2::*; pub use self::onion_response_1::*; pub use self::onion_response_2::*; pub use self::onion_response_3::*; -pub use self::friend_request::*; -use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; -use tox_binary_io::*; -use tox_crypto::*; -use xsalsa20poly1305::{XSalsa20Poly1305, aead::{Aead, Error as AeadError}}; use crate::dht::packed_node::PackedNode; use crate::ip_port::*; +use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, +}; +use tox_binary_io::*; +use tox_crypto::*; +use xsalsa20poly1305::{ + aead::{Aead, Error as AeadError}, + XSalsa20Poly1305, +}; use rand::{CryptoRng, Rng}; +use nom::error::{make_error, ErrorKind}; use nom::number::complete::le_u8; -use nom::error::{ErrorKind, make_error}; - -use cookie_factory::{ - do_gen, - gen_slice, - gen_call, - gen_cond, - gen_be_u8, - gen_le_u64, - gen_many_ref -}; + +use cookie_factory::{do_gen, gen_be_u8, gen_call, gen_cond, gen_le_u64, gen_many_ref, gen_slice}; use nom::{ + combinator::{cond, rest, rest_len}, Err, - combinator::{rest, rest_len, cond}, }; use std::io::{Error, ErrorKind as IoErrorKind}; const ONION_SEND_BASE: usize = crypto_box::KEY_SIZE + SIZE_IPPORT + ::TagSize::USIZE; const ONION_SEND_1: usize = xsalsa20poly1305::NONCE_SIZE + ONION_SEND_BASE * 3; const MAX_ONION_DATA_SIZE: usize = ONION_MAX_PACKET_SIZE - (ONION_SEND_1 + 1); // 1 is for packet_id -const MIN_ONION_DATA_REQUEST_SIZE: usize = 1 + crypto_box::KEY_SIZE + xsalsa20poly1305::NONCE_SIZE + crypto_box::KEY_SIZE + ::TagSize::USIZE; // 1 is for packet_id +const MIN_ONION_DATA_REQUEST_SIZE: usize = 1 + + crypto_box::KEY_SIZE + + xsalsa20poly1305::NONCE_SIZE + + crypto_box::KEY_SIZE + + ::TagSize::USIZE; // 1 is for packet_id /// Maximum size in butes of Onion Data Request packet pub const MAX_DATA_REQUEST_SIZE: usize = MAX_ONION_DATA_SIZE - MIN_ONION_DATA_REQUEST_SIZE; /// Minimum size in bytes of Onion Data Response packet @@ -69,11 +71,14 @@ pub const MIN_ONION_DATA_RESPONSE_SIZE: usize = crypto_box::KEY_SIZE + ::TagSize::USIZE; // 59 +pub const ONION_RETURN_1_SIZE: usize = + xsalsa20poly1305::NONCE_SIZE + SIZE_IPPORT + ::TagSize::USIZE; // 59 /// Size of second `OnionReturn` struct with one inner `OnionReturn`. -pub const ONION_RETURN_2_SIZE: usize = xsalsa20poly1305::NONCE_SIZE + SIZE_IPPORT + ::TagSize::USIZE + ONION_RETURN_1_SIZE; // 118 +pub const ONION_RETURN_2_SIZE: usize = + xsalsa20poly1305::NONCE_SIZE + SIZE_IPPORT + ::TagSize::USIZE + ONION_RETURN_1_SIZE; // 118 /// Size of third `OnionReturn` struct with two inner `OnionReturn`s. -pub const ONION_RETURN_3_SIZE: usize = xsalsa20poly1305::NONCE_SIZE + SIZE_IPPORT + ::TagSize::USIZE + ONION_RETURN_2_SIZE; // 177 +pub const ONION_RETURN_3_SIZE: usize = + xsalsa20poly1305::NONCE_SIZE + SIZE_IPPORT + ::TagSize::USIZE + ONION_RETURN_2_SIZE; // 177 /// The maximum size of onion packet including public key, nonce, packet kind /// byte, onion return. @@ -103,18 +108,25 @@ pub struct OnionReturn { /// Nonce for the current encrypted payload pub nonce: [u8; xsalsa20poly1305::NONCE_SIZE], /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for OnionReturn { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, nonce) = <[u8; xsalsa20poly1305::NONCE_SIZE]>::from_bytes(input)?; let (input, payload) = rest(input)?; - Ok((input, OnionReturn { nonce, payload: payload.to_vec() })) + Ok(( + input, + OnionReturn { + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for OnionReturn { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.nonce.as_ref()) >> @@ -125,6 +137,7 @@ impl ToBytes for OnionReturn { impl OnionReturn { #[allow(clippy::needless_pass_by_value)] + #[rustfmt::skip] fn inner_to_bytes<'a>(ip_port: &IpPort, inner: Option<&OnionReturn>, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, ip_port| IpPort::to_bytes(ip_port, buf, IpPortPadding::WithPadding), ip_port) >> @@ -143,7 +156,12 @@ impl OnionReturn { } /// Create new `OnionReturn` object using symmetric key for encryption. - pub fn new(rng: &mut R, symmetric_key: &XSalsa20Poly1305, ip_port: &IpPort, inner: Option<&OnionReturn>) -> OnionReturn { + pub fn new( + rng: &mut R, + symmetric_key: &XSalsa20Poly1305, + ip_port: &IpPort, + inner: Option<&OnionReturn>, + ) -> OnionReturn { let nonce = XSalsa20Poly1305::generate_nonce(rng); let mut buf = [0; ONION_RETURN_2_SIZE + SIZE_IPPORT]; let (_, size) = OnionReturn::inner_to_bytes(ip_port, inner, (&mut buf, 0)).unwrap(); @@ -151,7 +169,7 @@ impl OnionReturn { OnionReturn { nonce: nonce.into(), - payload + payload, } } @@ -163,26 +181,23 @@ impl OnionReturn { - fails to parse as `IpPort` with possibly inner `OnionReturn` */ pub fn get_payload(&self, symmetric_key: &XSalsa20Poly1305) -> Result<(IpPort, Option), Error> { - let decrypted = symmetric_key.decrypt(&self.nonce.into(), self.payload.as_slice()) - .map_err(|AeadError| { - Error::new(IoErrorKind::Other, "OnionReturn decrypt error.") - })?; + let decrypted = symmetric_key + .decrypt(&self.nonce.into(), self.payload.as_slice()) + .map_err(|AeadError| Error::new(IoErrorKind::Other, "OnionReturn decrypt error."))?; match OnionReturn::inner_from_bytes(&decrypted) { - Err(Err::Incomplete(e)) => { - Err(Error::new(IoErrorKind::Other, - format!("Inner onion return deserialize error: {:?}", e))) - }, - Err(Err::Error(e)) => { - Err(Error::new(IoErrorKind::Other, - format!("Inner onion return deserialize error: {:?}", e))) - }, - Err(Err::Failure(e)) => { - Err(Error::new(IoErrorKind::Other, - format!("Inner onion return deserialize error: {:?}", e))) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(Err::Incomplete(e)) => Err(Error::new( + IoErrorKind::Other, + format!("Inner onion return deserialize error: {:?}", e), + )), + Err(Err::Error(e)) => Err(Error::new( + IoErrorKind::Other, + format!("Inner onion return deserialize error: {:?}", e), + )), + Err(Err::Failure(e)) => Err(Error::new( + IoErrorKind::Other, + format!("Inner onion return deserialize error: {:?}", e), + )), + Ok((_, inner)) => Ok(inner), } } } @@ -199,7 +214,7 @@ pub enum AnnounceStatus { /// Requested node is found by its long term `PublicKey` Found = 1, /// We successfully announced ourselves - Announced = 2 + Announced = 2, } impl FromBytes for AnnounceStatus { @@ -237,20 +252,11 @@ mod tests { } ); - encode_decode_test!( - announce_status_failed, - AnnounceStatus::Failed - ); + encode_decode_test!(announce_status_failed, AnnounceStatus::Failed); - encode_decode_test!( - announce_status_found, - AnnounceStatus::Found - ); + encode_decode_test!(announce_status_found, AnnounceStatus::Found); - encode_decode_test!( - announce_status_accounced, - AnnounceStatus::Announced - ); + encode_decode_test!(announce_status_accounced, AnnounceStatus::Announced); #[test] fn onion_return_encrypt_decrypt() { @@ -261,14 +267,14 @@ mod tests { let ip_port_1 = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return_1 = OnionReturn::new(&mut rng, &alice_symmetric_key, &ip_port_1, None); // bob encrypt let ip_port_2 = IpPort { protocol: ProtocolType::Udp, ip_addr: "7.8.5.6".parse().unwrap(), - port: 54321 + port: 54321, }; let onion_return_2 = OnionReturn::new(&mut rng, &bob_symmetric_key, &ip_port_2, Some(&onion_return_1)); // bob can decrypt it's return address @@ -291,14 +297,14 @@ mod tests { let ip_port_1 = IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }; let onion_return_1 = OnionReturn::new(&mut rng, &alice_symmetric_key, &ip_port_1, None); // bob encrypt let ip_port_2 = IpPort { protocol: ProtocolType::Udp, ip_addr: "7.8.5.6".parse().unwrap(), - port: 54321 + port: 54321, }; let onion_return_2 = OnionReturn::new(&mut rng, &bob_symmetric_key, &ip_port_2, Some(&onion_return_1)); // eve can't decrypt return addresses @@ -324,7 +330,7 @@ mod tests { let invalid_payload_encoded = symmetric_key.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_onion_return = OnionReturn { nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; assert!(invalid_onion_return.get_payload(&symmetric_key).is_err()); } diff --git a/tox_packet/src/onion/onion_announce_request.rs b/tox_packet/src/onion/onion_announce_request.rs index 459b52704..4ad5bb89b 100644 --- a/tox_packet/src/onion/onion_announce_request.rs +++ b/tox_packet/src/onion/onion_announce_request.rs @@ -3,18 +3,18 @@ use super::*; +use crate::dht::*; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::*; use nom::{ + bytes::complete::{tag, take}, + combinator::{eof, map_parser, rest, rest_len, verify}, number::complete::le_u64, - combinator::{rest, rest_len, map_parser, verify, eof}, - bytes::complete::{take, tag} }; -use sha2::Sha256; use sha2::digest::typenum::Unsigned; use sha2::digest::OutputSizeUser; +use sha2::Sha256; /// The type of onion ping ID which is SHA256 hash. pub type PingId = [u8; ::OutputSize::USIZE]; @@ -53,7 +53,7 @@ pub struct InnerOnionAnnounceRequest { /// Temporary or real `PublicKey` for the current encrypted payload pub pk: PublicKey, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for InnerOnionAnnounceRequest { @@ -62,15 +62,19 @@ impl FromBytes for InnerOnionAnnounceRequest { let (input, nonce) = Nonce::from_bytes(input)?; let (input, pk) = PublicKey::from_bytes(input)?; let (input, payload) = rest(input)?; - Ok((input, InnerOnionAnnounceRequest { - nonce, - pk, - payload: payload.to_vec() - })) + Ok(( + input, + InnerOnionAnnounceRequest { + nonce, + pk, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for InnerOnionAnnounceRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x83) >> @@ -83,13 +87,21 @@ impl ToBytes for InnerOnionAnnounceRequest { impl InnerOnionAnnounceRequest { /// Create new `InnerOnionAnnounceRequest` object. - pub fn new(shared_secret: &SalsaBox, pk: PublicKey, payload: &OnionAnnounceRequestPayload) -> InnerOnionAnnounceRequest { + pub fn new( + shared_secret: &SalsaBox, + pk: PublicKey, + payload: &OnionAnnounceRequestPayload, + ) -> InnerOnionAnnounceRequest { let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()); let mut buf = [0; ONION_MAX_PACKET_SIZE]; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); let payload = shared_secret.encrypt(&nonce, &buf[..size]).unwrap(); - InnerOnionAnnounceRequest { nonce: nonce.into(), pk, payload } + InnerOnionAnnounceRequest { + nonce: nonce.into(), + pk, + payload, + } } /** Decrypt payload and try to parse it as `OnionAnnounceRequestPayload`. @@ -100,17 +112,12 @@ impl InnerOnionAnnounceRequest { - fails to parse as `OnionAnnounceRequestPayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionAnnounceRequestPayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -138,19 +145,25 @@ pub struct OnionAnnounceRequest { /// Inner announce request that was enclosed in onion packets pub inner: InnerOnionAnnounceRequest, /// Return address encrypted by the third node from onion chain - pub onion_return: OnionReturn + pub onion_return: OnionReturn, } impl FromBytes for OnionAnnounceRequest { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, rest_len) = verify(rest_len, |len| *len <= ONION_MAX_PACKET_SIZE && *len >= ONION_RETURN_3_SIZE)(input)?; - let (input, inner) = map_parser(take(rest_len - ONION_RETURN_3_SIZE), InnerOnionAnnounceRequest::from_bytes)(input)?; + let (input, rest_len) = verify(rest_len, |len| { + *len <= ONION_MAX_PACKET_SIZE && *len >= ONION_RETURN_3_SIZE + })(input)?; + let (input, inner) = map_parser( + take(rest_len - ONION_RETURN_3_SIZE), + InnerOnionAnnounceRequest::from_bytes, + )(input)?; let (input, onion_return) = OnionReturn::from_bytes(input)?; Ok((input, OnionAnnounceRequest { inner, onion_return })) } } impl ToBytes for OnionAnnounceRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, inner| InnerOnionAnnounceRequest::to_bytes(inner, buf), &self.inner) >> @@ -181,7 +194,7 @@ pub struct OnionAnnounceRequestPayload { /// `PublicKey` that should be used for sending data packets pub data_pk: PublicKey, /// Data to send back in the response - pub sendback_data: u64 + pub sendback_data: u64, } impl FromBytes for OnionAnnounceRequestPayload { @@ -191,11 +204,20 @@ impl FromBytes for OnionAnnounceRequestPayload { let (input, data_pk) = PublicKey::from_bytes(input)?; let (input, sendback_data) = le_u64(input)?; let (input, _) = eof(input)?; - Ok((input, OnionAnnounceRequestPayload { ping_id, search_pk, data_pk, sendback_data })) + Ok(( + input, + OnionAnnounceRequestPayload { + ping_id, + search_pk, + data_pk, + sendback_data, + }, + )) } } impl ToBytes for OnionAnnounceRequestPayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.ping_id.as_ref()) >> @@ -258,7 +280,7 @@ mod tests { ping_id: [42; ::OutputSize::USIZE], search_pk: SecretKey::generate(&mut rng).public_key(), data_pk: SecretKey::generate(&mut rng).public_key(), - sendback_data: 12345 + sendback_data: 12345, }; // encode payload with shared secret let onion_packet = InnerOnionAnnounceRequest::new(&shared_secret, alice_pk, &payload); @@ -280,7 +302,7 @@ mod tests { ping_id: [42; ::OutputSize::USIZE], search_pk: SecretKey::generate(&mut rng).public_key(), data_pk: SecretKey::generate(&mut rng).public_key(), - sendback_data: 12345 + sendback_data: 12345, }; // encode payload with shared secret let onion_packet = InnerOnionAnnounceRequest::new(&shared_secret, alice_pk, &payload); @@ -304,7 +326,7 @@ mod tests { let invalid_onion_announce_request = InnerOnionAnnounceRequest { nonce: nonce.into(), pk: pk.clone(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; assert!(invalid_onion_announce_request.get_payload(&shared_secret).is_err()); // Try short incomplete array @@ -313,7 +335,7 @@ mod tests { let invalid_onion_announce_request = InnerOnionAnnounceRequest { nonce: nonce.into(), pk, - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; assert!(invalid_onion_announce_request.get_payload(&shared_secret).is_err()); } diff --git a/tox_packet/src/onion/onion_announce_response.rs b/tox_packet/src/onion/onion_announce_response.rs index 4f2a48537..3666661ac 100644 --- a/tox_packet/src/onion/onion_announce_response.rs +++ b/tox_packet/src/onion/onion_announce_response.rs @@ -3,16 +3,16 @@ use super::*; +use crate::dht::*; use crypto_box::SalsaBox; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::*; use nom::{ - number::complete::le_u64, - combinator::{rest, rest_len, verify, success, eof}, bytes::complete::tag, + combinator::{eof, rest, rest_len, success, verify}, multi::many0, + number::complete::le_u64, }; /** It's used to respond to `OnionAnnounceRequest` packet. @@ -40,7 +40,7 @@ pub struct OnionAnnounceResponse { /// Nonce for the current encrypted payload pub nonce: Nonce, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for OnionAnnounceResponse { @@ -50,15 +50,19 @@ impl FromBytes for OnionAnnounceResponse { let (input, sendback_data) = le_u64(input)?; let (input, nonce) = Nonce::from_bytes(input)?; let (input, payload) = rest(input)?; - Ok((input, OnionAnnounceResponse { - sendback_data, - nonce, - payload: payload.to_vec() - })) + Ok(( + input, + OnionAnnounceResponse { + sendback_data, + nonce, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for OnionAnnounceResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x84) >> @@ -72,13 +76,21 @@ impl ToBytes for OnionAnnounceResponse { impl OnionAnnounceResponse { /// Create new `OnionAnnounceResponse` object. - pub fn new(shared_secret: &SalsaBox, sendback_data: u64, payload: &OnionAnnounceResponsePayload) -> OnionAnnounceResponse { + pub fn new( + shared_secret: &SalsaBox, + sendback_data: u64, + payload: &OnionAnnounceResponsePayload, + ) -> OnionAnnounceResponse { let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()); let mut buf = [0; ONION_MAX_PACKET_SIZE]; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); let payload = shared_secret.encrypt(&nonce, &buf[..size]).unwrap(); - OnionAnnounceResponse { sendback_data, nonce: nonce.into(), payload } + OnionAnnounceResponse { + sendback_data, + nonce: nonce.into(), + payload, + } } /** Decrypt payload and try to parse it as `OnionAnnounceResponsePayload`. @@ -89,17 +101,12 @@ impl OnionAnnounceResponse { - fails to parse as `OnionAnnounceResponsePayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionAnnounceResponsePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -134,7 +141,7 @@ pub struct OnionAnnounceResponsePayload { /// Onion ping id or PublicKey that should be used to send data packets pub ping_id_or_pk: [u8; 32], /// Up to 4 closest to the requested PublicKey DHT nodes - pub nodes: Vec + pub nodes: Vec, } impl FromBytes for OnionAnnounceResponsePayload { @@ -144,15 +151,19 @@ impl FromBytes for OnionAnnounceResponsePayload { let (input, nodes) = many0(PackedNode::from_bytes)(input)?; let (input, _) = verify(success(nodes.len()), |len| *len <= 4_usize)(input)?; let (input, _) = eof(input)?; - Ok((input, OnionAnnounceResponsePayload { - announce_status, - ping_id_or_pk, - nodes - })) + Ok(( + input, + OnionAnnounceResponsePayload { + announce_status, + ping_id_or_pk, + nodes, + }, + )) } } impl ToBytes for OnionAnnounceResponsePayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, announce_status| AnnounceStatus::to_bytes(announce_status, buf), &self.announce_status) >> @@ -168,8 +179,8 @@ impl ToBytes for OnionAnnounceResponsePayload { #[cfg(test)] mod tests { use super::*; - use rand::thread_rng; use crypto_box::SecretKey; + use rand::thread_rng; use std::net::SocketAddr; @@ -187,9 +198,10 @@ mod tests { OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Found, ping_id_or_pk: [42; 32], - nodes: vec![ - PackedNode::new(SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), SecretKey::generate(&mut thread_rng()).public_key()) - ] + nodes: vec![PackedNode::new( + SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), + SecretKey::generate(&mut thread_rng()).public_key() + )] } ); @@ -202,9 +214,10 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Found, ping_id_or_pk: [42; 32], - nodes: vec![ - PackedNode::new(SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), SecretKey::generate(&mut rng).public_key()) - ] + nodes: vec![PackedNode::new( + SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), + SecretKey::generate(&mut rng).public_key(), + )], }; // encode payload with shared secret let onion_packet = OnionAnnounceResponse::new(&shared_secret, 12345, &payload); @@ -224,9 +237,10 @@ mod tests { let payload = OnionAnnounceResponsePayload { announce_status: AnnounceStatus::Found, ping_id_or_pk: [42; 32], - nodes: vec![ - PackedNode::new(SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), SecretKey::generate(&mut rng).public_key()) - ] + nodes: vec![PackedNode::new( + SocketAddr::V4("5.6.7.8:12345".parse().unwrap()), + SecretKey::generate(&mut rng).public_key(), + )], }; // encode payload with shared secret let onion_packet = OnionAnnounceResponse::new(&shared_secret, 12345, &payload); @@ -249,7 +263,7 @@ mod tests { let invalid_onion_announce_response = OnionAnnounceResponse { sendback_data: 12345, nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; assert!(invalid_onion_announce_response.get_payload(&shared_secret).is_err()); // Try short incomplete array @@ -258,7 +272,7 @@ mod tests { let invalid_onion_announce_response = OnionAnnounceResponse { sendback_data: 12345, nonce: nonce.into(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; assert!(invalid_onion_announce_response.get_payload(&shared_secret).is_err()); } diff --git a/tox_packet/src/onion/onion_data_request.rs b/tox_packet/src/onion/onion_data_request.rs index c5a87bbc3..6cf1173ae 100644 --- a/tox_packet/src/onion/onion_data_request.rs +++ b/tox_packet/src/onion/onion_data_request.rs @@ -3,14 +3,14 @@ use super::*; -use tox_binary_io::*; -use tox_crypto::*; use crate::dht::*; use crate::onion::MAX_ONION_RESPONSE_PAYLOAD_SIZE; +use tox_binary_io::*; +use tox_crypto::*; use nom::{ - combinator::{rest, rest_len, map_parser, verify}, - bytes::complete::{take, tag}, + bytes::complete::{tag, take}, + combinator::{map_parser, rest, rest_len, verify}, }; /** It's used to send data requests to dht node using onion paths. @@ -41,7 +41,7 @@ pub struct InnerOnionDataRequest { /// Temporary `PublicKey` for the current encrypted payload pub temporary_pk: PublicKey, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for InnerOnionDataRequest { @@ -51,16 +51,20 @@ impl FromBytes for InnerOnionDataRequest { let (input, nonce) = Nonce::from_bytes(input)?; let (input, temporary_pk) = PublicKey::from_bytes(input)?; let (input, payload) = rest(input)?; - Ok((input, InnerOnionDataRequest { - destination_pk, - nonce, - temporary_pk, - payload: payload.to_vec() - })) + Ok(( + input, + InnerOnionDataRequest { + destination_pk, + nonce, + temporary_pk, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for InnerOnionDataRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x85) >> @@ -80,7 +84,7 @@ impl InnerOnionDataRequest { destination_pk: PublicKey, temporary_pk: PublicKey, nonce: Nonce, - payload: &OnionDataResponsePayload + payload: &OnionDataResponsePayload, ) -> InnerOnionDataRequest { let mut buf = [0; MAX_ONION_RESPONSE_PAYLOAD_SIZE]; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); @@ -100,17 +104,12 @@ impl InnerOnionDataRequest { - fails to parse as `OnionDataResponsePayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionDataResponsePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -137,19 +136,23 @@ pub struct OnionDataRequest { /// Inner onion data request that was enclosed in onion packets pub inner: InnerOnionDataRequest, /// Return address encrypted by the third node from onion chain - pub onion_return: OnionReturn + pub onion_return: OnionReturn, } impl FromBytes for OnionDataRequest { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - let (input, rest_len) = verify(rest_len, |len| *len <= ONION_MAX_PACKET_SIZE && *len >= ONION_RETURN_3_SIZE)(input)?; - let (input, inner) = map_parser(take(rest_len - ONION_RETURN_3_SIZE), InnerOnionDataRequest::from_bytes)(input)?; + let (input, rest_len) = verify(rest_len, |len| { + *len <= ONION_MAX_PACKET_SIZE && *len >= ONION_RETURN_3_SIZE + })(input)?; + let (input, inner) = + map_parser(take(rest_len - ONION_RETURN_3_SIZE), InnerOnionDataRequest::from_bytes)(input)?; let (input, onion_return) = OnionReturn::from_bytes(input)?; Ok((input, OnionDataRequest { inner, onion_return })) } } impl ToBytes for OnionDataRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, inner| InnerOnionDataRequest::to_bytes(inner, buf), &self.inner) >> @@ -252,7 +255,7 @@ mod tests { destination_pk: real_pk, nonce: nonce.into(), temporary_pk, - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); assert!(decoded_payload.is_err()); diff --git a/tox_packet/src/onion/onion_data_response.rs b/tox_packet/src/onion/onion_data_response.rs index 5db426613..27486295c 100644 --- a/tox_packet/src/onion/onion_data_response.rs +++ b/tox_packet/src/onion/onion_data_response.rs @@ -3,17 +3,18 @@ use super::*; +use crate::dht::*; use aead::AeadCore; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::*; -use nom::combinator::{rest, rest_len, verify, map}; -use nom::bytes::complete::tag; use nom::branch::alt; +use nom::bytes::complete::tag; +use nom::combinator::{map, rest, rest_len, verify}; /// Maximum size in bytes of Onion Data Response payload -pub const MAX_ONION_RESPONSE_PAYLOAD_SIZE: usize = MAX_ONION_CLIENT_DATA_SIZE + crypto_box::KEY_SIZE + ::TagSize::USIZE; +pub const MAX_ONION_RESPONSE_PAYLOAD_SIZE: usize = + MAX_ONION_CLIENT_DATA_SIZE + crypto_box::KEY_SIZE + ::TagSize::USIZE; /** When onion node receives `OnionDataRequest` packet it converts it to `OnionDataResponse` and sends to destination node if it announced itself @@ -38,7 +39,7 @@ pub struct OnionDataResponse { /// Temporary `PublicKey` for the current encrypted payload pub temporary_pk: PublicKey, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for OnionDataResponse { @@ -48,15 +49,19 @@ impl FromBytes for OnionDataResponse { let (input, nonce) = Nonce::from_bytes(input)?; let (input, temporary_pk) = PublicKey::from_bytes(input)?; let (input, payload) = rest(input)?; - Ok((input, OnionDataResponse { - nonce, - temporary_pk, - payload: payload.to_vec() - })) + Ok(( + input, + OnionDataResponse { + nonce, + temporary_pk, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for OnionDataResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x86) >> @@ -71,7 +76,12 @@ impl ToBytes for OnionDataResponse { impl OnionDataResponse { /// Create `OnionDataResponse` from `OnionDataResponsePayload` encrypting it /// with `shared_key` and `nonce` - pub fn new(shared_secret: &SalsaBox, temporary_pk: PublicKey, nonce: Nonce, payload: &OnionDataResponsePayload) -> OnionDataResponse { + pub fn new( + shared_secret: &SalsaBox, + temporary_pk: PublicKey, + nonce: Nonce, + payload: &OnionDataResponsePayload, + ) -> OnionDataResponse { let mut buf = [0; MAX_ONION_RESPONSE_PAYLOAD_SIZE]; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); let payload = shared_secret.encrypt((&nonce).into(), &buf[..size]).unwrap(); @@ -91,17 +101,12 @@ impl OnionDataResponse { - fails to parse as `OnionDataResponsePayload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionDataResponsePayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -133,14 +138,18 @@ impl FromBytes for OnionDataResponsePayload { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, real_pk) = PublicKey::from_bytes(input)?; let (input, payload) = rest(input)?; - Ok((input, OnionDataResponsePayload { - real_pk, - payload: payload.to_vec() - })) + Ok(( + input, + OnionDataResponsePayload { + real_pk, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for OnionDataResponsePayload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.real_pk.as_ref()) >> @@ -152,15 +161,17 @@ impl ToBytes for OnionDataResponsePayload { impl OnionDataResponsePayload { /// Create `OnionDataResponsePayload` from `OnionDataResponseInnerPayload` /// encrypting it with `shared_key` and `nonce` - pub fn new(shared_secret: &SalsaBox, real_pk: PublicKey, nonce: &Nonce, payload: &OnionDataResponseInnerPayload) -> OnionDataResponsePayload { + pub fn new( + shared_secret: &SalsaBox, + real_pk: PublicKey, + nonce: &Nonce, + payload: &OnionDataResponseInnerPayload, + ) -> OnionDataResponsePayload { let mut buf = [0; MAX_ONION_CLIENT_DATA_SIZE]; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); let payload = shared_secret.encrypt(nonce.into(), &buf[..size]).unwrap(); - OnionDataResponsePayload { - real_pk, - payload, - } + OnionDataResponsePayload { real_pk, payload } } /** Decrypt payload and try to parse it as `OnionDataResponseInnerPayload`. @@ -170,18 +181,17 @@ impl OnionDataResponsePayload { - fails to decrypt - fails to parse as `OnionDataResponseInnerPayload` */ - pub fn get_payload(&self, nonce: &Nonce, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt(nonce.into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + pub fn get_payload( + &self, + nonce: &Nonce, + shared_secret: &SalsaBox, + ) -> Result { + let decrypted = shared_secret + .decrypt(nonce.into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionDataResponseInnerPayload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -200,7 +210,10 @@ pub enum OnionDataResponseInnerPayload { impl FromBytes for OnionDataResponseInnerPayload { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { alt(( - map(DhtPkAnnouncePayload::from_bytes, OnionDataResponseInnerPayload::DhtPkAnnounce), + map( + DhtPkAnnouncePayload::from_bytes, + OnionDataResponseInnerPayload::DhtPkAnnounce, + ), map(FriendRequest::from_bytes, OnionDataResponseInnerPayload::FriendRequest), ))(input) } @@ -288,7 +301,7 @@ mod tests { let invalid_packet = OnionDataResponse { nonce: nonce.into(), temporary_pk: alice_pk, - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&shared_secret); assert!(decoded_payload.is_err()); @@ -305,16 +318,14 @@ mod tests { let payload = OnionDataResponseInnerPayload::DhtPkAnnounce(DhtPkAnnouncePayload { no_reply: 42, dht_pk: SecretKey::generate(&mut rng).public_key(), - nodes: vec![ - TcpUdpPackedNode { - ip_port: IpPort { - protocol: ProtocolType::Udp, - ip_addr: "127.0.0.1".parse().unwrap(), - port: 12345 - }, - pk: SecretKey::generate(&mut rng).public_key(), + nodes: vec![TcpUdpPackedNode { + ip_port: IpPort { + protocol: ProtocolType::Udp, + ip_addr: "127.0.0.1".parse().unwrap(), + port: 12345, }, - ], + pk: SecretKey::generate(&mut rng).public_key(), + }], }); // encode payload with shared secret let packet = OnionDataResponsePayload::new(&shared_secret, alice_pk, &nonce, &payload); @@ -337,16 +348,14 @@ mod tests { let payload = OnionDataResponseInnerPayload::DhtPkAnnounce(DhtPkAnnouncePayload { no_reply: 42, dht_pk: SecretKey::generate(&mut rng).public_key(), - nodes: vec![ - TcpUdpPackedNode { - ip_port: IpPort { - protocol: ProtocolType::Udp, - ip_addr: "127.0.0.1".parse().unwrap(), - port: 12345 - }, - pk: SecretKey::generate(&mut rng).public_key(), + nodes: vec![TcpUdpPackedNode { + ip_port: IpPort { + protocol: ProtocolType::Udp, + ip_addr: "127.0.0.1".parse().unwrap(), + port: 12345, }, - ], + pk: SecretKey::generate(&mut rng).public_key(), + }], }); // encode payload with shared secret let packet = OnionDataResponsePayload::new(&shared_secret, alice_pk, &nonce, &payload); @@ -368,7 +377,7 @@ mod tests { let invalid_payload_encoded = shared_secret.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_packet = OnionDataResponsePayload { real_pk: alice_pk.clone(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&nonce.into(), &shared_secret); assert!(decoded_payload.is_err()); @@ -377,7 +386,7 @@ mod tests { let invalid_payload_encoded = shared_secret.encrypt(&nonce, &invalid_payload[..]).unwrap(); let invalid_packet = OnionDataResponsePayload { real_pk: alice_pk, - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; let decoded_payload = invalid_packet.get_payload(&nonce.into(), &shared_secret); assert!(decoded_payload.is_err()); diff --git a/tox_packet/src/onion/onion_request_0.rs b/tox_packet/src/onion/onion_request_0.rs index c67abbb0c..1ec8e8b49 100644 --- a/tox_packet/src/onion/onion_request_0.rs +++ b/tox_packet/src/onion/onion_request_0.rs @@ -3,18 +3,19 @@ use super::*; +use crate::dht::*; use aead::AeadCore; use crypto_box::SalsaBox; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::*; -use nom::combinator::{rest, rest_len, verify}; use nom::bytes::complete::tag; +use nom::combinator::{rest, rest_len, verify}; /// Encrypted payload should contain `IpPort`, `PublicKey` and inner encrypted /// payload that should contain at least `IpPort` struct. -const ONION_REQUEST_0_MIN_PAYLOAD_SIZE: usize = (SIZE_IPPORT + ::TagSize::USIZE) * 2 + crypto_box::KEY_SIZE; +const ONION_REQUEST_0_MIN_PAYLOAD_SIZE: usize = + (SIZE_IPPORT + ::TagSize::USIZE) * 2 + crypto_box::KEY_SIZE; /** First onion request packet. It's sent from DHT node to the first node from onion chain. Payload can be encrypted with either temporary generated @@ -39,7 +40,7 @@ pub struct OnionRequest0 { /// Temporary `PublicKey` for the current encrypted payload pub temporary_pk: PublicKey, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for OnionRequest0 { @@ -49,15 +50,19 @@ impl FromBytes for OnionRequest0 { let (input, nonce) = Nonce::from_bytes(input)?; let (input, temporary_pk) = PublicKey::from_bytes(input)?; let (input, payload) = verify(rest, |payload: &[u8]| payload.len() >= ONION_REQUEST_0_MIN_PAYLOAD_SIZE)(input)?; - Ok((input, OnionRequest0 { - nonce, - temporary_pk, - payload: payload.to_vec() - })) + Ok(( + input, + OnionRequest0 { + nonce, + temporary_pk, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for OnionRequest0 { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_cond!( @@ -81,7 +86,11 @@ impl OnionRequest0 { let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); let payload = shared_secret.encrypt(&nonce, &buf[..size]).unwrap(); - OnionRequest0 { nonce: nonce.into(), temporary_pk, payload } + OnionRequest0 { + nonce: nonce.into(), + temporary_pk, + payload, + } } /** Decrypt payload and try to parse it as `OnionRequest0Payload`. @@ -92,17 +101,12 @@ impl OnionRequest0 { - fails to parse as `OnionRequest0Payload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionRequest0Payload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -129,23 +133,27 @@ pub struct OnionRequest0Payload { /// Temporary `PublicKey` for the current encrypted payload pub temporary_pk: PublicKey, /// Inner onion payload - pub inner: Vec + pub inner: Vec, } -impl FromBytes for OnionRequest0Payload{ +impl FromBytes for OnionRequest0Payload { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, ip_port) = IpPort::from_udp_bytes(input, IpPortPadding::WithPadding)?; let (input, temporary_pk) = PublicKey::from_bytes(input)?; let (input, inner) = rest(input)?; - Ok((input, OnionRequest0Payload { - ip_port, - temporary_pk, - inner: inner.to_vec() - })) + Ok(( + input, + OnionRequest0Payload { + ip_port, + temporary_pk, + inner: inner.to_vec(), + }, + )) } } impl ToBytes for OnionRequest0Payload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, ip_port| IpPort::to_udp_bytes(ip_port, buf, IpPortPadding::WithPadding), &self.ip_port) >> @@ -194,10 +202,10 @@ mod tests { ip_port: IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }, temporary_pk: SecretKey::generate(&mut rng).public_key(), - inner: vec![42; ONION_REQUEST_0_MIN_PAYLOAD_SIZE] + inner: vec![42; ONION_REQUEST_0_MIN_PAYLOAD_SIZE], }; // encode payload with shared secret let onion_packet = OnionRequest0::new(&shared_secret, alice_pk, &payload); @@ -219,10 +227,10 @@ mod tests { ip_port: IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }, temporary_pk: SecretKey::generate(&mut rng).public_key(), - inner: vec![42; ONION_REQUEST_0_MIN_PAYLOAD_SIZE] + inner: vec![42; ONION_REQUEST_0_MIN_PAYLOAD_SIZE], }; // encode payload with shared secret let onion_packet = OnionRequest0::new(&shared_secret, alice_pk, &payload); @@ -246,7 +254,7 @@ mod tests { let invalid_onion_request_0 = OnionRequest0 { nonce: nonce.into(), temporary_pk: temporary_pk.clone(), - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; assert!(invalid_onion_request_0.get_payload(&shared_secret).is_err()); // Try short incomplete array @@ -255,7 +263,7 @@ mod tests { let invalid_onion_request_0 = OnionRequest0 { nonce: nonce.into(), temporary_pk, - payload: invalid_payload_encoded + payload: invalid_payload_encoded, }; assert!(invalid_onion_request_0.get_payload(&shared_secret).is_err()); } diff --git a/tox_packet/src/onion/onion_request_1.rs b/tox_packet/src/onion/onion_request_1.rs index db2fe4b18..fbd7fd3d0 100644 --- a/tox_packet/src/onion/onion_request_1.rs +++ b/tox_packet/src/onion/onion_request_1.rs @@ -3,14 +3,14 @@ use super::*; -use crypto_box::aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}; -use tox_binary_io::*; use crate::dht::*; +use crypto_box::aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}; +use tox_binary_io::*; use crypto_box::aead::{Aead, Error as AeadError}; use nom::{ + bytes::complete::{tag, take}, combinator::{rest, rest_len, verify}, - bytes::complete::{take, tag} }; /// Encrypted payload should contain at least `IpPort` struct. @@ -42,7 +42,7 @@ pub struct OnionRequest1 { /// Encrypted payload pub payload: Vec, /// Return address encrypted by the first node from onion chain - pub onion_return: OnionReturn + pub onion_return: OnionReturn, } impl FromBytes for OnionRequest1 { @@ -51,19 +51,25 @@ impl FromBytes for OnionRequest1 { let (input, _) = tag(&[0x81][..])(input)?; let (input, nonce) = Nonce::from_bytes(input)?; let (input, temporary_pk) = PublicKey::from_bytes(input)?; - let (input, rest_len) = verify(rest_len, |rest_len| *rest_len >= ONION_REQUEST_1_MIN_PAYLOAD_SIZE + ONION_RETURN_1_SIZE)(input)?; + let (input, rest_len) = verify(rest_len, |rest_len| { + *rest_len >= ONION_REQUEST_1_MIN_PAYLOAD_SIZE + ONION_RETURN_1_SIZE + })(input)?; let (input, payload) = take(rest_len - ONION_RETURN_1_SIZE)(input)?; let (input, onion_return) = OnionReturn::from_bytes(input)?; - Ok((input, OnionRequest1 { - nonce, - temporary_pk, - payload: payload.to_vec(), - onion_return - })) + Ok(( + input, + OnionRequest1 { + nonce, + temporary_pk, + payload: payload.to_vec(), + onion_return, + }, + )) } } impl ToBytes for OnionRequest1 { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_cond!( @@ -82,13 +88,23 @@ impl ToBytes for OnionRequest1 { impl OnionRequest1 { /// Create new `OnionRequest1` object. - pub fn new(shared_secret: &SalsaBox, temporary_pk: PublicKey, payload: &OnionRequest1Payload, onion_return: OnionReturn) -> OnionRequest1 { + pub fn new( + shared_secret: &SalsaBox, + temporary_pk: PublicKey, + payload: &OnionRequest1Payload, + onion_return: OnionReturn, + ) -> OnionRequest1 { let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()); let mut buf = [0; ONION_MAX_PACKET_SIZE]; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); let payload = shared_secret.encrypt(&nonce, &buf[..size]).unwrap(); - OnionRequest1 { nonce: nonce.into(), temporary_pk, payload, onion_return } + OnionRequest1 { + nonce: nonce.into(), + temporary_pk, + payload, + onion_return, + } } /** Decrypt payload and try to parse it as `OnionRequest1Payload`. @@ -99,17 +115,12 @@ impl OnionRequest1 { - fails to parse as `OnionRequest1Payload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionRequest1Payload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -136,7 +147,7 @@ pub struct OnionRequest1Payload { /// Temporary `PublicKey` for the current encrypted payload pub temporary_pk: PublicKey, /// Inner onion payload - pub inner: Vec + pub inner: Vec, } impl FromBytes for OnionRequest1Payload { @@ -144,15 +155,19 @@ impl FromBytes for OnionRequest1Payload { let (input, ip_port) = IpPort::from_udp_bytes(input, IpPortPadding::WithPadding)?; let (input, temporary_pk) = PublicKey::from_bytes(input)?; let (input, inner) = rest(input)?; - Ok((input, OnionRequest1Payload { - ip_port, - temporary_pk, - inner: inner.to_vec() - })) + Ok(( + input, + OnionRequest1Payload { + ip_port, + temporary_pk, + inner: inner.to_vec(), + }, + )) } } impl ToBytes for OnionRequest1Payload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, ip_port| IpPort::to_udp_bytes(ip_port, buf, IpPortPadding::WithPadding), &self.ip_port) >> @@ -206,14 +221,14 @@ mod tests { ip_port: IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }, temporary_pk: SecretKey::generate(&mut rng).public_key(), - inner: vec![42; ONION_REQUEST_1_MIN_PAYLOAD_SIZE] + inner: vec![42; ONION_REQUEST_1_MIN_PAYLOAD_SIZE], }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], }; // encode payload with shared secret let onion_packet = OnionRequest1::new(&shared_secret, alice_pk, &payload, onion_return); @@ -235,14 +250,14 @@ mod tests { ip_port: IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }, temporary_pk: SecretKey::generate(&mut rng).public_key(), - inner: vec![42; ONION_REQUEST_1_MIN_PAYLOAD_SIZE] + inner: vec![42; ONION_REQUEST_1_MIN_PAYLOAD_SIZE], }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], }; // encode payload with shared secret let onion_packet = OnionRequest1::new(&shared_secret, alice_pk, &payload, onion_return); @@ -269,8 +284,8 @@ mod tests { payload: invalid_payload_encoded, onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], + }, }; assert!(invalid_onion_request_1.get_payload(&shared_secret).is_err()); // Try short incomplete array @@ -282,8 +297,8 @@ mod tests { payload: invalid_payload_encoded, onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_1_PAYLOAD_SIZE], + }, }; assert!(invalid_onion_request_1.get_payload(&shared_secret).is_err()); } diff --git a/tox_packet/src/onion/onion_request_2.rs b/tox_packet/src/onion/onion_request_2.rs index a5aac1e68..7b43c100a 100644 --- a/tox_packet/src/onion/onion_request_2.rs +++ b/tox_packet/src/onion/onion_request_2.rs @@ -3,13 +3,13 @@ use super::*; -use nom::combinator::{rest_len, verify, eof}; +use crypto_box::{aead::Error as AeadError, SalsaBox}; use nom::bytes::complete::{tag, take}; -use crypto_box::{SalsaBox, aead::Error as AeadError}; +use nom::combinator::{eof, rest_len, verify}; +use crate::dht::*; use tox_binary_io::*; use tox_crypto::*; -use crate::dht::*; /** Third onion request packet. It's sent from the second to the third node from onion chain. Payload should be encrypted with temporary generated `SecretKey` and @@ -37,7 +37,7 @@ pub struct OnionRequest2 { /// Encrypted payload pub payload: Vec, /// Return address encrypted by the second node from onion chain - pub onion_return: OnionReturn + pub onion_return: OnionReturn, } impl FromBytes for OnionRequest2 { @@ -49,16 +49,20 @@ impl FromBytes for OnionRequest2 { let (input, rest_len) = verify(rest_len, |rest_len| *rest_len >= ONION_RETURN_2_SIZE)(input)?; let (input, payload) = take(rest_len - ONION_RETURN_2_SIZE)(input)?; let (input, onion_return) = OnionReturn::from_bytes(input)?; - Ok((input, OnionRequest2 { - nonce, - temporary_pk, - payload: payload.to_vec(), - onion_return - })) + Ok(( + input, + OnionRequest2 { + nonce, + temporary_pk, + payload: payload.to_vec(), + onion_return, + }, + )) } } impl ToBytes for OnionRequest2 { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x82) >> @@ -73,13 +77,23 @@ impl ToBytes for OnionRequest2 { impl OnionRequest2 { /// Create new `OnionRequest2` object. - pub fn new(shared_secret: &SalsaBox, temporary_pk: PublicKey, payload: &OnionRequest2Payload, onion_return: OnionReturn) -> OnionRequest2 { + pub fn new( + shared_secret: &SalsaBox, + temporary_pk: PublicKey, + payload: &OnionRequest2Payload, + onion_return: OnionReturn, + ) -> OnionRequest2 { let nonce = SalsaBox::generate_nonce(&mut rand::thread_rng()); let mut buf = [0; ONION_MAX_PACKET_SIZE]; let (_, size) = payload.to_bytes((&mut buf, 0)).unwrap(); let payload = shared_secret.encrypt(&nonce, &buf[..size]).unwrap(); - OnionRequest2 { nonce: nonce.into(), temporary_pk, payload, onion_return } + OnionRequest2 { + nonce: nonce.into(), + temporary_pk, + payload, + onion_return, + } } /** Decrypt payload and try to parse it as `OnionRequest2Payload`. @@ -90,17 +104,12 @@ impl OnionRequest2 { - fails to parse as `OnionRequest2Payload` */ pub fn get_payload(&self, shared_secret: &SalsaBox) -> Result { - let decrypted = shared_secret.decrypt((&self.nonce).into(), self.payload.as_slice()) - .map_err(|AeadError| { - GetPayloadError::decrypt() - })?; + let decrypted = shared_secret + .decrypt((&self.nonce).into(), self.payload.as_slice()) + .map_err(|AeadError| GetPayloadError::decrypt())?; match OnionRequest2Payload::from_bytes(&decrypted) { - Err(error) => { - Err(GetPayloadError::deserialize(error, decrypted.clone())) - }, - Ok((_, inner)) => { - Ok(inner) - } + Err(error) => Err(GetPayloadError::deserialize(error, decrypted.clone())), + Ok((_, inner)) => Ok(inner), } } } @@ -126,7 +135,7 @@ pub struct OnionRequest2Payload { /// Address of the next node in the onion path pub ip_port: IpPort, /// Inner onion request - pub inner: InnerOnionRequest + pub inner: InnerOnionRequest, } impl FromBytes for OnionRequest2Payload { @@ -134,14 +143,12 @@ impl FromBytes for OnionRequest2Payload { let (input, ip_port) = IpPort::from_udp_bytes(input, IpPortPadding::WithPadding)?; let (input, inner) = InnerOnionRequest::from_bytes(input)?; let (input, _) = eof(input)?; - Ok((input, OnionRequest2Payload { - ip_port, - inner - })) + Ok((input, OnionRequest2Payload { ip_port, inner })) } } impl ToBytes for OnionRequest2Payload { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, ip_port| IpPort::to_udp_bytes(ip_port, buf, IpPortPadding::WithPadding), &self.ip_port) >> @@ -200,18 +207,18 @@ mod tests { ip_port: IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }, inner: InnerOnionRequest::InnerOnionDataRequest(InnerOnionDataRequest { destination_pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] - }) + payload: vec![42; 123], + }), }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], }; // encode payload with shared secret let onion_packet = OnionRequest2::new(&shared_secret, alice_pk, &payload, onion_return); @@ -233,18 +240,18 @@ mod tests { ip_port: IpPort { protocol: ProtocolType::Udp, ip_addr: "5.6.7.8".parse().unwrap(), - port: 12345 + port: 12345, }, inner: InnerOnionRequest::InnerOnionDataRequest(InnerOnionDataRequest { destination_pk: SecretKey::generate(&mut rng).public_key(), nonce: [42; ::NonceSize::USIZE], temporary_pk: SecretKey::generate(&mut rng).public_key(), - payload: vec![42; 123] - }) + payload: vec![42; 123], + }), }; let onion_return = OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], }; // encode payload with shared secret let onion_packet = OnionRequest2::new(&shared_secret, alice_pk, &payload, onion_return); @@ -271,8 +278,8 @@ mod tests { payload: invalid_payload_encoded, onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], + }, }; assert!(invalid_onion_request_2.get_payload(&shared_secret).is_err()); // Try short incomplete array @@ -284,8 +291,8 @@ mod tests { payload: invalid_payload_encoded, onion_return: OnionReturn { nonce: [42; xsalsa20poly1305::NONCE_SIZE], - payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE] - } + payload: vec![42; ONION_RETURN_2_PAYLOAD_SIZE], + }, }; assert!(invalid_onion_request_2.get_payload(&shared_secret).is_err()); } diff --git a/tox_packet/src/onion/onion_response_1.rs b/tox_packet/src/onion/onion_response_1.rs index f2835d2a0..6805dcdd4 100644 --- a/tox_packet/src/onion/onion_response_1.rs +++ b/tox_packet/src/onion/onion_response_1.rs @@ -3,8 +3,8 @@ use super::*; -use nom::combinator::{rest_len, map_parser, verify}; use nom::bytes::complete::{tag, take}; +use nom::combinator::{map_parser, rest_len, verify}; use tox_binary_io::*; @@ -28,7 +28,7 @@ pub struct OnionResponse1 { /// Return address encrypted by the first node from onion chain pub onion_return: OnionReturn, /// Encrypted payload - pub payload: InnerOnionResponse + pub payload: InnerOnionResponse, } impl FromBytes for OnionResponse1 { @@ -42,6 +42,7 @@ impl FromBytes for OnionResponse1 { } impl ToBytes for OnionResponse1 { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x8e) >> diff --git a/tox_packet/src/onion/onion_response_2.rs b/tox_packet/src/onion/onion_response_2.rs index 4fcfac6cf..df31fb45a 100644 --- a/tox_packet/src/onion/onion_response_2.rs +++ b/tox_packet/src/onion/onion_response_2.rs @@ -3,8 +3,8 @@ use super::*; -use nom::combinator::{rest_len, map_parser, verify}; use nom::bytes::complete::{tag, take}; +use nom::combinator::{map_parser, rest_len, verify}; use tox_binary_io::*; @@ -28,7 +28,7 @@ pub struct OnionResponse2 { /// Return address encrypted by the second node from onion chain pub onion_return: OnionReturn, /// Encrypted payload - pub payload: InnerOnionResponse + pub payload: InnerOnionResponse, } impl FromBytes for OnionResponse2 { @@ -42,6 +42,7 @@ impl FromBytes for OnionResponse2 { } impl ToBytes for OnionResponse2 { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x8d) >> @@ -55,8 +56,8 @@ impl ToBytes for OnionResponse2 { #[cfg(test)] mod tests { use super::*; - use crypto_box::{SalsaBox, aead::generic_array::typenum::marker_traits::Unsigned}; use crypto_box::aead::AeadCore; + use crypto_box::{aead::generic_array::typenum::marker_traits::Unsigned, SalsaBox}; const ONION_RETURN_2_PAYLOAD_SIZE: usize = ONION_RETURN_2_SIZE - xsalsa20poly1305::NONCE_SIZE; diff --git a/tox_packet/src/onion/onion_response_3.rs b/tox_packet/src/onion/onion_response_3.rs index 225a8ff77..243019f5f 100644 --- a/tox_packet/src/onion/onion_response_3.rs +++ b/tox_packet/src/onion/onion_response_3.rs @@ -3,8 +3,8 @@ use super::*; -use nom::combinator::{rest_len, map_parser, verify}; use nom::bytes::complete::{tag, take}; +use nom::combinator::{map_parser, rest_len, verify}; use tox_binary_io::*; @@ -28,7 +28,7 @@ pub struct OnionResponse3 { /// Return address encrypted by the third node from onion chain pub onion_return: OnionReturn, /// Encrypted payload - pub payload: InnerOnionResponse + pub payload: InnerOnionResponse, } impl FromBytes for OnionResponse3 { @@ -42,6 +42,7 @@ impl FromBytes for OnionResponse3 { } impl ToBytes for OnionResponse3 { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x8c) >> diff --git a/tox_packet/src/packed_node.rs b/tox_packet/src/packed_node.rs index b3c04186b..ec1ecafe6 100644 --- a/tox_packet/src/packed_node.rs +++ b/tox_packet/src/packed_node.rs @@ -1,14 +1,15 @@ //! Variant of PackedNode to contain both TCP and UDP +use cookie_factory::{do_gen, gen_call, gen_slice}; use tox_binary_io::*; use tox_crypto::*; -use cookie_factory::{do_gen, gen_call, gen_slice,}; use crate::ip_port::*; /// Variant of PackedNode to contain both TCP and UDP #[derive(Clone, Debug, Eq, PartialEq)] -pub struct TcpUdpPackedNode { // TODO: unify with dht::packed_node +pub struct TcpUdpPackedNode { + // TODO: unify with dht::packed_node /// IP address of the node. pub ip_port: IpPort, /// Public Key of the node. @@ -19,14 +20,12 @@ impl FromBytes for TcpUdpPackedNode { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, ip_port) = IpPort::from_bytes(input, IpPortPadding::NoPadding)?; let (input, pk) = PublicKey::from_bytes(input)?; - Ok((input, TcpUdpPackedNode { - ip_port, - pk, - })) + Ok((input, TcpUdpPackedNode { ip_port, pk })) } } impl ToBytes for TcpUdpPackedNode { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, data| IpPort::to_bytes(data, buf, IpPortPadding::NoPadding), &self.ip_port) >> diff --git a/tox_packet/src/relay/connect_notification.rs b/tox_packet/src/relay/connect_notification.rs index cc7377e9a..4555ebbac 100644 --- a/tox_packet/src/relay/connect_notification.rs +++ b/tox_packet/src/relay/connect_notification.rs @@ -3,9 +3,9 @@ use super::*; -use tox_binary_io::*; use crate::relay::connection_id::ConnectionId; use nom::bytes::complete::tag; +use tox_binary_io::*; /** Sent by server to client. Tell the client that connection_id is now connected meaning the other @@ -22,7 +22,7 @@ Length | Content #[derive(Debug, PartialEq, Eq, Clone)] pub struct ConnectNotification { /// The id of the connected client - pub connection_id: ConnectionId + pub connection_id: ConnectionId, } impl FromBytes for ConnectNotification { @@ -34,6 +34,7 @@ impl FromBytes for ConnectNotification { } impl ToBytes for ConnectNotification { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x02) >> diff --git a/tox_packet/src/relay/connection_id.rs b/tox_packet/src/relay/connection_id.rs index 18d3e82e7..9c5942442 100644 --- a/tox_packet/src/relay/connection_id.rs +++ b/tox_packet/src/relay/connection_id.rs @@ -22,7 +22,12 @@ impl ConnectionId { /// Get connection id corresponding to the index. pub fn from_index(index: u8) -> Self { - assert!(index < MAX_LINKS_N, "The index {} must be lower than {}", index, MAX_LINKS_N); + assert!( + index < MAX_LINKS_N, + "The index {} must be lower than {}", + index, + MAX_LINKS_N + ); ConnectionId(Some(NonZeroU8::new(index + 16).unwrap())) } @@ -35,7 +40,9 @@ impl ConnectionId { impl FromBytes for ConnectionId { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { - map(verify(be_u8, |id| *id == 0 || *id >= 0x10), |id| ConnectionId(NonZeroU8::new(id)))(input) + map(verify(be_u8, |id| *id == 0 || *id >= 0x10), |id| { + ConnectionId(NonZeroU8::new(id)) + })(input) } } @@ -49,15 +56,9 @@ impl ToBytes for ConnectionId { mod test { use super::*; - encode_decode_test!( - connection_id_encode_decode, - ConnectionId::from_index(42) - ); + encode_decode_test!(connection_id_encode_decode, ConnectionId::from_index(42)); - encode_decode_test!( - connection_id_0_encode_decode, - ConnectionId::zero() - ); + encode_decode_test!(connection_id_0_encode_decode, ConnectionId::zero()); #[test] fn zero() { diff --git a/tox_packet/src/relay/data.rs b/tox_packet/src/relay/data.rs index 4d76c82e2..c0b61f750 100644 --- a/tox_packet/src/relay/data.rs +++ b/tox_packet/src/relay/data.rs @@ -3,10 +3,10 @@ use super::*; -use tox_binary_io::*; -use crate::dht::{CookieRequest, CookieResponse, CryptoHandshake, CryptoData}; +use crate::dht::{CookieRequest, CookieResponse, CryptoData, CryptoHandshake}; use crate::relay::connection_id::ConnectionId; -use nom::{combinator::map, branch::alt}; +use nom::{branch::alt, combinator::map}; +use tox_binary_io::*; /** Sent by client to server. The client sends data with `connection_id` and the server @@ -37,6 +37,7 @@ impl FromBytes for Data { } impl ToBytes for Data { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_call!(|buf, connection_id| ConnectionId::to_bytes(connection_id, buf), &self.connection_id) >> diff --git a/tox_packet/src/relay/disconnect_notification.rs b/tox_packet/src/relay/disconnect_notification.rs index c7546e170..4b2aaecb8 100644 --- a/tox_packet/src/relay/disconnect_notification.rs +++ b/tox_packet/src/relay/disconnect_notification.rs @@ -3,9 +3,9 @@ use super::*; -use tox_binary_io::*; use crate::relay::connection_id::ConnectionId; use nom::bytes::complete::tag; +use tox_binary_io::*; /** Sent by client to server. Sent when client wants the server to forget about the connection related @@ -32,7 +32,7 @@ Length | Content #[derive(Debug, PartialEq, Eq, Clone)] pub struct DisconnectNotification { /// The id of the disconnected client - pub connection_id: ConnectionId + pub connection_id: ConnectionId, } impl FromBytes for DisconnectNotification { @@ -44,6 +44,7 @@ impl FromBytes for DisconnectNotification { } impl ToBytes for DisconnectNotification { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x03) >> diff --git a/tox_packet/src/relay/handshake.rs b/tox_packet/src/relay/handshake.rs index cc19cbdf4..7ae272f7c 100644 --- a/tox_packet/src/relay/handshake.rs +++ b/tox_packet/src/relay/handshake.rs @@ -45,6 +45,7 @@ impl FromBytes for ClientHandshake { } impl ToBytes for ClientHandshake { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.pk.as_ref()) >> diff --git a/tox_packet/src/relay/mod.rs b/tox_packet/src/relay/mod.rs index 1b994d3a3..0de7316de 100644 --- a/tox_packet/src/relay/mod.rs +++ b/tox_packet/src/relay/mod.rs @@ -2,46 +2,38 @@ to [Tox spec](https://zetok.github.io/tox-spec/#encrypted-payload-types) */ -pub mod connection_id; -mod route_request; -mod route_response; mod connect_notification; +pub mod connection_id; +mod data; mod disconnect_notification; -mod ping_request; -mod pong_response; -mod oob_send; -mod oob_receive; mod onion_request; mod onion_response; -mod data; +mod oob_receive; +mod oob_send; +mod ping_request; +mod pong_response; +mod route_request; +mod route_response; -pub use self::route_request::RouteRequest; -pub use self::route_response::RouteResponse; pub use self::connect_notification::ConnectNotification; +pub use self::data::{Data, DataPayload}; pub use self::disconnect_notification::DisconnectNotification; -pub use self::ping_request::PingRequest; -pub use self::pong_response::PongResponse; -pub use self::oob_send::OobSend; -pub use self::oob_receive::OobReceive; pub use self::onion_request::OnionRequest; pub use self::onion_response::OnionResponse; -pub use self::data::{Data, DataPayload}; +pub use self::oob_receive::OobReceive; +pub use self::oob_send::OobSend; +pub use self::ping_request::PingRequest; +pub use self::pong_response::PongResponse; +pub use self::route_request::RouteRequest; +pub use self::route_response::RouteResponse; use tox_binary_io::*; -use nom::combinator::{success, verify, map}; -use nom::bytes::streaming::take; use nom::branch::alt; +use nom::bytes::streaming::take; +use nom::combinator::{map, success, verify}; -use cookie_factory::{ - do_gen, - gen_slice, - gen_call, - gen_cond, - gen_be_u8, - gen_be_u16, - gen_be_u64, -}; +use cookie_factory::{do_gen, gen_be_u16, gen_be_u64, gen_be_u8, gen_call, gen_cond, gen_slice}; use nom::number::streaming::be_u16; @@ -74,7 +66,7 @@ pub enum Packet { /// [`OnionResponse`](./struct.OnionResponse.html) structure. OnionResponse(OnionResponse), /// [`Data`](./struct.Data.html) structure. - Data(Data) + Data(Data), } /// A serialized Packet should be not longer than 2032 bytes @@ -129,7 +121,7 @@ variable | Encrypted payload (max 2048) #[derive(Debug, PartialEq, Eq, Clone)] pub struct EncryptedPacket { /// Encrypted payload - pub payload: Vec + pub payload: Vec, } /// A serialized EncryptedPacket should be not longer than 2050 bytes @@ -141,13 +133,21 @@ pub const MAX_TCP_ENC_PACKET_PAYLOAD_SIZE: usize = 2048; impl FromBytes for EncryptedPacket { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, length) = be_u16(input)?; - let (input, _) = verify(success(length), |len| *len > 0 && *len as usize <= MAX_TCP_ENC_PACKET_PAYLOAD_SIZE)(input)?; + let (input, _) = verify(success(length), |len| { + *len > 0 && *len as usize <= MAX_TCP_ENC_PACKET_PAYLOAD_SIZE + })(input)?; let (input, payload) = take(length)(input)?; - Ok((input, EncryptedPacket { payload: payload.to_vec() })) + Ok(( + input, + EncryptedPacket { + payload: payload.to_vec(), + }, + )) } } impl ToBytes for EncryptedPacket { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_cond!(self.payload.len() > MAX_TCP_ENC_PACKET_PAYLOAD_SIZE, |buf| gen_error(buf, 0)) >> @@ -157,15 +157,12 @@ impl ToBytes for EncryptedPacket { } } - #[cfg(test)] mod test { use super::*; encode_decode_test!( encrypted_packet_encode_decode, - EncryptedPacket { - payload: vec![42; 123] - } + EncryptedPacket { payload: vec![42; 123] } ); } diff --git a/tox_packet/src/relay/onion_request.rs b/tox_packet/src/relay/onion_request.rs index 8e5dc077b..8e425eb92 100644 --- a/tox_packet/src/relay/onion_request.rs +++ b/tox_packet/src/relay/onion_request.rs @@ -3,14 +3,14 @@ use super::*; -use crypto_box::{SalsaBox, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; -use tox_binary_io::*; -use tox_crypto::*; use crate::ip_port::*; -use crate::onion::{ - ONION_MAX_PACKET_SIZE, - ONION_RETURN_1_SIZE, +use crate::onion::{ONION_MAX_PACKET_SIZE, ONION_RETURN_1_SIZE}; +use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, }; +use tox_binary_io::*; +use tox_crypto::*; use nom::bytes::complete::tag; use nom::combinator::{rest, verify}; @@ -21,7 +21,8 @@ const ONION_MIN_PAYLOAD_SIZE: usize = (SIZE_IPPORT + ::Tag /// `OnionRequest1` packet with encrypted payload from `OnionRequest` packet /// shouldn't be bigger than `ONION_MAX_PACKET_SIZE`. -const ONION_MAX_PAYLOAD_SIZE: usize = ONION_MAX_PACKET_SIZE - (1 + NONCEBYTES + crypto_box::KEY_SIZE + ONION_RETURN_1_SIZE); +const ONION_MAX_PAYLOAD_SIZE: usize = + ONION_MAX_PACKET_SIZE - (1 + NONCEBYTES + crypto_box::KEY_SIZE + ONION_RETURN_1_SIZE); /** Sent by client to server. The server will pack payload from this request to `OnionRequest1` packet and send @@ -54,7 +55,7 @@ pub struct OnionRequest { /// Temporary `PublicKey` for the current encrypted payload pub temporary_pk: PublicKey, /// Encrypted payload - pub payload: Vec + pub payload: Vec, } impl FromBytes for OnionRequest { @@ -63,15 +64,23 @@ impl FromBytes for OnionRequest { let (input, nonce) = Nonce::from_bytes(input)?; let (input, ip_port) = IpPort::from_bytes(input, IpPortPadding::WithPadding)?; let (input, temporary_pk) = PublicKey::from_bytes(input)?; - let (input, payload) = verify( - rest, - |payload: &[u8]| payload.len() >= ONION_MIN_PAYLOAD_SIZE && payload.len() <= ONION_MAX_PAYLOAD_SIZE - )(input)?; - Ok((input, OnionRequest { nonce, ip_port, temporary_pk, payload: payload.to_vec() })) + let (input, payload) = verify(rest, |payload: &[u8]| { + payload.len() >= ONION_MIN_PAYLOAD_SIZE && payload.len() <= ONION_MAX_PAYLOAD_SIZE + })(input)?; + Ok(( + input, + OnionRequest { + nonce, + ip_port, + temporary_pk, + payload: payload.to_vec(), + }, + )) } } impl ToBytes for OnionRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_cond!( diff --git a/tox_packet/src/relay/onion_response.rs b/tox_packet/src/relay/onion_response.rs index bfb6500c7..bbc48288b 100644 --- a/tox_packet/src/relay/onion_response.rs +++ b/tox_packet/src/relay/onion_response.rs @@ -3,9 +3,9 @@ use super::*; -use tox_binary_io::*; use crate::onion::InnerOnionResponse; use nom::bytes::complete::tag; +use tox_binary_io::*; /** Sent by server to client. The server just sends payload from `OnionResponse1` packet that it got from a @@ -22,7 +22,7 @@ variable | Payload #[derive(Debug, PartialEq, Eq, Clone)] pub struct OnionResponse { /// Inner onion response - pub payload: InnerOnionResponse + pub payload: InnerOnionResponse, } impl FromBytes for OnionResponse { @@ -34,6 +34,7 @@ impl FromBytes for OnionResponse { } impl ToBytes for OnionResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x09) >> @@ -46,9 +47,12 @@ impl ToBytes for OnionResponse { mod test { use super::*; - use crypto_box::{SalsaBox, SecretKey, aead::{AeadCore, generic_array::typenum::marker_traits::Unsigned}}; - use rand::thread_rng; use crate::onion::{OnionAnnounceResponse, OnionDataResponse}; + use crypto_box::{ + aead::{generic_array::typenum::marker_traits::Unsigned, AeadCore}, + SalsaBox, SecretKey, + }; + use rand::thread_rng; encode_decode_test!( onion_response_with_announce_encode_decode, diff --git a/tox_packet/src/relay/oob_receive.rs b/tox_packet/src/relay/oob_receive.rs index c93476c14..1b0b0ceb3 100644 --- a/tox_packet/src/relay/oob_receive.rs +++ b/tox_packet/src/relay/oob_receive.rs @@ -6,8 +6,8 @@ use super::*; use tox_binary_io::*; use tox_crypto::*; -use nom::combinator::rest; use nom::bytes::complete::tag; +use nom::combinator::rest; /** Sent by server to client. OOB recv are sent with the announced public key of the peer that sent the @@ -27,7 +27,7 @@ pub struct OobReceive { /// Public Key of the sender pub sender_pk: PublicKey, /// OOB data packet - pub data: Vec + pub data: Vec, } impl FromBytes for OobReceive { @@ -35,11 +35,18 @@ impl FromBytes for OobReceive { let (input, _) = tag("\x07")(input)?; let (input, sender_pk) = PublicKey::from_bytes(input)?; let (input, data) = rest(input)?; - Ok((input, OobReceive { sender_pk, data: data.to_vec() })) + Ok(( + input, + OobReceive { + sender_pk, + data: data.to_vec(), + }, + )) } } impl ToBytes for OobReceive { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x07) >> diff --git a/tox_packet/src/relay/oob_send.rs b/tox_packet/src/relay/oob_send.rs index 8f390c5bc..e6489042d 100644 --- a/tox_packet/src/relay/oob_send.rs +++ b/tox_packet/src/relay/oob_send.rs @@ -6,8 +6,8 @@ use super::*; use tox_binary_io::*; use tox_crypto::*; -use nom::combinator::rest; use nom::bytes::complete::tag; +use nom::combinator::rest; /** Sent by client to server. If a peer with private key equal to the key they announced themselves with is @@ -37,7 +37,7 @@ pub struct OobSend { /// Public Key of the receiver pub destination_pk: PublicKey, /// OOB data packet - pub data: Vec + pub data: Vec, } impl FromBytes for OobSend { @@ -45,11 +45,18 @@ impl FromBytes for OobSend { let (input, _) = tag("\x06")(input)?; let (input, destination_pk) = PublicKey::from_bytes(input)?; let (input, data) = rest(input)?; - Ok((input, OobSend { destination_pk, data: data.to_vec() })) + Ok(( + input, + OobSend { + destination_pk, + data: data.to_vec(), + }, + )) } } impl ToBytes for OobSend { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x06) >> diff --git a/tox_packet/src/relay/ping_request.rs b/tox_packet/src/relay/ping_request.rs index a50c4e747..44fb6c6d3 100644 --- a/tox_packet/src/relay/ping_request.rs +++ b/tox_packet/src/relay/ping_request.rs @@ -5,8 +5,8 @@ use super::*; use tox_binary_io::*; -use nom::number::complete::be_u64; use nom::bytes::complete::tag; +use nom::number::complete::be_u64; /** Sent by both client and server, both will respond. Ping packets are used to know if the other side of the connection is still @@ -32,7 +32,7 @@ Length | Content #[derive(Debug, PartialEq, Eq, Clone)] pub struct PingRequest { /// The id of ping - pub ping_id: u64 + pub ping_id: u64, } impl FromBytes for PingRequest { @@ -44,6 +44,7 @@ impl FromBytes for PingRequest { } impl ToBytes for PingRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x04) >> @@ -56,10 +57,5 @@ impl ToBytes for PingRequest { mod test { use super::*; - encode_decode_test!( - ping_request_encode_decode, - PingRequest { - ping_id: 12345 - } - ); + encode_decode_test!(ping_request_encode_decode, PingRequest { ping_id: 12345 }); } diff --git a/tox_packet/src/relay/pong_response.rs b/tox_packet/src/relay/pong_response.rs index ad05c482d..f20a854ac 100644 --- a/tox_packet/src/relay/pong_response.rs +++ b/tox_packet/src/relay/pong_response.rs @@ -5,8 +5,8 @@ use super::*; use tox_binary_io::*; -use nom::number::complete::be_u64; use nom::bytes::complete::tag; +use nom::number::complete::be_u64; /** Sent by both client and server, both will respond. The server should respond to ping packets with pong packets with the same `ping_id` @@ -24,18 +24,19 @@ Length | Content #[derive(Debug, PartialEq, Eq, Clone)] pub struct PongResponse { /// The id of ping to respond - pub ping_id: u64 + pub ping_id: u64, } impl FromBytes for PongResponse { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, _) = tag("\x05")(input)?; let (input, ping_id) = be_u64(input)?; - Ok((input, PongResponse { ping_id })) + Ok((input, PongResponse { ping_id })) } } impl ToBytes for PongResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x05) >> @@ -48,10 +49,5 @@ impl ToBytes for PongResponse { mod test { use super::*; - encode_decode_test!( - pong_response_encode_decode, - PongResponse { - ping_id: 12345 - } - ); + encode_decode_test!(pong_response_encode_decode, PongResponse { ping_id: 12345 }); } diff --git a/tox_packet/src/relay/route_request.rs b/tox_packet/src/relay/route_request.rs index b970286f7..e4fb53e63 100644 --- a/tox_packet/src/relay/route_request.rs +++ b/tox_packet/src/relay/route_request.rs @@ -3,9 +3,9 @@ use super::*; +use nom::bytes::complete::tag; use tox_binary_io::*; use tox_crypto::*; -use nom::bytes::complete::tag; /** Sent by client to server. Send a routing request to the server that we want to connect @@ -35,6 +35,7 @@ impl FromBytes for RouteRequest { } impl ToBytes for RouteRequest { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x00) >> diff --git a/tox_packet/src/relay/route_response.rs b/tox_packet/src/relay/route_response.rs index 539bed8cb..7c5d65273 100644 --- a/tox_packet/src/relay/route_response.rs +++ b/tox_packet/src/relay/route_response.rs @@ -3,10 +3,10 @@ use super::*; -use tox_binary_io::*; -use tox_crypto::*; use crate::relay::connection_id::ConnectionId; use nom::bytes::complete::tag; +use tox_binary_io::*; +use tox_crypto::*; /** Sent by server to client. The response to the routing request, tell the client if the @@ -43,6 +43,7 @@ impl FromBytes for RouteResponse { } impl ToBytes for RouteResponse { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_be_u8!(0x01) >> diff --git a/tox_packet/src/toxid.rs b/tox_packet/src/toxid.rs index 0fba3c4b2..2a9751f0b 100644 --- a/tox_packet/src/toxid.rs +++ b/tox_packet/src/toxid.rs @@ -5,13 +5,15 @@ // FIXME: ↑ improve // TODO: ↓ add logging - use std::fmt; -use nom::combinator::map; -use nom::bytes::complete::take; -use rand::{CryptoRng, Rng, distributions::{Distribution, Standard}}; use cookie_factory::{do_gen, gen_slice}; +use nom::bytes::complete::take; +use nom::combinator::map; +use rand::{ + distributions::{Distribution, Standard}, + CryptoRng, Rng, +}; use tox_binary_io::*; use tox_crypto::*; @@ -62,8 +64,11 @@ assert_eq!(format!("{:X}", NoSpam([255, 255, 255, 255])), "FFFFFFFF"); */ impl fmt::UpperHex for NoSpam { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:02X}{:02X}{:02X}{:02X}", - self.0[0], self.0[1], self.0[2], self.0[3]) + write!( + f, + "{:02X}{:02X}{:02X}{:02X}", + self.0[0], self.0[1], self.0[2], self.0[3] + ) } } @@ -92,9 +97,7 @@ impl FromBytes for NoSpam { impl ToBytes for NoSpam { fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { - do_gen!(buf, - gen_slice!(&self.0) - ) + do_gen!(buf, gen_slice!(&self.0)) } } @@ -225,12 +228,13 @@ impl FromBytes for ToxId { fn from_bytes(input: &[u8]) -> IResult<&[u8], Self> { let (input, pk) = PublicKey::from_bytes(input)?; let (input, nospam) = NoSpam::from_bytes(input)?; - let (input, checksum) = map(take(CHECKSUMBYTES), |bytes: &[u8]| { [bytes[0], bytes[1]] })(input)?; + let (input, checksum) = map(take(CHECKSUMBYTES), |bytes: &[u8]| [bytes[0], bytes[1]])(input)?; Ok((input, ToxId { pk, nospam, checksum })) } } impl ToBytes for ToxId { + #[rustfmt::skip] fn to_bytes<'a>(&self, buf: (&'a mut [u8], usize)) -> Result<(&'a mut [u8], usize), GenError> { do_gen!(buf, gen_slice!(self.pk.as_ref()) >> @@ -327,10 +331,7 @@ mod tests { // NoSpam::from_bytes() - encode_decode_test!( - no_spam_encode_decode, - NoSpam([42; NOSPAMBYTES]) - ); + encode_decode_test!(no_spam_encode_decode, NoSpam([42; NOSPAMBYTES])); // ToxId::