mirror of https://github.com/ospab/ostp.git
Compare commits
3 Commits
b7a31af911
...
6987ac5344
| Author | SHA1 | Date |
|---|---|---|
|
|
6987ac5344 | |
|
|
d65af355f1 | |
|
|
23c4d38ee4 |
|
|
@ -98,7 +98,7 @@ pub async fn dial_tcp(
|
|||
let mut buf = [0u8; 8192];
|
||||
let mut handshake_success = false;
|
||||
match tokio::time::timeout(
|
||||
std::time::Duration::from_millis(3000),
|
||||
std::time::Duration::from_millis(15000),
|
||||
transport.recv(&mut buf),
|
||||
).await {
|
||||
Ok(Ok(n)) => {
|
||||
|
|
@ -108,7 +108,7 @@ pub async fn dial_tcp(
|
|||
}
|
||||
}
|
||||
_ => {
|
||||
tracing::warn!("TCP handshake timeout for {}:{}", server_str, port);
|
||||
tracing::warn!("OSTP handshake timeout for {}:{}", server_str, port);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -133,7 +133,7 @@ pub async fn dial_tcp(
|
|||
// The kernel will buffer incoming data from server_stream while we wait.
|
||||
let mut connect_ok = false;
|
||||
match tokio::time::timeout(
|
||||
std::time::Duration::from_secs(10),
|
||||
std::time::Duration::from_secs(30),
|
||||
async {
|
||||
let mut wait_buf = [0u8; 8192];
|
||||
loop {
|
||||
|
|
@ -247,14 +247,14 @@ pub async fn handle_udp(
|
|||
// Wait for handshake response (server sends HandshakePayload back)
|
||||
let mut buf = [0u8; 8192];
|
||||
match tokio::time::timeout(
|
||||
std::time::Duration::from_millis(2000),
|
||||
std::time::Duration::from_millis(15000),
|
||||
transport.recv(&mut buf),
|
||||
).await {
|
||||
Ok(Ok(n)) => {
|
||||
let _ = machine.on_event(OstpEvent::Inbound(bytes::Bytes::copy_from_slice(&buf[..n])));
|
||||
}
|
||||
_ => {
|
||||
tracing::warn!("UDP handshake timeout for {}:{}", server, port);
|
||||
tracing::warn!("OSTP handshake timeout for {}:{}", server, port);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
|
@ -304,7 +304,7 @@ async fn make_transport(
|
|||
let domain = transport_cfg.domain.clone()
|
||||
.unwrap_or_else(|| "tunnel.example.com".to_string());
|
||||
let resolver = transport_cfg.resolver.clone()
|
||||
.unwrap_or_else(|| "8.8.8.8".to_string());
|
||||
.unwrap_or_else(|| server.to_string());
|
||||
let transport = crate::transport::dns::start_dns_transport(domain, resolver, transport_cfg.pubkey.clone()).await
|
||||
.map_err(|e| anyhow::anyhow!(e))?;
|
||||
Ok(transport)
|
||||
|
|
|
|||
|
|
@ -24,6 +24,3 @@ reqwest = { version = "0.12", default-features = false, features = ["blocking",
|
|||
pico-args = "0.5.0"
|
||||
clipboard-win = "3.1.1"
|
||||
|
||||
[[bin]]
|
||||
name = "test_parse"
|
||||
path = "../test_parse.rs"
|
||||
|
|
|
|||
|
|
@ -80,6 +80,83 @@ struct Args {
|
|||
prober: bool,
|
||||
}
|
||||
|
||||
fn patch_existing_client_config(config_path: &std::path::Path, new_client_inner: serde_json::Value) -> serde_json::Value {
|
||||
let unified_new = serde_json::to_value(UnifiedConfig {
|
||||
mode: AppMode::Client(new_client_inner.clone()),
|
||||
version: Some(env!("CARGO_PKG_VERSION").to_string()),
|
||||
log: Some(serde_json::json!({ "level": "info" })),
|
||||
}).unwrap();
|
||||
|
||||
if !config_path.exists() {
|
||||
return unified_new;
|
||||
}
|
||||
|
||||
let content = match std::fs::read_to_string(config_path) {
|
||||
Ok(c) => c,
|
||||
Err(_) => return unified_new,
|
||||
};
|
||||
|
||||
let mut stripped = json_comments::StripComments::new(content.as_bytes());
|
||||
let mut existing: serde_json::Value = match serde_json::from_reader(&mut stripped) {
|
||||
Ok(v) => v,
|
||||
Err(_) => return unified_new,
|
||||
};
|
||||
|
||||
if existing.get("mode").and_then(|m| m.as_str()) != Some("client") {
|
||||
return unified_new;
|
||||
}
|
||||
|
||||
let mut new_proxy = None;
|
||||
if let Some(outbounds) = new_client_inner.get("outbounds").and_then(|o| o.as_array()) {
|
||||
for ob in outbounds {
|
||||
if ob.get("tag").and_then(|t| t.as_str()) == Some("proxy") {
|
||||
new_proxy = Some(ob.clone());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(new_proxy) = new_proxy {
|
||||
if let Some(existing_outbounds) = existing.get_mut("outbounds").and_then(|o| o.as_array_mut()) {
|
||||
let mut replaced = false;
|
||||
for ob in existing_outbounds.iter_mut() {
|
||||
if ob.get("tag").and_then(|t| t.as_str()) == Some("proxy") {
|
||||
*ob = new_proxy.clone();
|
||||
replaced = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !replaced {
|
||||
existing_outbounds.insert(0, new_proxy);
|
||||
}
|
||||
} else {
|
||||
existing["outbounds"] = serde_json::json!([new_proxy]);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(new_inbounds) = new_client_inner.get("inbounds").and_then(|i| i.as_array()) {
|
||||
for new_ib in new_inbounds {
|
||||
if new_ib.get("type").and_then(|t| t.as_str()) == Some("tun") {
|
||||
if let Some(auto_route) = new_ib.get("auto_route").and_then(|a| a.as_bool()) {
|
||||
if auto_route {
|
||||
if let Some(existing_inbounds) = existing.get_mut("inbounds").and_then(|i| i.as_array_mut()) {
|
||||
for existing_ib in existing_inbounds.iter_mut() {
|
||||
if existing_ib.get("type").and_then(|t| t.as_str()) == Some("tun") {
|
||||
existing_ib["auto_route"] = serde_json::json!(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
existing["version"] = serde_json::json!(env!("CARGO_PKG_VERSION"));
|
||||
|
||||
existing
|
||||
}
|
||||
|
||||
fn parse_ostp_link(link: &str) -> Result<serde_json::Value> {
|
||||
let parsed = url::Url::parse(link)
|
||||
.map_err(|e| anyhow!("Failed to parse share link URL: {e}"))?;
|
||||
|
|
@ -1224,12 +1301,8 @@ async fn run_app() -> Result<()> {
|
|||
println!("{} Importing configuration from share link...", "[ostp]".cyan().bold());
|
||||
let client_cfg = parse_ostp_link(&import_url)
|
||||
.map_err(|e| anyhow!("Share Link Error: {e}"))?;
|
||||
let unified = UnifiedConfig {
|
||||
mode: AppMode::Client(client_cfg),
|
||||
version: Some("0.3.1".to_string()),
|
||||
log: Some(serde_json::json!({ "level": "info" })),
|
||||
};
|
||||
let content = serde_json::to_string_pretty(&unified)?;
|
||||
let patched = patch_existing_client_config(&args.config, client_cfg);
|
||||
let content = serde_json::to_string_pretty(&patched)?;
|
||||
if let Some(parent) = args.config.parent() {
|
||||
if !parent.as_os_str().is_empty() {
|
||||
fs::create_dir_all(parent)?;
|
||||
|
|
@ -1301,7 +1374,8 @@ async fn run_app() -> Result<()> {
|
|||
client_cfg["log"]["level"] = serde_json::json!("debug");
|
||||
}
|
||||
|
||||
return run_client_directly(client_cfg).await;
|
||||
let patched = patch_existing_client_config(&args.config, client_cfg);
|
||||
return run_client_directly(patched).await;
|
||||
}
|
||||
|
||||
// Handle --check: validate config and exit
|
||||
|
|
|
|||
Loading…
Reference in New Issue