mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
wip: debugging tor
This commit is contained in:
@@ -40,6 +40,8 @@ sudo chown 0:0 tmp/combined/lib/systemd/system/container-runtime.service
|
|||||||
sudo cp container-runtime-failure.service tmp/combined/lib/systemd/system/container-runtime-failure.service
|
sudo cp container-runtime-failure.service tmp/combined/lib/systemd/system/container-runtime-failure.service
|
||||||
sudo chown 0:0 tmp/combined/lib/systemd/system/container-runtime-failure.service
|
sudo chown 0:0 tmp/combined/lib/systemd/system/container-runtime-failure.service
|
||||||
sudo cp ../core/target/$ARCH-unknown-linux-musl/release/containerbox tmp/combined/usr/bin/start-container
|
sudo cp ../core/target/$ARCH-unknown-linux-musl/release/containerbox tmp/combined/usr/bin/start-container
|
||||||
|
echo -e '#!/bin/bash\nexec start-container $@' | sudo tee tmp/combined/usr/bin/start-cli # TODO: remove
|
||||||
|
sudo chmod +x tmp/combined/usr/bin/start-cli
|
||||||
sudo chown 0:0 tmp/combined/usr/bin/start-container
|
sudo chown 0:0 tmp/combined/usr/bin/start-container
|
||||||
echo container-runtime | sha256sum | head -c 32 | cat - <(echo) | sudo tee tmp/combined/etc/machine-id
|
echo container-runtime | sha256sum | head -c 32 | cat - <(echo) | sudo tee tmp/combined/etc/machine-id
|
||||||
cat deb-install.sh | sudo systemd-nspawn --console=pipe -D tmp/combined $QEMU /bin/bash
|
cat deb-install.sh | sudo systemd-nspawn --console=pipe -D tmp/combined $QEMU /bin/bash
|
||||||
|
|||||||
738
core/Cargo.lock
generated
738
core/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,7 @@ if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
|
|||||||
RUSTFLAGS="--cfg tokio_unstable"
|
RUSTFLAGS="--cfg tokio_unstable"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "RUSTFLAGS=$RUSTFLAGS" -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$(pwd)":/home/rust/src -w /home/rust/src -P messense/rust-musl-cross:$ARCH-musl'
|
source ./core/builder-alias.sh
|
||||||
|
|
||||||
echo "FEATURES=\"$FEATURES\""
|
echo "FEATURES=\"$FEATURES\""
|
||||||
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
|
|||||||
RUSTFLAGS="--cfg tokio_unstable"
|
RUSTFLAGS="--cfg tokio_unstable"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "RUSTFLAGS=$RUSTFLAGS" -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$(pwd)":/home/rust/src -w /home/rust/src -P messense/rust-musl-cross:$ARCH-musl'
|
source ./core/builder-alias.sh
|
||||||
|
|
||||||
echo "FEATURES=\"$FEATURES\""
|
echo "FEATURES=\"$FEATURES\""
|
||||||
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
|
|||||||
RUSTFLAGS="--cfg tokio_unstable"
|
RUSTFLAGS="--cfg tokio_unstable"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "RUSTFLAGS=$RUSTFLAGS" -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$(pwd)":/home/rust/src -w /home/rust/src -P messense/rust-musl-cross:$ARCH-musl'
|
source ./core/builder-alias.sh
|
||||||
|
|
||||||
echo "FEATURES=\"$FEATURES\""
|
echo "FEATURES=\"$FEATURES\""
|
||||||
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
|
|||||||
RUSTFLAGS="--cfg tokio_unstable"
|
RUSTFLAGS="--cfg tokio_unstable"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "RUSTFLAGS=$RUSTFLAGS" -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$(pwd)":/home/rust/src -w /home/rust/src -P messense/rust-musl-cross:$ARCH-musl'
|
source ./core/builder-alias.sh
|
||||||
|
|
||||||
echo "FEATURES=\"$FEATURES\""
|
echo "FEATURES=\"$FEATURES\""
|
||||||
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ if [[ "${ENVIRONMENT}" =~ (^|-)unstable($|-) ]]; then
|
|||||||
RUSTFLAGS="--cfg tokio_unstable"
|
RUSTFLAGS="--cfg tokio_unstable"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "RUSTFLAGS=$RUSTFLAGS" -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$(pwd)":/home/rust/src -w /home/rust/src -P messense/rust-musl-cross:$ARCH-musl'
|
source ./core/builder-alias.sh
|
||||||
|
|
||||||
echo "FEATURES=\"$FEATURES\""
|
echo "FEATURES=\"$FEATURES\""
|
||||||
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
echo "RUSTFLAGS=\"$RUSTFLAGS\""
|
||||||
|
|||||||
3
core/builder-alias.sh
Normal file
3
core/builder-alias.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
alias 'rust-musl-builder'='docker run $USE_TTY --rm -e "RUSTFLAGS=$RUSTFLAGS" -e SCCACHE_GHA_ENABLED -e SCCACHE_GHA_VERSION -v "$HOME/.cargo/registry":/root/.cargo/registry -v "$HOME/.cargo/git":/root/.cargo/git -v "$HOME/.cache/sccache":/root/.cache/sccache -v "$(pwd)":/home/rust/src -w /home/rust/src -P start9/rust-musl-cross:$ARCH-musl'
|
||||||
@@ -6,7 +6,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
arti-client = { version = "0.33", features = ["full"] }
|
arti-client = { version = "0.33", default-features = false, git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
axum = "0.8.4"
|
axum = "0.8.4"
|
||||||
base64 = "0.22.1"
|
base64 = "0.22.1"
|
||||||
color-eyre = "0.6.2"
|
color-eyre = "0.6.2"
|
||||||
|
|||||||
@@ -64,7 +64,9 @@ arti-client = { version = "0.33", features = [
|
|||||||
"static",
|
"static",
|
||||||
"tokio",
|
"tokio",
|
||||||
"ephemeral-keystore",
|
"ephemeral-keystore",
|
||||||
], default-features = false }
|
"onion-service-client",
|
||||||
|
"onion-service-service",
|
||||||
|
], default-features = false, git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
aes = { version = "0.7.5", features = ["ctr"] }
|
aes = { version = "0.7.5", features = ["ctr"] }
|
||||||
async-acme = { version = "0.6.0", git = "https://github.com/dr-bonez/async-acme.git", features = [
|
async-acme = { version = "0.6.0", git = "https://github.com/dr-bonez/async-acme.git", features = [
|
||||||
"use_rustls",
|
"use_rustls",
|
||||||
@@ -195,7 +197,7 @@ rpassword = "7.2.0"
|
|||||||
rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "master" }
|
rpc-toolkit = { git = "https://github.com/Start9Labs/rpc-toolkit.git", branch = "master" }
|
||||||
rust-argon2 = "2.0.0"
|
rust-argon2 = "2.0.0"
|
||||||
rustyline-async = "0.4.1"
|
rustyline-async = "0.4.1"
|
||||||
safelog = "0.4.8"
|
safelog = { version = "0.4.8", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
semver = { version = "1.0.20", features = ["serde"] }
|
semver = { version = "1.0.20", features = ["serde"] }
|
||||||
serde = { version = "1.0", features = ["derive", "rc"] }
|
serde = { version = "1.0", features = ["derive", "rc"] }
|
||||||
serde_cbor = { package = "ciborium", version = "0.2.1" }
|
serde_cbor = { package = "ciborium", version = "0.2.1" }
|
||||||
@@ -227,13 +229,22 @@ tokio-stream = { version = "0.1.14", features = ["io-util", "sync", "net"] }
|
|||||||
tokio-tar = { git = "https://github.com/dr-bonez/tokio-tar.git" }
|
tokio-tar = { git = "https://github.com/dr-bonez/tokio-tar.git" }
|
||||||
tokio-tungstenite = { version = "0.26.2", features = ["native-tls", "url"] }
|
tokio-tungstenite = { version = "0.26.2", features = ["native-tls", "url"] }
|
||||||
tokio-util = { version = "0.7.9", features = ["io"] }
|
tokio-util = { version = "0.7.9", features = ["io"] }
|
||||||
tor-cell = { version = "0.33" }
|
tor-cell = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
tor-hscrypto = { version = "0.33", features = ["full"] }
|
tor-hscrypto = { version = "0.33", features = [
|
||||||
tor-hsservice = { version = "0.33" }
|
"full",
|
||||||
tor-keymgr = { version = "0.33", features = ["ephemeral-keystore"] }
|
], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
tor-llcrypto = { version = "0.33", features = ["full"] }
|
tor-hsservice = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
tor-proto = { version = "0.33" }
|
tor-keymgr = { version = "0.33", features = [
|
||||||
tor-rtcompat = { version = "0.33", features = ["tokio", "rustls"] }
|
"ephemeral-keystore",
|
||||||
|
], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
|
tor-llcrypto = { version = "0.33", features = [
|
||||||
|
"full",
|
||||||
|
], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
|
tor-proto = { version = "0.33", git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
|
tor-rtcompat = { version = "0.33", features = [
|
||||||
|
"tokio",
|
||||||
|
"rustls",
|
||||||
|
], git = "https://github.com/Start9Labs/arti.git", branch = "patch/disable-exit" }
|
||||||
tower-service = "0.3.3"
|
tower-service = "0.3.3"
|
||||||
tracing = "0.1.39"
|
tracing = "0.1.39"
|
||||||
tracing-error = "0.2.0"
|
tracing-error = "0.2.0"
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use models::{ActionId, PackageId};
|
|||||||
use reqwest::{Client, Proxy};
|
use reqwest::{Client, Proxy};
|
||||||
use rpc_toolkit::yajrc::RpcError;
|
use rpc_toolkit::yajrc::RpcError;
|
||||||
use rpc_toolkit::{CallRemote, Context, Empty};
|
use rpc_toolkit::{CallRemote, Context, Empty};
|
||||||
use tokio::sync::{Mutex, RwLock, broadcast, oneshot, watch};
|
use tokio::sync::{RwLock, broadcast, oneshot, watch};
|
||||||
use tokio::time::Instant;
|
use tokio::time::Instant;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ use crate::db::model::package::TaskSeverity;
|
|||||||
use crate::disk::OsPartitionInfo;
|
use crate::disk::OsPartitionInfo;
|
||||||
use crate::init::{InitResult, check_time_is_synchronized};
|
use crate::init::{InitResult, check_time_is_synchronized};
|
||||||
use crate::install::PKG_ARCHIVE_DIR;
|
use crate::install::PKG_ARCHIVE_DIR;
|
||||||
use crate::lxc::{ContainerId, LxcContainer, LxcManager};
|
use crate::lxc::LxcManager;
|
||||||
use crate::net::net_controller::{NetController, NetService};
|
use crate::net::net_controller::{NetController, NetService};
|
||||||
use crate::net::utils::{find_eth_iface, find_wifi_iface};
|
use crate::net::utils::{find_eth_iface, find_wifi_iface};
|
||||||
use crate::net::web_server::{UpgradableListener, WebServerAcceptorSetter};
|
use crate::net::web_server::{UpgradableListener, WebServerAcceptorSetter};
|
||||||
@@ -74,12 +74,6 @@ pub struct RpcContextSeed {
|
|||||||
pub client: Client,
|
pub client: Client,
|
||||||
pub start_time: Instant,
|
pub start_time: Instant,
|
||||||
pub crons: SyncMutex<BTreeMap<Guid, NonDetachingJoinHandle<()>>>,
|
pub crons: SyncMutex<BTreeMap<Guid, NonDetachingJoinHandle<()>>>,
|
||||||
// #[cfg(feature = "dev")]
|
|
||||||
pub dev: Dev,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct Dev {
|
|
||||||
pub lxc: Mutex<BTreeMap<ContainerId, LxcContainer>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Hardware {
|
pub struct Hardware {
|
||||||
@@ -262,10 +256,6 @@ impl RpcContext {
|
|||||||
.with_kind(crate::ErrorKind::ParseUrl)?,
|
.with_kind(crate::ErrorKind::ParseUrl)?,
|
||||||
start_time: Instant::now(),
|
start_time: Instant::now(),
|
||||||
crons,
|
crons,
|
||||||
// #[cfg(feature = "dev")]
|
|
||||||
dev: Dev {
|
|
||||||
lxc: Mutex::new(BTreeMap::new()),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = Self(seed.clone());
|
let res = Self(seed.clone());
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ use crate::account::AccountInfo;
|
|||||||
use crate::db::model::package::AllPackageData;
|
use crate::db::model::package::AllPackageData;
|
||||||
use crate::net::acme::AcmeProvider;
|
use crate::net::acme::AcmeProvider;
|
||||||
use crate::net::forward::START9_BRIDGE_IFACE;
|
use crate::net::forward::START9_BRIDGE_IFACE;
|
||||||
use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, NetInfo};
|
|
||||||
use crate::net::host::Host;
|
use crate::net::host::Host;
|
||||||
|
use crate::net::host::binding::{AddSslOptions, BindInfo, BindOptions, NetInfo};
|
||||||
use crate::net::utils::ipv6_is_local;
|
use crate::net::utils::ipv6_is_local;
|
||||||
use crate::net::vhost::AlpnInfo;
|
use crate::net::vhost::AlpnInfo;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|||||||
@@ -10,34 +10,34 @@ use futures::future::BoxFuture;
|
|||||||
use futures::{FutureExt, StreamExt, TryStreamExt};
|
use futures::{FutureExt, StreamExt, TryStreamExt};
|
||||||
use helpers::NonDetachingJoinHandle;
|
use helpers::NonDetachingJoinHandle;
|
||||||
use hickory_client::client::Client;
|
use hickory_client::client::Client;
|
||||||
|
use hickory_client::proto::DnsHandle;
|
||||||
use hickory_client::proto::runtime::TokioRuntimeProvider;
|
use hickory_client::proto::runtime::TokioRuntimeProvider;
|
||||||
use hickory_client::proto::tcp::TcpClientStream;
|
use hickory_client::proto::tcp::TcpClientStream;
|
||||||
use hickory_client::proto::udp::UdpClientStream;
|
use hickory_client::proto::udp::UdpClientStream;
|
||||||
use hickory_client::proto::xfer::{DnsExchangeBackground, DnsRequestOptions};
|
use hickory_client::proto::xfer::{DnsExchangeBackground, DnsRequestOptions};
|
||||||
use hickory_client::proto::DnsHandle;
|
use hickory_server::ServerFuture;
|
||||||
use hickory_server::authority::MessageResponseBuilder;
|
use hickory_server::authority::MessageResponseBuilder;
|
||||||
use hickory_server::proto::op::{Header, ResponseCode};
|
use hickory_server::proto::op::{Header, ResponseCode};
|
||||||
use hickory_server::proto::rr::{Name, Record, RecordType};
|
use hickory_server::proto::rr::{Name, Record, RecordType};
|
||||||
use hickory_server::server::{Request, RequestHandler, ResponseHandler, ResponseInfo};
|
use hickory_server::server::{Request, RequestHandler, ResponseHandler, ResponseInfo};
|
||||||
use hickory_server::ServerFuture;
|
|
||||||
use imbl::OrdMap;
|
use imbl::OrdMap;
|
||||||
use imbl_value::InternedString;
|
use imbl_value::InternedString;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use models::{GatewayId, OptionExt, PackageId};
|
use models::{GatewayId, OptionExt, PackageId};
|
||||||
use rpc_toolkit::{
|
use rpc_toolkit::{
|
||||||
from_fn_async, from_fn_blocking, Context, HandlerArgs, HandlerExt, ParentHandler,
|
Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async, from_fn_blocking,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::net::{TcpListener, UdpSocket};
|
use tokio::net::{TcpListener, UdpSocket};
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::context::RpcContext;
|
use crate::context::RpcContext;
|
||||||
use crate::db::model::public::NetworkInterfaceInfo;
|
|
||||||
use crate::db::model::Database;
|
use crate::db::model::Database;
|
||||||
|
use crate::db::model::public::NetworkInterfaceInfo;
|
||||||
use crate::net::gateway::NetworkInterfaceWatcher;
|
use crate::net::gateway::NetworkInterfaceWatcher;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::util::io::file_string_stream;
|
use crate::util::io::file_string_stream;
|
||||||
use crate::util::serde::{display_serializable, HandlerExtSerde};
|
use crate::util::serde::{HandlerExtSerde, display_serializable};
|
||||||
use crate::util::sync::{SyncRwLock, Watch};
|
use crate::util::sync::{SyncRwLock, Watch};
|
||||||
|
|
||||||
pub fn dns_api<C: Context>() -> ParentHandler<C> {
|
pub fn dns_api<C: Context>() -> ParentHandler<C> {
|
||||||
@@ -349,11 +349,7 @@ impl RequestHandler for Resolver {
|
|||||||
Header::response_from_request(request.header()),
|
Header::response_from_request(request.header()),
|
||||||
&ip.into_iter()
|
&ip.into_iter()
|
||||||
.filter_map(|a| {
|
.filter_map(|a| {
|
||||||
if let IpAddr::V4(a) = a {
|
if let IpAddr::V4(a) = a { Some(a) } else { None }
|
||||||
Some(a)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.map(|ip| {
|
.map(|ip| {
|
||||||
Record::from_rdata(
|
Record::from_rdata(
|
||||||
@@ -377,11 +373,7 @@ impl RequestHandler for Resolver {
|
|||||||
Header::response_from_request(request.header()),
|
Header::response_from_request(request.header()),
|
||||||
&ip.into_iter()
|
&ip.into_iter()
|
||||||
.filter_map(|a| {
|
.filter_map(|a| {
|
||||||
if let IpAddr::V6(a) = a {
|
if let IpAddr::V6(a) = a { Some(a) } else { None }
|
||||||
Some(a)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.map(|ip| {
|
.map(|ip| {
|
||||||
Record::from_rdata(
|
Record::from_rdata(
|
||||||
@@ -415,9 +407,7 @@ impl RequestHandler for Resolver {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let query = query.original().clone();
|
let query = query.original().clone();
|
||||||
let mut streams = self
|
let mut streams = self.client.lookup(query, DnsRequestOptions::default());
|
||||||
.client
|
|
||||||
.lookup(query, DnsRequestOptions::default());
|
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
for stream in streams.iter_mut() {
|
for stream in streams.iter_mut() {
|
||||||
match tokio::time::timeout(Duration::from_secs(5), stream.next()).await {
|
match tokio::time::timeout(Duration::from_secs(5), stream.next()).await {
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use itertools::Itertools;
|
|||||||
use models::GatewayId;
|
use models::GatewayId;
|
||||||
use nix::net::if_::if_nametoindex;
|
use nix::net::if_::if_nametoindex;
|
||||||
use patch_db::json_ptr::JsonPointer;
|
use patch_db::json_ptr::JsonPointer;
|
||||||
use rpc_toolkit::{from_fn_async, Context, HandlerArgs, HandlerExt, ParentHandler};
|
use rpc_toolkit::{Context, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::io::{AsyncBufReadExt, BufReader};
|
use tokio::io::{AsyncBufReadExt, BufReader};
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
@@ -24,25 +24,25 @@ use tokio::process::Command;
|
|||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
use zbus::proxy::{PropertyChanged, PropertyStream, SignalStream};
|
use zbus::proxy::{PropertyChanged, PropertyStream, SignalStream};
|
||||||
use zbus::zvariant::{
|
use zbus::zvariant::{
|
||||||
DeserializeDict, Dict, OwnedObjectPath, OwnedValue, Type as ZType, Value as ZValue,
|
DICT_ENTRY_SIG_END_STR, DeserializeDict, Dict, OwnedObjectPath, OwnedValue, Type as ZType,
|
||||||
DICT_ENTRY_SIG_END_STR,
|
Value as ZValue,
|
||||||
};
|
};
|
||||||
use zbus::{proxy, Connection};
|
use zbus::{Connection, proxy};
|
||||||
|
|
||||||
use crate::context::{CliContext, RpcContext};
|
use crate::context::{CliContext, RpcContext};
|
||||||
use crate::db::model::public::{IpInfo, NetworkInterfaceInfo, NetworkInterfaceType};
|
|
||||||
use crate::db::model::Database;
|
use crate::db::model::Database;
|
||||||
|
use crate::db::model::public::{IpInfo, NetworkInterfaceInfo, NetworkInterfaceType};
|
||||||
use crate::net::forward::START9_BRIDGE_IFACE;
|
use crate::net::forward::START9_BRIDGE_IFACE;
|
||||||
use crate::net::gateway::device::DeviceProxy;
|
use crate::net::gateway::device::DeviceProxy;
|
||||||
use crate::net::utils::ipv6_is_link_local;
|
use crate::net::utils::ipv6_is_link_local;
|
||||||
use crate::net::web_server::Accept;
|
use crate::net::web_server::Accept;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use crate::util::Invoke;
|
||||||
use crate::util::collections::OrdMapIterMut;
|
use crate::util::collections::OrdMapIterMut;
|
||||||
use crate::util::future::Until;
|
use crate::util::future::Until;
|
||||||
use crate::util::io::open_file;
|
use crate::util::io::open_file;
|
||||||
use crate::util::serde::{display_serializable, HandlerExtSerde};
|
use crate::util::serde::{HandlerExtSerde, display_serializable};
|
||||||
use crate::util::sync::{SyncMutex, Watch};
|
use crate::util::sync::{SyncMutex, Watch};
|
||||||
use crate::util::Invoke;
|
|
||||||
|
|
||||||
pub fn gateway_api<C: Context>() -> ParentHandler<C> {
|
pub fn gateway_api<C: Context>() -> ParentHandler<C> {
|
||||||
ParentHandler::new()
|
ParentHandler::new()
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
use std::net::Ipv4Addr;
|
||||||
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use imbl_value::InternedString;
|
use imbl_value::InternedString;
|
||||||
use models::GatewayId;
|
use models::GatewayId;
|
||||||
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
|
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
|
|
||||||
use crate::context::{CliContext, RpcContext};
|
use crate::context::{CliContext, RpcContext};
|
||||||
use crate::db::model::DatabaseModel;
|
use crate::db::model::DatabaseModel;
|
||||||
use crate::net::acme::AcmeProvider;
|
use crate::net::acme::AcmeProvider;
|
||||||
use crate::net::host::{all_hosts, HostApiKind};
|
use crate::net::host::{HostApiKind, all_hosts};
|
||||||
use crate::net::tor::OnionAddress;
|
use crate::net::tor::OnionAddress;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::util::serde::{display_serializable, HandlerExtSerde};
|
use crate::util::serde::{HandlerExtSerde, display_serializable};
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
#[serde(rename_all = "kebab-case")]
|
#[serde(rename_all = "kebab-case")]
|
||||||
@@ -35,10 +36,10 @@ pub struct PublicDomainConfig {
|
|||||||
pub acme: Option<AcmeProvider>,
|
pub acme: Option<AcmeProvider>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_duplicates(db: &DatabaseModel) -> Result<(), Error> {
|
fn handle_duplicates(db: &mut DatabaseModel) -> Result<(), Error> {
|
||||||
let mut onions = BTreeSet::<OnionAddress>::new();
|
let mut onions = BTreeSet::<OnionAddress>::new();
|
||||||
let mut domains = BTreeSet::<InternedString>::new();
|
let mut domains = BTreeSet::<InternedString>::new();
|
||||||
let mut check_onion = |onion: OnionAddress| {
|
let check_onion = |onions: &mut BTreeSet<OnionAddress>, onion: OnionAddress| {
|
||||||
if onions.contains(&onion) {
|
if onions.contains(&onion) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!("onion address {onion} is already in use"),
|
eyre!("onion address {onion} is already in use"),
|
||||||
@@ -48,7 +49,7 @@ fn check_duplicates(db: &DatabaseModel) -> Result<(), Error> {
|
|||||||
onions.insert(onion);
|
onions.insert(onion);
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
let mut check_domain = |domain: InternedString| {
|
let check_domain = |domains: &mut BTreeSet<InternedString>, domain: InternedString| {
|
||||||
if domains.contains(&domain) {
|
if domains.contains(&domain) {
|
||||||
return Err(Error::new(
|
return Err(Error::new(
|
||||||
eyre!("domain {domain} is already in use"),
|
eyre!("domain {domain} is already in use"),
|
||||||
@@ -58,23 +59,47 @@ fn check_duplicates(db: &DatabaseModel) -> Result<(), Error> {
|
|||||||
domains.insert(domain);
|
domains.insert(domain);
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
|
let mut not_in_use = Vec::new();
|
||||||
for host in all_hosts(db) {
|
for host in all_hosts(db) {
|
||||||
let host = host?;
|
let host = host?;
|
||||||
|
let in_use = host.as_bindings().de()?.values().any(|v| v.enabled);
|
||||||
|
if !in_use {
|
||||||
|
not_in_use.push(host);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
for onion in host.as_onions().de()? {
|
for onion in host.as_onions().de()? {
|
||||||
check_onion(onion)?;
|
check_onion(&mut onions, onion)?;
|
||||||
}
|
}
|
||||||
for domain in host.as_public_domains().keys()? {
|
for domain in host.as_public_domains().keys()? {
|
||||||
check_domain(domain)?;
|
check_domain(&mut domains, domain)?;
|
||||||
}
|
}
|
||||||
for domain in host.as_private_domains().de()? {
|
for domain in host.as_private_domains().de()? {
|
||||||
check_domain(domain)?;
|
check_domain(&mut domains, domain)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for host in not_in_use {
|
||||||
|
host.as_onions_mut()
|
||||||
|
.mutate(|o| Ok(o.retain(|o| !onions.contains(o))))?;
|
||||||
|
host.as_public_domains_mut()
|
||||||
|
.mutate(|d| Ok(d.retain(|d, _| !domains.contains(d))))?;
|
||||||
|
host.as_private_domains_mut()
|
||||||
|
.mutate(|d| Ok(d.retain(|d| !domains.contains(d))))?;
|
||||||
|
|
||||||
|
for onion in host.as_onions().de()? {
|
||||||
|
check_onion(&mut onions, onion)?;
|
||||||
|
}
|
||||||
|
for domain in host.as_public_domains().keys()? {
|
||||||
|
check_domain(&mut domains, domain)?;
|
||||||
|
}
|
||||||
|
for domain in host.as_private_domains().de()? {
|
||||||
|
check_domain(&mut domains, domain)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn address_api<C: Context, Kind: HostApiKind>(
|
pub fn address_api<C: Context, Kind: HostApiKind>()
|
||||||
) -> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
|
-> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
|
||||||
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
|
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
|
||||||
.subcommand(
|
.subcommand(
|
||||||
"domain",
|
"domain",
|
||||||
@@ -209,12 +234,12 @@ pub struct AddPublicDomainParams {
|
|||||||
pub async fn add_public_domain<Kind: HostApiKind>(
|
pub async fn add_public_domain<Kind: HostApiKind>(
|
||||||
ctx: RpcContext,
|
ctx: RpcContext,
|
||||||
AddPublicDomainParams {
|
AddPublicDomainParams {
|
||||||
ref fqdn,
|
fqdn,
|
||||||
acme,
|
acme,
|
||||||
gateway,
|
gateway,
|
||||||
}: AddPublicDomainParams,
|
}: AddPublicDomainParams,
|
||||||
inheritance: Kind::Inheritance,
|
inheritance: Kind::Inheritance,
|
||||||
) -> Result<(), Error> {
|
) -> Result<Option<Ipv4Addr>, Error> {
|
||||||
ctx.db
|
ctx.db
|
||||||
.mutate(|db| {
|
.mutate(|db| {
|
||||||
if let Some(acme) = &acme {
|
if let Some(acme) = &acme {
|
||||||
@@ -231,31 +256,35 @@ pub async fn add_public_domain<Kind: HostApiKind>(
|
|||||||
|
|
||||||
Kind::host_for(&inheritance, db)?
|
Kind::host_for(&inheritance, db)?
|
||||||
.as_public_domains_mut()
|
.as_public_domains_mut()
|
||||||
.insert(fqdn, &PublicDomainConfig { acme, gateway })?;
|
.insert(&fqdn, &PublicDomainConfig { acme, gateway })?;
|
||||||
check_duplicates(db)
|
handle_duplicates(db)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.result?;
|
.result?;
|
||||||
Kind::sync_host(&ctx, inheritance).await?;
|
Kind::sync_host(&ctx, inheritance).await?;
|
||||||
|
|
||||||
Ok(())
|
tokio::task::spawn_blocking(|| {
|
||||||
|
crate::net::dns::query_dns(ctx, crate::net::dns::QueryDnsParams { fqdn })
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.with_kind(ErrorKind::Unknown)?
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Parser)]
|
#[derive(Deserialize, Serialize, Parser)]
|
||||||
pub struct RemoveDomainParams {
|
pub struct RemoveDomainParams {
|
||||||
pub domain: InternedString,
|
pub fqdn: InternedString,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn remove_public_domain<Kind: HostApiKind>(
|
pub async fn remove_public_domain<Kind: HostApiKind>(
|
||||||
ctx: RpcContext,
|
ctx: RpcContext,
|
||||||
RemoveDomainParams { domain }: RemoveDomainParams,
|
RemoveDomainParams { fqdn }: RemoveDomainParams,
|
||||||
inheritance: Kind::Inheritance,
|
inheritance: Kind::Inheritance,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
ctx.db
|
ctx.db
|
||||||
.mutate(|db| {
|
.mutate(|db| {
|
||||||
Kind::host_for(&inheritance, db)?
|
Kind::host_for(&inheritance, db)?
|
||||||
.as_public_domains_mut()
|
.as_public_domains_mut()
|
||||||
.remove(&domain)
|
.remove(&fqdn)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.result?;
|
.result?;
|
||||||
@@ -279,7 +308,7 @@ pub async fn add_private_domain<Kind: HostApiKind>(
|
|||||||
Kind::host_for(&inheritance, db)?
|
Kind::host_for(&inheritance, db)?
|
||||||
.as_private_domains_mut()
|
.as_private_domains_mut()
|
||||||
.mutate(|d| Ok(d.insert(fqdn)))?;
|
.mutate(|d| Ok(d.insert(fqdn)))?;
|
||||||
check_duplicates(db)
|
handle_duplicates(db)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.result?;
|
.result?;
|
||||||
@@ -290,7 +319,7 @@ pub async fn add_private_domain<Kind: HostApiKind>(
|
|||||||
|
|
||||||
pub async fn remove_private_domain<Kind: HostApiKind>(
|
pub async fn remove_private_domain<Kind: HostApiKind>(
|
||||||
ctx: RpcContext,
|
ctx: RpcContext,
|
||||||
RemoveDomainParams { domain }: RemoveDomainParams,
|
RemoveDomainParams { fqdn: domain }: RemoveDomainParams,
|
||||||
inheritance: Kind::Inheritance,
|
inheritance: Kind::Inheritance,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
ctx.db
|
ctx.db
|
||||||
@@ -332,7 +361,7 @@ pub async fn add_onion<Kind: HostApiKind>(
|
|||||||
Kind::host_for(&inheritance, db)?
|
Kind::host_for(&inheritance, db)?
|
||||||
.as_onions_mut()
|
.as_onions_mut()
|
||||||
.mutate(|a| Ok(a.insert(onion)))?;
|
.mutate(|a| Ok(a.insert(onion)))?;
|
||||||
check_duplicates(db)
|
handle_duplicates(db)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.result?;
|
.result?;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use std::collections::{BTreeMap, BTreeSet};
|
use std::collections::{BTreeMap, BTreeSet};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use clap::builder::ValueParserFactory;
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
|
use clap::builder::ValueParserFactory;
|
||||||
use imbl::OrdSet;
|
use imbl::OrdSet;
|
||||||
use models::{FromStrParser, GatewayId, HostId};
|
use models::{FromStrParser, GatewayId, HostId};
|
||||||
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerArgs, HandlerExt, ParentHandler};
|
use rpc_toolkit::{Context, Empty, HandlerArgs, HandlerExt, ParentHandler, from_fn_async};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ use crate::net::gateway::InterfaceFilter;
|
|||||||
use crate::net::host::HostApiKind;
|
use crate::net::host::HostApiKind;
|
||||||
use crate::net::vhost::AlpnInfo;
|
use crate::net::vhost::AlpnInfo;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::util::serde::{display_serializable, HandlerExtSerde};
|
use crate::util::serde::{HandlerExtSerde, display_serializable};
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)]
|
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, TS)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
@@ -169,8 +169,8 @@ pub struct AddSslOptions {
|
|||||||
pub alpn: Option<AlpnInfo>,
|
pub alpn: Option<AlpnInfo>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn binding<C: Context, Kind: HostApiKind>(
|
pub fn binding<C: Context, Kind: HostApiKind>()
|
||||||
) -> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
|
-> ParentHandler<C, Kind::Params, Kind::InheritedParams> {
|
||||||
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
|
ParentHandler::<C, Kind::Params, Kind::InheritedParams>::new()
|
||||||
.subcommand(
|
.subcommand(
|
||||||
"list",
|
"list",
|
||||||
|
|||||||
@@ -127,14 +127,16 @@ pub fn host_for<'a>(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn all_hosts(db: &DatabaseModel) -> impl Iterator<Item = Result<&Model<Host>, Error>> {
|
pub fn all_hosts(db: &mut DatabaseModel) -> impl Iterator<Item = Result<&mut Model<Host>, Error>> {
|
||||||
[Ok(db.as_public().as_server_info().as_network().as_host())]
|
use patch_db::DestructureMut;
|
||||||
|
let destructured = db.as_public_mut().destructure_mut();
|
||||||
|
[Ok(destructured.server_info.as_network_mut().as_host_mut())]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(
|
.chain(
|
||||||
[db.as_public().as_package_data().as_entries()]
|
[destructured.package_data.as_entries_mut()]
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten_ok()
|
.flatten_ok()
|
||||||
.map(|entry| entry.and_then(|(_, v)| v.as_hosts().as_entries()))
|
.map(|entry| entry.and_then(|(_, v)| v.as_hosts_mut().as_entries_mut()))
|
||||||
.flatten_ok()
|
.flatten_ok()
|
||||||
.map_ok(|(_, v)| v),
|
.map_ok(|(_, v)| v),
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::net::{Ipv4Addr, SocketAddr};
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use imbl::{vector, OrdMap};
|
use imbl::{OrdMap, vector};
|
||||||
use imbl_value::InternedString;
|
use imbl_value::InternedString;
|
||||||
use ipnet::IpNet;
|
use ipnet::IpNet;
|
||||||
use models::{HostId, OptionExt, PackageId};
|
use models::{HostId, OptionExt, PackageId};
|
||||||
@@ -11,8 +11,9 @@ use tokio::sync::Mutex;
|
|||||||
use tokio::task::JoinHandle;
|
use tokio::task::JoinHandle;
|
||||||
use tracing::instrument;
|
use tracing::instrument;
|
||||||
|
|
||||||
use crate::db::model::public::NetworkInterfaceInfo;
|
use crate::HOST_IP;
|
||||||
use crate::db::model::Database;
|
use crate::db::model::Database;
|
||||||
|
use crate::db::model::public::NetworkInterfaceInfo;
|
||||||
use crate::error::ErrorCollection;
|
use crate::error::ErrorCollection;
|
||||||
use crate::hostname::Hostname;
|
use crate::hostname::Hostname;
|
||||||
use crate::net::dns::DnsController;
|
use crate::net::dns::DnsController;
|
||||||
@@ -23,7 +24,7 @@ use crate::net::gateway::{
|
|||||||
};
|
};
|
||||||
use crate::net::host::address::HostAddress;
|
use crate::net::host::address::HostAddress;
|
||||||
use crate::net::host::binding::{AddSslOptions, BindId, BindOptions};
|
use crate::net::host::binding::{AddSslOptions, BindId, BindOptions};
|
||||||
use crate::net::host::{host_for, Host, Hosts};
|
use crate::net::host::{Host, Hosts, host_for};
|
||||||
use crate::net::service_interface::{HostnameInfo, IpHostname, OnionHostname};
|
use crate::net::service_interface::{HostnameInfo, IpHostname, OnionHostname};
|
||||||
use crate::net::tor::{OnionAddress, TorController, TorSecretKey};
|
use crate::net::tor::{OnionAddress, TorController, TorSecretKey};
|
||||||
use crate::net::utils::ipv6_is_local;
|
use crate::net::utils::ipv6_is_local;
|
||||||
@@ -31,7 +32,6 @@ use crate::net::vhost::{AlpnInfo, TargetInfo, VHostController};
|
|||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::service::effects::callbacks::ServiceCallbacks;
|
use crate::service::effects::callbacks::ServiceCallbacks;
|
||||||
use crate::util::serde::MaybeUtf8String;
|
use crate::util::serde::MaybeUtf8String;
|
||||||
use crate::HOST_IP;
|
|
||||||
|
|
||||||
pub struct NetController {
|
pub struct NetController {
|
||||||
pub(crate) db: TypedPatchDb<Database>,
|
pub(crate) db: TypedPatchDb<Database>,
|
||||||
|
|||||||
@@ -9,24 +9,19 @@ use arti_client::{TorClient, TorClientConfig};
|
|||||||
use base64::Engine;
|
use base64::Engine;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use color_eyre::eyre::eyre;
|
use color_eyre::eyre::eyre;
|
||||||
use futures::{FutureExt, Stream, StreamExt};
|
use futures::StreamExt;
|
||||||
use helpers::NonDetachingJoinHandle;
|
use helpers::NonDetachingJoinHandle;
|
||||||
use imbl_value::InternedString;
|
use imbl_value::InternedString;
|
||||||
use itertools::Itertools;
|
|
||||||
use lazy_static::lazy_static;
|
|
||||||
use regex::Regex;
|
|
||||||
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler};
|
use rpc_toolkit::{from_fn_async, Context, Empty, HandlerExt, ParentHandler};
|
||||||
use safelog::DisplayRedacted;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::io::AsyncWriteExt;
|
use tokio::io::AsyncWriteExt;
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio::sync::oneshot;
|
|
||||||
use tor_cell::relaycell::msg::Connected;
|
use tor_cell::relaycell::msg::Connected;
|
||||||
use tor_hscrypto::pk::{HsId, HsIdKeypair};
|
use tor_hscrypto::pk::{HsId, HsIdKeypair};
|
||||||
use tor_hsservice::status::State as ArtiOnionServiceState;
|
use tor_hsservice::status::State as ArtiOnionServiceState;
|
||||||
use tor_hsservice::{HsNickname, RendRequest, RunningOnionService};
|
use tor_hsservice::{HsNickname, RunningOnionService};
|
||||||
use tor_keymgr::config::ArtiKeystoreKind;
|
use tor_keymgr::config::ArtiKeystoreKind;
|
||||||
use tor_proto::stream::IncomingStreamRequest;
|
use tor_proto::client::stream::IncomingStreamRequest;
|
||||||
use tor_rtcompat::tokio::TokioRustlsRuntime;
|
use tor_rtcompat::tokio::TokioRustlsRuntime;
|
||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
|
|
||||||
@@ -39,13 +34,11 @@ use crate::util::serde::{
|
|||||||
};
|
};
|
||||||
use crate::util::sync::{SyncMutex, SyncRwLock};
|
use crate::util::sync::{SyncMutex, SyncRwLock};
|
||||||
|
|
||||||
const STARTING_HEALTH_TIMEOUT: u64 = 120; // 2min
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct OnionAddress(pub HsId);
|
pub struct OnionAddress(pub HsId);
|
||||||
impl std::fmt::Display for OnionAddress {
|
impl std::fmt::Display for OnionAddress {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.0.fmt_unredacted(f)
|
safelog::DisplayRedacted::fmt_unredacted(&self.0, f)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl FromStr for OnionAddress {
|
impl FromStr for OnionAddress {
|
||||||
@@ -201,7 +194,7 @@ impl std::fmt::Debug for OnionStore {
|
|||||||
impl<'a> std::fmt::Debug for OnionStoreMap<'a> {
|
impl<'a> std::fmt::Debug for OnionStoreMap<'a> {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct KeyFor(OnionAddress);
|
struct KeyFor(#[allow(unused)] OnionAddress);
|
||||||
let mut map = f.debug_map();
|
let mut map = f.debug_map();
|
||||||
for (k, v) in self.0 {
|
for (k, v) in self.0 {
|
||||||
map.key(k);
|
map.key(k);
|
||||||
@@ -451,7 +444,6 @@ impl TorController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn reset(&self, wipe_state: bool) -> Result<(), Error> {
|
pub async fn reset(&self, wipe_state: bool) -> Result<(), Error> {
|
||||||
// todo!()
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,7 +480,7 @@ impl OnionService {
|
|||||||
.run_while(async {
|
.run_while(async {
|
||||||
loop {
|
loop {
|
||||||
if let Err(e) = async {
|
if let Err(e) = async {
|
||||||
let (new_service, mut stream) = client.peek(|c| {
|
let (new_service, stream) = client.peek(|c| {
|
||||||
c.launch_onion_service_with_hsid(
|
c.launch_onion_service_with_hsid(
|
||||||
OnionServiceConfigBuilder::default()
|
OnionServiceConfigBuilder::default()
|
||||||
.nickname(
|
.nickname(
|
||||||
@@ -504,68 +496,81 @@ impl OnionService {
|
|||||||
)
|
)
|
||||||
.with_kind(ErrorKind::Tor)
|
.with_kind(ErrorKind::Tor)
|
||||||
})?;
|
})?;
|
||||||
|
let addr = new_service.onion_address().map(|a| safelog::DisplayRedacted::display_unredacted(&a).to_string());
|
||||||
|
let mut status_stream = new_service.status_events();
|
||||||
|
bg.add_job(async move {
|
||||||
|
while let Some(status) = status_stream.next().await {
|
||||||
|
tracing::debug!("{addr:?} status: {status:?}");
|
||||||
|
if let Some(err) = status.current_problem() {
|
||||||
|
tracing::error!("{err:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
service.replace(Some(new_service));
|
service.replace(Some(new_service));
|
||||||
|
let mut stream = tor_hsservice::handle_rend_requests(stream);
|
||||||
while let Some(req) = stream.next().await {
|
while let Some(req) = stream.next().await {
|
||||||
bg.add_job({
|
bg.add_job({
|
||||||
let bg = bg.clone();
|
let bg = bg.clone();
|
||||||
let bindings = bindings.clone();
|
let bindings = bindings.clone();
|
||||||
async move {
|
async move {
|
||||||
if let Err(e) = async {
|
if let Err(e) = async {
|
||||||
let mut stream =
|
let IncomingStreamRequest::Begin(begin) =
|
||||||
req.accept().await.with_kind(ErrorKind::Tor)?;
|
req.request()
|
||||||
while let Some(req) = stream.next().await {
|
else {
|
||||||
let IncomingStreamRequest::Begin(begin) =
|
return req
|
||||||
req.request()
|
.reject(tor_cell::relaycell::msg::End::new_with_reason(
|
||||||
else {
|
tor_cell::relaycell::msg::EndReason::DONE,
|
||||||
continue; // TODO: reject instead?
|
))
|
||||||
};
|
|
||||||
let Some(target) = bindings.peek(|b| {
|
|
||||||
b.get(&begin.port()).and_then(|a| {
|
|
||||||
a.iter()
|
|
||||||
.find(|(_, rc)| {
|
|
||||||
rc.strong_count() > 0
|
|
||||||
})
|
|
||||||
.map(|(addr, _)| *addr)
|
|
||||||
})
|
|
||||||
}) else {
|
|
||||||
continue; // TODO: reject instead?
|
|
||||||
};
|
|
||||||
bg.add_job(async move {
|
|
||||||
if let Err(e) = async {
|
|
||||||
let mut outgoing =
|
|
||||||
TcpStream::connect(target)
|
|
||||||
.await
|
|
||||||
.with_kind(
|
|
||||||
ErrorKind::Network,
|
|
||||||
)?;
|
|
||||||
let mut incoming = req
|
|
||||||
.accept(Connected::new_empty())
|
|
||||||
.await
|
|
||||||
.with_kind(ErrorKind::Tor)?;
|
|
||||||
if let Err(e) =
|
|
||||||
tokio::io::copy_bidirectional(
|
|
||||||
&mut outgoing,
|
|
||||||
&mut incoming,
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
tracing::error!("{e}");
|
|
||||||
tracing::debug!("{e:?}");
|
|
||||||
}
|
|
||||||
incoming.flush().await?;
|
|
||||||
outgoing.flush().await?;
|
|
||||||
incoming.shutdown().await?;
|
|
||||||
outgoing.shutdown().await?;
|
|
||||||
|
|
||||||
Ok::<_, Error>(())
|
|
||||||
}
|
|
||||||
.await
|
.await
|
||||||
|
.with_kind(ErrorKind::Tor);
|
||||||
|
};
|
||||||
|
let Some(target) = bindings.peek(|b| {
|
||||||
|
b.get(&begin.port()).and_then(|a| {
|
||||||
|
a.iter()
|
||||||
|
.find(|(_, rc)| rc.strong_count() > 0)
|
||||||
|
.map(|(addr, _)| *addr)
|
||||||
|
})
|
||||||
|
}) else {
|
||||||
|
return req
|
||||||
|
.reject(tor_cell::relaycell::msg::End::new_with_reason(
|
||||||
|
tor_cell::relaycell::msg::EndReason::DONE,
|
||||||
|
))
|
||||||
|
.await
|
||||||
|
.with_kind(ErrorKind::Tor);
|
||||||
|
};
|
||||||
|
bg.add_job(async move {
|
||||||
|
if let Err(e) = async {
|
||||||
|
let mut outgoing =
|
||||||
|
TcpStream::connect(target)
|
||||||
|
.await
|
||||||
|
.with_kind(ErrorKind::Network)?;
|
||||||
|
let mut incoming = req
|
||||||
|
.accept(Connected::new_empty())
|
||||||
|
.await
|
||||||
|
.with_kind(ErrorKind::Tor)?;
|
||||||
|
if let Err(e) =
|
||||||
|
tokio::io::copy_bidirectional(
|
||||||
|
&mut outgoing,
|
||||||
|
&mut incoming,
|
||||||
|
)
|
||||||
|
.await
|
||||||
{
|
{
|
||||||
tracing::error!("{e}");
|
tracing::error!("{e}");
|
||||||
tracing::debug!("{e:?}");
|
tracing::debug!("{e:?}");
|
||||||
}
|
}
|
||||||
});
|
incoming.flush().await?;
|
||||||
}
|
outgoing.flush().await?;
|
||||||
|
incoming.shutdown().await?;
|
||||||
|
outgoing.shutdown().await?;
|
||||||
|
|
||||||
|
Ok::<_, Error>(())
|
||||||
|
}
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
tracing::error!("{e}");
|
||||||
|
tracing::debug!("{e:?}");
|
||||||
|
}
|
||||||
|
});
|
||||||
Ok::<_, Error>(())
|
Ok::<_, Error>(())
|
||||||
}
|
}
|
||||||
.await
|
.await
|
||||||
@@ -623,6 +628,7 @@ impl OnionService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn shutdown(self) -> Result<(), Error> {
|
pub async fn shutdown(self) -> Result<(), Error> {
|
||||||
|
self.0.service.replace(None);
|
||||||
self.0._thread.abort();
|
self.0._thread.abort();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use std::task::Poll;
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use axum::Router;
|
use axum::Router;
|
||||||
use futures::future::Either;
|
|
||||||
use futures::FutureExt;
|
use futures::FutureExt;
|
||||||
|
use futures::future::Either;
|
||||||
use helpers::NonDetachingJoinHandle;
|
use helpers::NonDetachingJoinHandle;
|
||||||
use hyper_util::rt::{TokioIo, TokioTimer};
|
use hyper_util::rt::{TokioIo, TokioTimer};
|
||||||
use tokio::net::{TcpListener, TcpStream};
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
@@ -15,7 +15,7 @@ use tokio::sync::oneshot;
|
|||||||
|
|
||||||
use crate::context::{DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext};
|
use crate::context::{DiagnosticContext, InitContext, InstallContext, RpcContext, SetupContext};
|
||||||
use crate::net::gateway::{
|
use crate::net::gateway::{
|
||||||
lookup_info_by_addr, NetworkInterfaceListener, SelfContainedNetworkInterfaceListener,
|
NetworkInterfaceListener, SelfContainedNetworkInterfaceListener, lookup_info_by_addr,
|
||||||
};
|
};
|
||||||
use crate::net::static_server::{
|
use crate::net::static_server::{
|
||||||
diagnostic_ui_router, init_ui_router, install_ui_router, main_ui_router, redirecter, refresher,
|
diagnostic_ui_router, init_ui_router, install_ui_router, main_ui_router, redirecter, refresher,
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ use crate::service::effects::prelude::*;
|
|||||||
use crate::service::persistent_container::Subcontainer;
|
use crate::service::persistent_container::Subcontainer;
|
||||||
use crate::util::Invoke;
|
use crate::util::Invoke;
|
||||||
|
|
||||||
#[cfg(feature = "container-runtime")]
|
#[cfg(feature = "start-container")]
|
||||||
mod sync;
|
mod sync;
|
||||||
|
|
||||||
#[cfg(not(feature = "container-runtime"))]
|
#[cfg(not(feature = "start-container"))]
|
||||||
mod sync_dummy;
|
mod sync_dummy;
|
||||||
|
|
||||||
pub use sync::*;
|
pub use sync::*;
|
||||||
#[cfg(not(feature = "container-runtime"))]
|
#[cfg(not(feature = "start-container"))]
|
||||||
use sync_dummy as sync;
|
use sync_dummy as sync;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
|
#[derive(Debug, Deserialize, Serialize, Parser, TS)]
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ impl BackgroundJobRunner {
|
|||||||
cx: &mut std::task::Context<'_>,
|
cx: &mut std::task::Context<'_>,
|
||||||
) -> std::task::Poll<Self::Output> {
|
) -> std::task::Poll<Self::Output> {
|
||||||
let this = self.project();
|
let this = self.project();
|
||||||
this.runner.poll(cx);
|
let _ = this.runner.poll(cx);
|
||||||
this.fut.poll(cx)
|
this.fut.poll(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use std::os::unix::prelude::MetadataExt;
|
|||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::atomic::AtomicU64;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::AtomicU64;
|
||||||
use std::task::{Poll, Waker};
|
use std::task::{Poll, Waker};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ use nix::unistd::{Gid, Uid};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tokio::fs::{File, OpenOptions};
|
use tokio::fs::{File, OpenOptions};
|
||||||
use tokio::io::{
|
use tokio::io::{
|
||||||
duplex, AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, DuplexStream, ReadBuf, WriteHalf,
|
AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, DuplexStream, ReadBuf, WriteHalf, duplex,
|
||||||
};
|
};
|
||||||
use tokio::net::TcpStream;
|
use tokio::net::TcpStream;
|
||||||
use tokio::sync::{Notify, OwnedMutexGuard};
|
use tokio::sync::{Notify, OwnedMutexGuard};
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use std::sync::atomic::AtomicUsize;
|
|||||||
use std::sync::{Arc, Weak};
|
use std::sync::{Arc, Weak};
|
||||||
use std::task::{Poll, Waker};
|
use std::task::{Poll, Waker};
|
||||||
|
|
||||||
use futures::stream::BoxStream;
|
|
||||||
use futures::Stream;
|
use futures::Stream;
|
||||||
|
use futures::stream::BoxStream;
|
||||||
|
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
|||||||
2
patch-db
2
patch-db
Submodule patch-db updated: d2f38ef5f7...5b23a1eac6
@@ -193,7 +193,7 @@ export class PublicDomainService {
|
|||||||
),
|
),
|
||||||
250,
|
250,
|
||||||
)
|
)
|
||||||
} else if (ip === wanIp) {
|
} else if (ip !== wanIp) {
|
||||||
setTimeout(
|
setTimeout(
|
||||||
() =>
|
() =>
|
||||||
this.showDns(
|
this.showDns(
|
||||||
|
|||||||
@@ -167,10 +167,9 @@ export class InterfaceTorDomainsComponent {
|
|||||||
const loader = this.loader.open('Saving').subscribe()
|
const loader = this.loader.open('Saving').subscribe()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let onion = key
|
const onion = key
|
||||||
? await this.api.addTorKey({ key })
|
? await this.api.addTorKey({ key })
|
||||||
: await this.api.generateTorKey({})
|
: await this.api.generateTorKey({})
|
||||||
onion = `${onion}.onion`
|
|
||||||
|
|
||||||
if (this.interface.packageId) {
|
if (this.interface.packageId) {
|
||||||
await this.api.pkgAddOnion({
|
await this.api.pkgAddOnion({
|
||||||
|
|||||||
@@ -114,14 +114,16 @@ export default class ServiceInterfaceRoute {
|
|||||||
|
|
||||||
const { serviceInterfaces, hosts } = pkg
|
const { serviceInterfaces, hosts } = pkg
|
||||||
const iFace = serviceInterfaces[this.interfaceId()]
|
const iFace = serviceInterfaces[this.interfaceId()]
|
||||||
const key = iFace?.addressInfo.hostId || ''
|
const key = iFace!.addressInfo.hostId || ''
|
||||||
const host = hosts[key]
|
const host = hosts[key]
|
||||||
const port = iFace?.addressInfo.internalPort
|
const port = iFace!.addressInfo.internalPort
|
||||||
|
|
||||||
if (!host || !iFace || !port) {
|
if (!host || !iFace || !port) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const binding = host.bindings[port]
|
||||||
|
|
||||||
const gateways = this.gatewayService.gateways() || []
|
const gateways = this.gatewayService.gateways() || []
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -129,10 +131,13 @@ export default class ServiceInterfaceRoute {
|
|||||||
addresses: this.interfaceService.getAddresses(iFace, host, gateways),
|
addresses: this.interfaceService.getAddresses(iFace, host, gateways),
|
||||||
gateways:
|
gateways:
|
||||||
gateways.map(g => ({
|
gateways.map(g => ({
|
||||||
enabled: true,
|
enabled:
|
||||||
|
(g.public
|
||||||
|
? binding?.net.publicEnabled.includes(g.id)
|
||||||
|
: !binding?.net.privateDisabled.includes(g.id)) ?? false,
|
||||||
...g,
|
...g,
|
||||||
})) || [],
|
})) || [],
|
||||||
torDomains: host.onions.map(o => `${o}.onion`),
|
torDomains: host.onions,
|
||||||
publicDomains: getPublicDomains(host.publicDomains, gateways),
|
publicDomains: getPublicDomains(host.publicDomains, gateways),
|
||||||
privateDomains: host.privateDomains,
|
privateDomains: host.privateDomains,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -84,6 +84,8 @@ export default class StartOsUiComponent {
|
|||||||
|
|
||||||
if (!network || !gateways) return
|
if (!network || !gateways) return
|
||||||
|
|
||||||
|
const binding = network.host.bindings['80']
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...this.iface,
|
...this.iface,
|
||||||
addresses: this.interfaceService.getAddresses(
|
addresses: this.interfaceService.getAddresses(
|
||||||
@@ -92,10 +94,13 @@ export default class StartOsUiComponent {
|
|||||||
gateways,
|
gateways,
|
||||||
),
|
),
|
||||||
gateways: gateways.map(g => ({
|
gateways: gateways.map(g => ({
|
||||||
enabled: true,
|
enabled:
|
||||||
|
(g.public
|
||||||
|
? binding?.net.publicEnabled.includes(g.id)
|
||||||
|
: !binding?.net.privateDisabled.includes(g.id)) ?? false,
|
||||||
...g,
|
...g,
|
||||||
})),
|
})),
|
||||||
torDomains: network.host.onions.map(o => `${o}.onion`),
|
torDomains: network.host.onions,
|
||||||
publicDomains: getPublicDomains(network.host.publicDomains, gateways),
|
publicDomains: getPublicDomains(network.host.publicDomains, gateways),
|
||||||
privateDomains: network.host.privateDomains,
|
privateDomains: network.host.privateDomains,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ export namespace RR {
|
|||||||
key: string
|
key: string
|
||||||
}
|
}
|
||||||
export type GenerateTorKeyReq = {} // net.tor.key.generate
|
export type GenerateTorKeyReq = {} // net.tor.key.generate
|
||||||
export type AddTorKeyRes = string // onion address without .onion suffix
|
export type AddTorKeyRes = string // onion address *with* .onion suffix
|
||||||
|
|
||||||
export type ServerBindingToggleGatewayReq = {
|
export type ServerBindingToggleGatewayReq = {
|
||||||
// server.host.binding.set-gateway-enabled
|
// server.host.binding.set-gateway-enabled
|
||||||
|
|||||||
@@ -1339,12 +1339,12 @@ export class MockApiService extends ApiService {
|
|||||||
|
|
||||||
async addTorKey(params: RR.AddTorKeyReq): Promise<RR.AddTorKeyRes> {
|
async addTorKey(params: RR.AddTorKeyReq): Promise<RR.AddTorKeyRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
return 'vanityabcdefghijklmnop'
|
return 'vanityabcdefghijklmnop.onion'
|
||||||
}
|
}
|
||||||
|
|
||||||
async generateTorKey(params: RR.GenerateTorKeyReq): Promise<RR.AddTorKeyRes> {
|
async generateTorKey(params: RR.GenerateTorKeyReq): Promise<RR.AddTorKeyRes> {
|
||||||
await pauseFor(2000)
|
await pauseFor(2000)
|
||||||
return 'abcdefghijklmnopqrstuv'
|
return 'abcdefghijklmnopqrstuv.onion'
|
||||||
}
|
}
|
||||||
|
|
||||||
async serverBindingToggleGateway(
|
async serverBindingToggleGateway(
|
||||||
|
|||||||
Reference in New Issue
Block a user