mirror of
https://github.com/EasyTier/EasyTier.git
synced 2026-09-01 08:49:16 +00:00
3fe427bc99
* feat(credentials): manage declarative credentials through TOML Make managed credentials part of the canonical TOML configuration and load them before peers can authenticate. Reuse ConfigRpc hot patches to durably replace the configured credential set without restarting the instance. Serialize credential mutations so base, managed, and ephemeral keys cannot race into conflicts. Remove the managed overlay file format, digest protocol, capability negotiation, force reconciliation, and database CAS machinery. Redact credential secrets from debug output and management events. Write credential-bearing files atomically with private permissions. * fix(core): release JoinSet reapers with their owners Pass weak task-set references into background reapers so they cannot retain the JoinSet they are meant to collect. This lets stale smoltcp bridge tasks terminate when an IPv4 generation is replaced. Add ownership and TCP generation-replacement regressions covering the production port-forward failure.
149 lines
4.4 KiB
Rust
149 lines
4.4 KiB
Rust
mod rpc;
|
|
|
|
use crate::rpc::ServiceGenerator;
|
|
use std::{env, path::PathBuf};
|
|
|
|
#[cfg(target_os = "windows")]
|
|
use std::io::Cursor;
|
|
|
|
#[cfg(target_os = "windows")]
|
|
fn check_protoc_exist() -> Option<PathBuf> {
|
|
let path = env::var_os("PROTOC").map(PathBuf::from);
|
|
if path.is_some() && path.as_ref().unwrap().exists() {
|
|
return path;
|
|
}
|
|
|
|
let path = env::var_os("PATH").unwrap_or_default();
|
|
for p in env::split_paths(&path) {
|
|
let p = p.join("protoc.exe");
|
|
if p.exists() && p.is_file() {
|
|
return Some(p);
|
|
}
|
|
}
|
|
|
|
None
|
|
}
|
|
|
|
#[cfg(target_os = "windows")]
|
|
fn get_cargo_target_dir() -> Result<PathBuf, Box<dyn std::error::Error>> {
|
|
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
|
|
let profile = env::var("PROFILE")?;
|
|
let mut target_dir = None;
|
|
let mut sub_path = out_dir.as_path();
|
|
while let Some(parent) = sub_path.parent() {
|
|
if parent.ends_with(&profile) {
|
|
target_dir = Some(parent);
|
|
break;
|
|
}
|
|
sub_path = parent;
|
|
}
|
|
let target_dir = target_dir.ok_or("not found")?;
|
|
Ok(target_dir.to_path_buf())
|
|
}
|
|
|
|
#[cfg(target_os = "windows")]
|
|
fn download_protoc() -> PathBuf {
|
|
let out_dir = get_cargo_target_dir().unwrap().join("protobuf");
|
|
let fname = out_dir.join("bin/protoc.exe");
|
|
if fname.exists() {
|
|
println!("cargo:info=use existing protoc: {:?}", fname);
|
|
return fname;
|
|
}
|
|
|
|
println!("cargo:info=need download protoc, please wait...");
|
|
|
|
let url = "https://github.com/protocolbuffers/protobuf/releases/download/v26.0-rc1/protoc-26.0-rc-1-win64.zip";
|
|
let response = reqwest::blocking::get(url).unwrap();
|
|
println!("{:?}", response);
|
|
let mut content = response
|
|
.bytes()
|
|
.map(|v| v.to_vec())
|
|
.map(Cursor::new)
|
|
.map(zip::ZipArchive::new)
|
|
.unwrap()
|
|
.unwrap();
|
|
content.extract(out_dir).unwrap();
|
|
|
|
fname
|
|
}
|
|
|
|
#[cfg(target_os = "windows")]
|
|
fn ensure_protoc_for_windows() {
|
|
let protoc_path = if let Some(path) = check_protoc_exist() {
|
|
println!("cargo:info=use os existing protoc: {:?}", path);
|
|
path
|
|
} else {
|
|
download_protoc()
|
|
};
|
|
|
|
unsafe {
|
|
env::set_var("PROTOC", protoc_path);
|
|
}
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
#[cfg(target_os = "windows")]
|
|
ensure_protoc_for_windows();
|
|
|
|
let proto_files_reflect = ["proto/peer_rpc.proto", "proto/common.proto"];
|
|
|
|
let proto_files = [
|
|
"proto/core_peer.proto",
|
|
"proto/core_config.proto",
|
|
"proto/error.proto",
|
|
"proto/tests.proto",
|
|
"proto/api_instance.proto",
|
|
"proto/api_logger.proto",
|
|
"proto/api_config.proto",
|
|
"proto/api_manage.proto",
|
|
"proto/web.proto",
|
|
"proto/magic_dns.proto",
|
|
"proto/acl.proto",
|
|
];
|
|
|
|
for proto_file in proto_files.iter().chain(proto_files_reflect.iter()) {
|
|
println!("cargo:rerun-if-changed={proto_file}");
|
|
}
|
|
|
|
let out = PathBuf::from(env::var("OUT_DIR")?);
|
|
let descriptor = out.join("descriptors.bin");
|
|
|
|
let mut config = prost_build::Config::new();
|
|
if env::var_os("CARGO_FEATURE_JSON_RPC").is_some() {
|
|
config
|
|
.extern_path(".google.protobuf.Any", "::prost_wkt_types::Any")
|
|
.extern_path(".google.protobuf.Timestamp", "::prost_wkt_types::Timestamp")
|
|
.extern_path(".google.protobuf.Value", "::prost_wkt_types::Value");
|
|
} else {
|
|
config
|
|
.extern_path(".google.protobuf.Any", "::prost_types::Any")
|
|
.extern_path(".google.protobuf.Timestamp", "::prost_types::Timestamp")
|
|
.extern_path(".google.protobuf.Value", "::prost_types::Value");
|
|
}
|
|
config
|
|
.file_descriptor_set_path(&descriptor)
|
|
.service_generator(Box::new(ServiceGenerator::default()))
|
|
.btree_map(["."])
|
|
.skip_debug([
|
|
".common.Ipv4Addr",
|
|
".common.Ipv6Addr",
|
|
".common.UUID",
|
|
".api.manage.ManagedCredentialConfig",
|
|
".api.manage.VpnPortalConfig",
|
|
]);
|
|
|
|
config.compile_protos(&proto_files, &["proto/"])?;
|
|
|
|
config.file_descriptor_set_path(out.join("file_descriptor_set.bin"));
|
|
config.compile_protos(&proto_files_reflect, &["proto/"])?;
|
|
|
|
let descriptor = std::fs::read(descriptor)?;
|
|
pbjson_build::Builder::new()
|
|
.register_descriptors(&descriptor)?
|
|
.preserve_proto_field_names()
|
|
.btree_map(["."])
|
|
.build(&["."])?;
|
|
|
|
Ok(())
|
|
}
|