diff --git a/core/server/test_utils.go b/core/server/test_utils.go index f7d7864..a96fc21 100644 --- a/core/server/test_utils.go +++ b/core/server/test_utils.go @@ -137,7 +137,7 @@ func BatchURLTest(ctx context.Context, i *boxbox.Box, outboundTags []string, url } client := &http.Client{ Transport: &http.Transport{ - DialContext: func(ctx context.Context, network string, addr string) (net.Conn, error) { + DialContext: func(_ context.Context, network string, addr string) (net.Conn, error) { return outbound.DialContext(ctx, "tcp", metadata.ParseSocksaddr(addr)) }, }, diff --git a/include/configs/common/Outbound.h b/include/configs/common/Outbound.h index bf53652..8ccdcd8 100644 --- a/include/configs/common/Outbound.h +++ b/include/configs/common/Outbound.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "DialFields.h" #include "multiplex.h" #include "TLS.h" @@ -27,18 +28,23 @@ namespace Configs void ResolveDomainToIP(const std::function &onFinished) { bool noResolve = false; - if (IsIpAddress(server) || server.isEmpty()) noResolve = true; + auto serverAddr = GetAddress(); + if (IsIpAddress(serverAddr) || serverAddr.isEmpty()) noResolve = true; if (noResolve) { onFinished(); return; } - QHostInfo::lookupHost(server, QApplication::instance(), [=, this](const QHostInfo &host) { + QHostInfo::lookupHost(serverAddr, QApplication::instance(), [=, this](const QHostInfo &host) { auto addrs = host.addresses(); - if (!addrs.isEmpty()) server = addrs.first().toString(); + if (!addrs.isEmpty()) SetAddress(addrs.first().toString()); onFinished(); }); } + virtual void SetAddress(QString newAddr) { + server = std::move(newAddr); + } + virtual QString GetAddress() { return server; diff --git a/include/configs/outbounds/tailscale.h b/include/configs/outbounds/tailscale.h index fde9097..6b709fb 100644 --- a/include/configs/outbounds/tailscale.h +++ b/include/configs/outbounds/tailscale.h @@ -40,6 +40,8 @@ namespace Configs QJsonObject ExportToJson() override; BuildResult Build() override; + void SetAddress(QString newAddr) override; + QString GetAddress() override; QString DisplayAddress() override; QString DisplayType() override; bool IsEndpoint() override; diff --git a/include/configs/outbounds/wireguard.h b/include/configs/outbounds/wireguard.h index 103c1e0..6d874b1 100644 --- a/include/configs/outbounds/wireguard.h +++ b/include/configs/outbounds/wireguard.h @@ -83,6 +83,8 @@ namespace Configs QJsonObject ExportToJson() override; BuildResult Build() override; + void SetAddress(QString newAddr) override; + QString GetAddress() override; QString DisplayAddress() override; QString DisplayType() override; bool IsEndpoint() override; diff --git a/src/configs/generate.cpp b/src/configs/generate.cpp index c1eb75c..26e16b9 100644 --- a/src/configs/generate.cpp +++ b/src/configs/generate.cpp @@ -529,7 +529,7 @@ namespace Configs { ctx->buildConfigResult->coreConfig["inbounds"] = inbounds; } - void unwrapChain(const QList& entIDs, QList> &ents, QString& error) + void entIDListtoEntList(const QList& entIDs, QList> &ents, QString& error) { bool hasExtracore = false; bool hasCustom = false; @@ -556,10 +556,24 @@ namespace Configs { } } + QList unwrapChain(int entID) { + auto ent = profileManager->GetProfile(entID); + if (ent == nullptr) + { + return {}; + } + if (ent->type == "chain") { + auto chain = ent->Chain(); + if (chain == nullptr) return {}; + return chain->list; + } + return {entID}; + } + void buildOutboundChain(std::shared_ptr &ctx, const QList& entIDs, const QString& prefix, bool includeProxy, bool link) { QList> ents; - unwrapChain(entIDs, ents, ctx->error); + entIDListtoEntList(entIDs, ents, ctx->error); for (int idx = 0; idx < ents.size(); idx++) { auto tag = prefix + "-" + Int2String(idx); @@ -898,6 +912,7 @@ namespace Configs { QList entIDs; for (const auto& proxy : profiles) entIDs << proxy->id; ctx->buildPrerequisities->dnsDeps->directDomains = QListStr2QJsonArray(getEntDomains(entIDs, ctx->error)); + if (!ctx->buildPrerequisities->dnsDeps->directDomains.isEmpty()) ctx->buildPrerequisities->dnsDeps->needDirectDnsRules = true; buildDNSSection(ctx); if (!ctx->error.isEmpty()) { @@ -942,7 +957,11 @@ namespace Configs { continue; } } - buildOutboundChain(ctx, {item->id}, "proxy-" + Int2String(suffix), false, true); + buildOutboundChain(ctx, unwrapChain(item->id), "proxy-" + Int2String(suffix), false, true); + if (!ctx->error.isEmpty()) { + res->error = ctx->error; + return res; + } auto tag = "proxy-" + Int2String(suffix) + "-0"; res->outboundTags << tag; res->tag2entID.insert(tag, item->id); diff --git a/src/configs/outbounds/tailscale.cpp b/src/configs/outbounds/tailscale.cpp index 066d103..e273911 100644 --- a/src/configs/outbounds/tailscale.cpp +++ b/src/configs/outbounds/tailscale.cpp @@ -114,6 +114,14 @@ namespace Configs { return {object, ""}; } + void tailscale::SetAddress(QString newAddr) { + control_url = newAddr; + } + + QString tailscale::GetAddress() { + return control_url; + } + QString tailscale::DisplayAddress() { return control_url; diff --git a/src/configs/outbounds/wireguard.cpp b/src/configs/outbounds/wireguard.cpp index 28768d3..8940472 100644 --- a/src/configs/outbounds/wireguard.cpp +++ b/src/configs/outbounds/wireguard.cpp @@ -261,9 +261,18 @@ namespace Configs { return {object, ""}; } + void wireguard::SetAddress(QString newAddr) { + peer->address = newAddr; + } + + QString wireguard::GetAddress() { + return peer->address; + } + + QString wireguard::DisplayAddress() { - return ::DisplayAddress(peer->address, peer->port > 0); + return ::DisplayAddress(peer->address, peer->port); } QString wireguard::DisplayType() diff --git a/src/dataStore/RouteEntity.cpp b/src/dataStore/RouteEntity.cpp index 7c06345..f9c05ad 100644 --- a/src/dataStore/RouteEntity.cpp +++ b/src/dataStore/RouteEntity.cpp @@ -784,17 +784,15 @@ namespace Configs { bool RoutingChain::add_simple_process_rule(const QString& content, const std::shared_ptr& rule, ruleType type) { - auto sp = content.split(":"); - if (sp.size() < 2) return false; - const QString& subType = sp[0]; - if (subType == "processPath" && type == simpleProcessPath) + if (!content.contains(":")) return false; + auto prefix = content.first(content.indexOf(':')); + const QString& address = content.section(':', 1); + if (prefix == "processPath" && type == simpleProcessPath) { - const QString& address = content.section(':', 1); if (!rule->process_path.contains(address)) rule->process_path.append(address); return true; - } else if (subType == "processName" && type == simpleProcessName && sp.size() == 2) + } else if (prefix == "processName" && type == simpleProcessName) { - const QString& address = sp[1]; if (!rule->process_name.contains(address)) rule->process_name.append(address); return true; } else diff --git a/src/ui/mainwindow.cpp b/src/ui/mainwindow.cpp index 6417667..5dc5141 100644 --- a/src/ui/mainwindow.cpp +++ b/src/ui/mainwindow.cpp @@ -1789,10 +1789,18 @@ void MainWindow::on_menu_export_config_triggered() { msg.exec(); if (msg.clickedButton() == button_1) { result = BuildSingBoxConfig(ent); + if (!result->error.isEmpty()) { + MessageBoxWarning("Build config error", result->error); + return; + } config_core = QJsonObject2QString(result->coreConfig, true); QApplication::clipboard()->setText(config_core); } else if (msg.clickedButton() == button_2) { auto res = Configs::BuildTestConfig({ent}); + if (!res->error.isEmpty()) { + MessageBoxWarning("Build Test config error", res->error); + return; + } config_core = QJsonObject2QString(res->coreConfig, true); QApplication::clipboard()->setText(config_core); }