diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index ca3bb3d..7959f0e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -47,6 +47,11 @@ jobs: with: command: test args: --verbose + - name: Test (IPv6) + uses: actions-rs/cargo@v1 + with: + command: test + args: --features v6-test --verbose - name: Clippy uses: actions-rs/cargo@v1 with: diff --git a/server/Cargo.toml b/server/Cargo.toml index df8ecbc..13a495b 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -12,6 +12,9 @@ version = "1.4.1" name = "innernet-server" path = "src/main.rs" +[features] +v6-test = [] + [dependencies] anyhow = "1" bytes = "1" diff --git a/server/src/api/admin/peer.rs b/server/src/api/admin/peer.rs index b651bb6..11c7856 100644 --- a/server/src/api/admin/peer.rs +++ b/server/src/api/admin/peer.rs @@ -103,7 +103,11 @@ mod tests { let old_peers = DatabasePeer::list(&server.db().lock())?; - let peer = test::developer_peer_contents("developer3", "10.80.64.4")?; + let peer = if cfg!(feature = "v6-test") { + test::developer_peer_contents("developer3", "fd00:1337::2:0:0:3")? + } else { + test::developer_peer_contents("developer3", "10.80.64.4")? + }; let res = server .form_request(test::ADMIN_PEER_IP, "POST", "/v1/admin/peers", &peer) diff --git a/server/src/main.rs b/server/src/main.rs index 2031f8f..1e854ea 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -651,8 +651,13 @@ mod tests { async fn test_with_session_disguised_with_headers() -> Result<(), Error> { let server = test::Server::new()?; + let path = if cfg!(feature = "v6-test") { + format!("http://[{}]/v1/admin/peers", test::WG_MANAGE_PEER_IP) + } else { + format!("http://{}/v1/admin/peers", test::WG_MANAGE_PEER_IP) + }; let req = Request::builder() - .uri(format!("http://{}/v1/admin/peers", test::WG_MANAGE_PEER_IP)) + .uri(path) .header("Forwarded", format!("for={}", test::ADMIN_PEER_IP)) .header("X-Forwarded-For", test::ADMIN_PEER_IP) .header("X-Real-IP", test::ADMIN_PEER_IP) @@ -660,7 +665,11 @@ mod tests { .unwrap(); // Request from an unknown IP, trying to disguise as an admin using HTTP headers. - let res = server.raw_request("10.80.80.80", req).await; + let res = if cfg!(feature = "v6-test") { + server.raw_request("fd00:1337::1337", req).await + } else { + server.raw_request("10.80.80.80", req).await + }; // addr::remote() filter only look at remote_addr from TCP socket. // HTTP headers are not considered. This also means that innernet @@ -676,13 +685,22 @@ mod tests { let key = Key::generate_private().generate_public(); + let path = if cfg!(feature = "v6-test") { + format!("http://[{}]/v1/admin/peers", test::WG_MANAGE_PEER_IP) + } else { + format!("http://{}/v1/admin/peers", test::WG_MANAGE_PEER_IP) + }; // Request from an unknown IP, trying to disguise as an admin using HTTP headers. let req = Request::builder() - .uri(format!("http://{}/v1/admin/peers", test::WG_MANAGE_PEER_IP)) + .uri(path) .header(shared::INNERNET_PUBKEY_HEADER, key.to_base64()) .body(Body::empty()) .unwrap(); - let res = server.raw_request("10.80.80.80", req).await; + let res = if cfg!(feature = "v6-test") { + server.raw_request("fd00:1337::1337", req).await + } else { + server.raw_request("10.80.80.80", req).await + }; // addr::remote() filter only look at remote_addr from TCP socket. // HTTP headers are not considered. This also means that innernet @@ -696,12 +714,21 @@ mod tests { async fn test_unparseable_public_key() -> Result<(), Error> { let server = test::Server::new()?; + let path = if cfg!(feature = "v6-test") { + format!("http://[{}]/v1/admin/peers", test::WG_MANAGE_PEER_IP) + } else { + format!("http://{}/v1/admin/peers", test::WG_MANAGE_PEER_IP) + }; let req = Request::builder() - .uri(format!("http://{}/v1/admin/peers", test::WG_MANAGE_PEER_IP)) + .uri(path) .header(shared::INNERNET_PUBKEY_HEADER, "!!!") .body(Body::empty()) .unwrap(); - let res = server.raw_request("10.80.80.80", req).await; + let res = if cfg!(feature = "v6-test") { + server.raw_request("fd00:1337::1337", req).await + } else { + server.raw_request("10.80.80.80", req).await + }; // addr::remote() filter only look at remote_addr from TCP socket. // HTTP headers are not considered. This also means that innernet diff --git a/server/src/test.rs b/server/src/test.rs index 7d90e03..4cb611b 100644 --- a/server/src/test.rs +++ b/server/src/test.rs @@ -14,21 +14,47 @@ use std::{collections::HashMap, net::SocketAddr, path::PathBuf, sync::Arc}; use tempfile::TempDir; use wgctrl::{Backend, InterfaceName, Key, KeyPair}; -pub const ROOT_CIDR: &str = "10.80.0.0/15"; -pub const SERVER_CIDR: &str = "10.80.0.1/32"; -pub const ADMIN_CIDR: &str = "10.80.1.0/24"; -pub const DEVELOPER_CIDR: &str = "10.80.64.0/24"; -pub const USER_CIDR: &str = "10.80.128.0/17"; -pub const EXPERIMENTAL_CIDR: &str = "10.81.0.0/16"; -pub const EXPERIMENTAL_SUBCIDR: &str = "10.81.0.0/17"; +#[cfg(not(feature = "v6-test"))] +mod v4 { + pub const ROOT_CIDR: &str = "10.80.0.0/15"; + pub const SERVER_CIDR: &str = "10.80.0.1/32"; + pub const ADMIN_CIDR: &str = "10.80.1.0/24"; + pub const DEVELOPER_CIDR: &str = "10.80.64.0/24"; + pub const USER_CIDR: &str = "10.80.128.0/17"; + pub const EXPERIMENTAL_CIDR: &str = "10.81.0.0/16"; + pub const EXPERIMENTAL_SUBCIDR: &str = "10.81.0.0/17"; -pub const ADMIN_PEER_IP: &str = "10.80.1.1"; -pub const WG_MANAGE_PEER_IP: &str = "10.80.1.1"; -pub const DEVELOPER1_PEER_IP: &str = "10.80.64.2"; -pub const DEVELOPER2_PEER_IP: &str = "10.80.64.3"; -pub const USER1_PEER_IP: &str = "10.80.128.2"; -pub const USER2_PEER_IP: &str = "10.80.129.2"; -pub const EXPERIMENT_SUBCIDR_PEER_IP: &str = "10.81.0.1"; + pub const ADMIN_PEER_IP: &str = "10.80.1.1"; + pub const WG_MANAGE_PEER_IP: &str = ADMIN_PEER_IP; + pub const DEVELOPER1_PEER_IP: &str = "10.80.64.2"; + pub const DEVELOPER2_PEER_IP: &str = "10.80.64.3"; + pub const USER1_PEER_IP: &str = "10.80.128.2"; + pub const USER2_PEER_IP: &str = "10.80.129.2"; + pub const EXPERIMENT_SUBCIDR_PEER_IP: &str = "10.81.0.1"; +} +#[cfg(not(feature = "v6-test"))] +pub use v4::*; + +#[cfg(feature = "v6-test")] +mod v6 { + pub const ROOT_CIDR: &str = "fd00:1337::/64"; + pub const SERVER_CIDR: &str = "fd00:1337::1/128"; + pub const ADMIN_CIDR: &str = "fd00:1337::1:0:0:0/80"; + pub const DEVELOPER_CIDR: &str = "fd00:1337::2:0:0:0/80"; + pub const USER_CIDR: &str = "fd00:1337::3:0:0:0/80"; + pub const EXPERIMENTAL_CIDR: &str = "fd00:1337::4:0:0:0/80"; + pub const EXPERIMENTAL_SUBCIDR: &str = "fd00:1337::4:0:0:0/81"; + + pub const ADMIN_PEER_IP: &str = "fd00:1337::1:0:0:1"; + pub const WG_MANAGE_PEER_IP: &str = ADMIN_PEER_IP; + pub const DEVELOPER1_PEER_IP: &str = "fd00:1337::2:0:0:1"; + pub const DEVELOPER2_PEER_IP: &str = "fd00:1337::2:0:0:2"; + pub const USER1_PEER_IP: &str = "fd00:1337::3:0:0:1"; + pub const USER2_PEER_IP: &str = "fd00:1337::3:0:0:2"; + pub const EXPERIMENT_SUBCIDR_PEER_IP: &str = "fd00:1337::4:0:0:1"; +} +#[cfg(feature = "v6-test")] +pub use v6::*; pub const ROOT_CIDR_ID: i64 = 1; pub const INFRA_CIDR_ID: i64 = 2; @@ -160,8 +186,13 @@ impl Server { } fn base_request_builder(&self, verb: &str, path: &str) -> http::request::Builder { + let path = if cfg!(feature = "v6-test") { + format!("http://[{}]{}", WG_MANAGE_PEER_IP, path) + } else { + format!("http://{}{}", WG_MANAGE_PEER_IP, path) + }; Request::builder() - .uri(format!("http://{}{}", WG_MANAGE_PEER_IP, path)) + .uri(path) .method(verb) .header( shared::INNERNET_PUBKEY_HEADER,