Add bind interface (#9222)

This commit is contained in:
DHR60
2026-05-04 06:38:32 +00:00
committed by GitHub
parent 37ef25cbfe
commit 8450f2e420
21 changed files with 261 additions and 67 deletions
@@ -57,6 +57,7 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
ConvertGeo2Ruleset();
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
@@ -170,6 +171,7 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
_coreConfig.route.rules.Add(rule);
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Success = true;
ret.Data = JsonUtils.Serialize(_coreConfig);
@@ -229,6 +231,7 @@ public partial class CoreConfigSingboxService(CoreConfigContext context)
listen_port = port,
type = EInboundProtocol.mixed.ToString(),
});
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
@@ -59,22 +59,38 @@ public partial class CoreConfigSingboxService
return JsonUtils.Serialize(fullConfigTemplateNode);
}
private void ApplyOutboundSendThrough()
private void ApplyOutboundBindInterface()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
var bindInterface = _config.CoreBasicItem.BindInterface?.TrimEx();
if (bindInterface.IsNullOrEmpty())
{
return;
}
if (!(context.IsTunEnabled || context.IsWindows))
{
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.inet4_bind_address = ShouldApplySendThrough(outbound, sendThrough) ? sendThrough : null;
outbound.detour = ShouldBindNet(outbound) ? bindInterface : null;
}
}
private static bool ShouldApplySendThrough(Outbound4Sbox outbound, string? sendThrough)
private void ApplyOutboundSendThrough()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
if (sendThrough.IsNullOrEmpty())
{
return false;
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.inet4_bind_address = ShouldBindNet(outbound) ? sendThrough : null;
}
}
private static bool ShouldBindNet(Outbound4Sbox outbound)
{
if (outbound.type is "direct" or "block" or "dns" or "selector" or "urltest")
{
return false;
@@ -60,6 +60,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{
ApplyOutboundFragment();
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
var finalRule = BuildFinalRule();
@@ -203,6 +204,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{
ApplyOutboundFragment();
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
//ret.Msg =string.Format(ResUI.SuccessfulConfiguration"), node.getSummary());
ret.Success = true;
@@ -274,6 +276,7 @@ public partial class CoreConfigV2rayService(CoreConfigContext context)
{
ApplyOutboundFragment();
}
ApplyOutboundBindInterface();
ApplyOutboundSendThrough();
ret.Msg = string.Format(ResUI.SuccessfulConfiguration, "");
@@ -134,22 +134,59 @@ public partial class CoreConfigV2rayService
return JsonUtils.Serialize(fullConfigTemplateNode);
}
private void ApplyOutboundSendThrough()
private void ApplyOutboundBindInterface()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
var bindInterface = _config.CoreBasicItem.BindInterface?.TrimEx();
if (bindInterface.IsNullOrEmpty())
{
return;
}
if (!(context.IsTunEnabled || context.IsWindows))
{
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.sendThrough = ShouldApplySendThrough(outbound, sendThrough) ? sendThrough : null;
if (!ShouldBindNet(outbound))
{
continue;
}
outbound.streamSettings ??= new();
outbound.streamSettings.sockopt ??= new();
outbound.streamSettings.sockopt.Interface = bindInterface;
// xhttp download bind interface
if (outbound?.streamSettings?.xhttpSettings?.extra is null)
{
continue;
}
var xhttpExtra = JsonUtils.ParseJson(JsonUtils.Serialize(outbound.streamSettings.xhttpSettings!.extra));
if (xhttpExtra is not JsonObject xhttpExtraObject
|| xhttpExtraObject["downloadSettings"] is not JsonObject downloadSettings)
{
continue;
}
var sockopt = downloadSettings["sockopt"] as JsonObject ?? new JsonObject();
sockopt["interface"] = bindInterface;
downloadSettings["sockopt"] = sockopt;
outbound.streamSettings.xhttpSettings.extra = xhttpExtraObject;
}
}
private static bool ShouldApplySendThrough(Outbounds4Ray outbound, string? sendThrough)
private void ApplyOutboundSendThrough()
{
var sendThrough = _config.CoreBasicItem.SendThrough?.TrimEx();
if (sendThrough.IsNullOrEmpty())
{
return false;
return;
}
foreach (var outbound in _coreConfig.outbounds ?? [])
{
outbound.sendThrough = ShouldBindNet(outbound) ? sendThrough : null;
}
}
private static bool ShouldBindNet(Outbounds4Ray outbound)
{
if (outbound.protocol is "freedom" or "blackhole" or "dns" or "loopback")
{
return false;
@@ -60,6 +60,11 @@ public partial class CoreConfigV2rayService
{
tunInbound.settings.gateway = ["172.18.0.1/30"];
}
var bindInterface = _config.CoreBasicItem.BindInterface?.TrimEx();
if (!bindInterface.IsNullOrEmpty())
{
tunInbound.settings.autoOutboundsInterface = bindInterface;
}
tunInbound.sniffing = inbound.sniffing;
_coreConfig.inbounds.Add(tunInbound);
}