mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-10 07:08:05 -05:00
net: Perform full p2p code cleanup and improve certain pieces.
Notable changes: * Rewritten transport protocols into Dialer and Listener (Nym is TODO) This simplifies using the transports a lot, as can be seen for example in src/rpc, and generally around the p2p library. It also defines features for each transport (all of which are enabled by default). We drop the socks client for Tor and Nym and use first-class support with the Arti Tor library, and nym-sphinx/nym-websockets (to be used with nym-client). * Outbound session healing The outbound session will now poll and try to fill all the requested slots more efficiently, and if needed, will activate peer discovery to find more peers if we can't connect to any known ones. Also if we're unable to connect to any, we shall drop them from our set. Additionally, transport mixing is enabled by default, so when we're allowing transport mixing, and we use Tor, we will also be able to connect to other transports that Tor can connect to (e.g. tcp://). * Unix socket transport dropped We haven't been using this, and it seems we're not going down this path, so the code has been obsoleted and removed. * TLS session verification We fully verify server and client TLS certificates upon connection so we're able to perform TLS1.3 with forward secrecy. * lilith pruning lilith now periodically prunes known peers from its sets if it's unable to connect to them.
This commit is contained in:
@@ -16,66 +16,31 @@
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::{env::var, fs};
|
||||
|
||||
use async_std::{
|
||||
io,
|
||||
io::{ReadExt, WriteExt},
|
||||
stream::StreamExt,
|
||||
task,
|
||||
};
|
||||
use url::Url;
|
||||
|
||||
use darkfi::net::transport::{NymTransport, TcpTransport, TorTransport, Transport, UnixTransport};
|
||||
|
||||
#[async_std::test]
|
||||
async fn unix_transport() {
|
||||
let unix = UnixTransport::new();
|
||||
let url = Url::parse("unix:///tmp/darkfi_test.sock").unwrap();
|
||||
|
||||
let listener = unix.listen_on(url.clone()).unwrap().await.unwrap();
|
||||
|
||||
task::spawn(async move {
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
let stream = stream.unwrap();
|
||||
let (reader, writer) = &mut (&stream, &stream);
|
||||
io::copy(reader, writer).await.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
let payload = b"ohai unix";
|
||||
|
||||
let mut client = unix.dial(url, None).unwrap().await.unwrap();
|
||||
client.write_all(payload).await.unwrap();
|
||||
let mut buf = vec![0_u8; 9];
|
||||
client.read_exact(&mut buf).await.unwrap();
|
||||
|
||||
std::fs::remove_file("/tmp/darkfi_test.sock").unwrap();
|
||||
assert_eq!(buf, payload);
|
||||
}
|
||||
use darkfi::net::transport::{Dialer, Listener};
|
||||
|
||||
#[async_std::test]
|
||||
async fn tcp_transport() {
|
||||
let tcp = TcpTransport::new(None, 1024);
|
||||
let url = Url::parse("tcp://127.0.0.1:5432").unwrap();
|
||||
|
||||
let listener = tcp.listen_on(url.clone()).unwrap().await.unwrap();
|
||||
|
||||
let listener = Listener::new(url.clone()).await.unwrap().listen().await.unwrap();
|
||||
task::spawn(async move {
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
let stream = stream.unwrap();
|
||||
let (reader, writer) = &mut (&stream, &stream);
|
||||
io::copy(reader, writer).await.unwrap();
|
||||
}
|
||||
let (stream, _) = listener.next().await.unwrap();
|
||||
let (mut reader, mut writer) = smol::io::split(stream);
|
||||
io::copy(&mut reader, &mut writer).await.unwrap();
|
||||
});
|
||||
|
||||
let payload = b"ohai tcp";
|
||||
|
||||
let mut client = tcp.dial(url, None).unwrap().await.unwrap();
|
||||
let dialer = Dialer::new(url).await.unwrap();
|
||||
let mut client = dialer.dial(None).await.unwrap();
|
||||
client.write_all(payload).await.unwrap();
|
||||
let mut buf = vec![0_u8; 8];
|
||||
let mut buf = vec![0u8; 8];
|
||||
client.read_exact(&mut buf).await.unwrap();
|
||||
|
||||
assert_eq!(buf, payload);
|
||||
@@ -83,193 +48,20 @@ async fn tcp_transport() {
|
||||
|
||||
#[async_std::test]
|
||||
async fn tcp_tls_transport() {
|
||||
let tcp = TcpTransport::new(None, 1024);
|
||||
let url = Url::parse("tcp+tls://127.0.0.1:5433").unwrap();
|
||||
|
||||
let listener = tcp.listen_on(url.clone()).unwrap().await.unwrap();
|
||||
let (acceptor, listener) = tcp.upgrade_listener(listener).unwrap().await.unwrap();
|
||||
|
||||
let listener = Listener::new(url.clone()).await.unwrap().listen().await.unwrap();
|
||||
task::spawn(async move {
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
let stream = stream.unwrap();
|
||||
let stream = acceptor.accept(stream).await.unwrap();
|
||||
let (mut reader, mut writer) = smol::io::split(stream);
|
||||
match io::copy(&mut reader, &mut writer).await {
|
||||
Ok(_) => {}
|
||||
Err(e) => {
|
||||
if e.kind() != std::io::ErrorKind::UnexpectedEof {
|
||||
panic!("{}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let (stream, _) = listener.next().await.unwrap();
|
||||
let (mut reader, mut writer) = smol::io::split(stream);
|
||||
io::copy(&mut reader, &mut writer).await.unwrap();
|
||||
});
|
||||
|
||||
let payload = b"ohai tls";
|
||||
|
||||
let client = tcp.dial(url, None).unwrap().await.unwrap();
|
||||
let mut client = tcp.upgrade_dialer(client).unwrap().await.unwrap();
|
||||
let dialer = Dialer::new(url).await.unwrap();
|
||||
let mut client = dialer.dial(None).await.unwrap();
|
||||
client.write_all(payload).await.unwrap();
|
||||
let mut buf = vec![0_u8; 8];
|
||||
client.read_exact(&mut buf).await.unwrap();
|
||||
|
||||
assert_eq!(buf, payload);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
#[ignore]
|
||||
async fn tor_transport_no_control() {
|
||||
let url = Url::parse("socks5://127.0.0.1:9050").unwrap();
|
||||
let hurl = var("DARKFI_TOR_LOCAL_ADDRESS")
|
||||
.expect("Please set the env var DARKFI_TOR_LOCAL_ADDRESS to the configured local address in hidden service. \
|
||||
For example: \'export DARKFI_TOR_LOCAL_ADDRESS=\"tcp://127.0.0.1:8080\"\'");
|
||||
let hurl = Url::parse(&hurl).unwrap();
|
||||
|
||||
let onion = var("DARKFI_TOR_PUBLIC_ADDRESS").expect(
|
||||
"Please set the env var DARKFI_TOR_PUBLIC_ADDRESS to the configured onion address. \
|
||||
For example: \'export DARKFI_TOR_PUBLIC_ADDRESS=\"tor://abcdefghij234567.onion\"\'",
|
||||
);
|
||||
|
||||
let tor = TorTransport::new(url, None).unwrap();
|
||||
let listener = tor.clone().listen_on(hurl).unwrap().await.unwrap();
|
||||
|
||||
task::spawn(async move {
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
let stream = stream.unwrap();
|
||||
let (reader, writer) = &mut (&stream, &stream);
|
||||
io::copy(reader, writer).await.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
let payload = b"ohai tor";
|
||||
let url = Url::parse(&onion).unwrap();
|
||||
let mut client = tor.dial(url, None).unwrap().await.unwrap();
|
||||
client.write_all(payload).await.unwrap();
|
||||
let mut buf = vec![0_u8; 8];
|
||||
client.read_exact(&mut buf).await.unwrap();
|
||||
assert_eq!(buf, payload);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
#[ignore]
|
||||
async fn tor_transport_with_control() {
|
||||
let auth_cookie = var("DARKFI_TOR_COOKIE").expect(
|
||||
"Please set the env var DARKFI_TOR_COOKIE to the configured tor cookie file. \
|
||||
For example: \'export DARKFI_TOR_COOKIE=\"/var/lib/tor/control_auth_cookie\"\'",
|
||||
);
|
||||
let auth_cookie = hex::encode(fs::read(auth_cookie).unwrap());
|
||||
let socks_url = Url::parse("socks5://127.0.0.1:9050").unwrap();
|
||||
let torc_url = Url::parse("tcp://127.0.0.1:9051").unwrap();
|
||||
let local_url = Url::parse("tcp://127.0.0.1:8787").unwrap();
|
||||
|
||||
let tor = TorTransport::new(socks_url, Some((torc_url, auth_cookie))).unwrap();
|
||||
// generate EHS pointing to local address
|
||||
let hurl = tor.create_ehs(local_url.clone()).unwrap();
|
||||
|
||||
let listener = tor.clone().listen_on(local_url).unwrap().await.unwrap();
|
||||
|
||||
task::spawn(async move {
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
let stream = stream.unwrap();
|
||||
let (reader, writer) = &mut (&stream, &stream);
|
||||
io::copy(reader, writer).await.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
let payload = b"ohai tor";
|
||||
|
||||
let mut client = tor.dial(hurl, None).unwrap().await.unwrap();
|
||||
client.write_all(payload).await.unwrap();
|
||||
let mut buf = vec![0_u8; 8];
|
||||
client.read_exact(&mut buf).await.unwrap();
|
||||
assert_eq!(buf, payload);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
#[should_panic(expected = "Socks5Error(ReplyError(HostUnreachable))")]
|
||||
#[ignore]
|
||||
async fn tor_transport_with_control_dropped() {
|
||||
let auth_cookie = var("DARKFI_TOR_COOKIE").expect(
|
||||
"Please set the env var DARKFI_TOR_COOKIE to the configured tor cookie file. \
|
||||
For example: \'export DARKFI_TOR_COOKIE=\"/var/lib/tor/control_auth_cookie\"\'",
|
||||
);
|
||||
let auth_cookie = hex::encode(fs::read(auth_cookie).unwrap());
|
||||
let socks_url = Url::parse("socks5://127.0.0.1:9050").unwrap();
|
||||
let torc_url = Url::parse("tcp://127.0.0.1:9051").unwrap();
|
||||
let local_url = Url::parse("tcp://127.0.0.1:8787").unwrap();
|
||||
let hurl;
|
||||
// We create a new scope for the Transport, to see if when we drop it, the host is still reachable
|
||||
{
|
||||
let tor = TorTransport::new(socks_url.clone(), Some((torc_url, auth_cookie))).unwrap();
|
||||
// generate EHS pointing to local address
|
||||
hurl = tor.create_ehs(local_url.clone()).unwrap();
|
||||
// Nothing is listening, but the host is reachable.
|
||||
// In this case, dialing should fail with Socks5Error(ReplyError(GeneralFailure));
|
||||
// And not with Socks5Error(ReplyError(HostUnreachable))
|
||||
}
|
||||
|
||||
let tor_client = TorTransport::new(socks_url, None).unwrap();
|
||||
// Try to reach the host
|
||||
let _client = tor_client.dial(hurl, None).unwrap().await.unwrap();
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
#[ignore]
|
||||
async fn nym_transport() {
|
||||
let target_url = Url::parse("nym://127.0.0.1:25553").unwrap();
|
||||
|
||||
let nym = NymTransport::new().unwrap();
|
||||
|
||||
let listener = nym.clone().listen_on(target_url.clone()).unwrap().await.unwrap();
|
||||
|
||||
task::spawn(async move {
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
let stream = stream.unwrap();
|
||||
let (reader, writer) = &mut (&stream, &stream);
|
||||
io::copy(reader, writer).await.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
let payload = b"ohai nym";
|
||||
|
||||
let mut client = nym.dial(target_url, None).unwrap().await.unwrap();
|
||||
client.write_all(payload).await.unwrap();
|
||||
let mut buf = vec![0_u8; 8];
|
||||
client.read_exact(&mut buf).await.unwrap();
|
||||
|
||||
assert_eq!(buf, payload);
|
||||
}
|
||||
|
||||
#[async_std::test]
|
||||
#[ignore]
|
||||
async fn nym_tls_transport() {
|
||||
let target_url = Url::parse("nym+tls://127.0.0.1:25553").unwrap();
|
||||
|
||||
let nym = NymTransport::new().unwrap();
|
||||
|
||||
let listener = nym.clone().listen_on(target_url.clone()).unwrap().await.unwrap();
|
||||
let (acceptor, listener) = nym.clone().upgrade_listener(listener).unwrap().await.unwrap();
|
||||
|
||||
task::spawn(async move {
|
||||
let mut incoming = listener.incoming();
|
||||
while let Some(stream) = incoming.next().await {
|
||||
let stream = stream.unwrap();
|
||||
let stream = acceptor.accept(stream).await.unwrap();
|
||||
let (mut reader, mut writer) = smol::io::split(stream);
|
||||
io::copy(&mut reader, &mut writer).await.unwrap();
|
||||
}
|
||||
});
|
||||
|
||||
let payload = b"ohai nymtls";
|
||||
|
||||
let client = nym.clone().dial(target_url, None).unwrap().await.unwrap();
|
||||
let mut client = nym.upgrade_dialer(client).unwrap().await.unwrap();
|
||||
client.write_all(payload).await.unwrap();
|
||||
let mut buf = vec![0_u8; 11];
|
||||
let mut buf = vec![0u8; 8];
|
||||
client.read_exact(&mut buf).await.unwrap();
|
||||
|
||||
assert_eq!(buf, payload);
|
||||
|
||||
Reference in New Issue
Block a user