diff --git a/src/get.rs b/src/get.rs index a0fff16242..96cd095589 100644 --- a/src/get.rs +++ b/src/get.rs @@ -53,7 +53,11 @@ async fn setup(opts: Options) -> Result { let tls_client_config = tls::make_client_config(&keypair, opts.peer_id, opts.keylog)?; let mut client_config = quinn::ClientConfig::new(Arc::new(tls_client_config)); - let mut endpoint = quinn::Endpoint::client("0.0.0.0:0".parse().unwrap())?; + let bind_addr = match opts.addr.is_ipv6() { + true => "[::]:0".parse().unwrap(), + false => "0.0.0.0:0".parse().unwrap(), + }; + let mut endpoint = quinn::Endpoint::client(bind_addr)?; let mut transport_config = quinn::TransportConfig::default(); transport_config.keep_alive_interval(Some(Duration::from_secs(1))); client_config.transport_config(Arc::new(transport_config)); diff --git a/src/lib.rs b/src/lib.rs index dc5ba6670c..baf6a27ecc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -17,7 +17,7 @@ pub use util::Hash; mod tests { use std::{ net::SocketAddr, - path::PathBuf, + path::{Path, PathBuf}, sync::{atomic::AtomicUsize, Arc}, time::Duration, }; @@ -403,4 +403,45 @@ mod tests { err.expect_err("expected an error when passing in a misbehaving `on_blob` function"); Ok(()) } + + #[tokio::test] + async fn test_ipv6() { + let readme = Path::new(env!("CARGO_MANIFEST_DIR")).join("README.md"); + let (db, hash) = create_collection(vec![readme.into()]).await.unwrap(); + let provider = match Provider::builder(db) + .bind_addr("[::1]:0".parse().unwrap()) + .spawn() + { + Ok(provider) => provider, + Err(_) => { + // We assume the problem here is IPv6 on this host. If the problem is + // not IPv6 then other tests will also fail. + return; + } + }; + let auth_token = provider.auth_token(); + let addr = provider.listen_addr(); + let peer_id = Some(provider.peer_id()); + tokio::time::timeout( + Duration::from_secs(10), + get::run( + hash, + auth_token, + get::Options { + addr, + peer_id, + keylog: true, + }, + || async move { Ok(()) }, + |_collection| async move { Ok(()) }, + |_hash, mut stream, _name| async move { + io::copy(&mut stream, &mut io::sink()).await?; + Ok(stream) + }, + ), + ) + .await + .expect("timeout") + .expect("get failed"); + } }