This commit is contained in:
snltty
2025-04-24 00:55:37 +08:00
parent a835545b77
commit e20b01a4b7
5 changed files with 38 additions and 40 deletions

View File

@@ -92,6 +92,8 @@ namespace linker.app
[Service(Label = "VpnServiceLinker", Name = "com.snltty.linker.app.VpnServiceLinker", Enabled = true, Permission = "android.permission.BIND_VPN_SERVICE")]
public class VpnServiceLinker : VpnService, ILinkerTunDeviceCallback, ITuntapProxyCallback
{
private static LinkerVpnDevice linkerVpnDevice = new LinkerVpnDevice();
TuntapConfigTransfer tuntapConfigTransfer;
TuntapProxy tuntapProxy;
TuntapDecenter tuntapDecenter;
@@ -105,7 +107,8 @@ namespace linker.app
tuntapProxy.Callback = this;
tuntapDecenter = LinkerMessengerEntry.GetService<TuntapDecenter>();
tuntapTransfer.Initialize(new LinkerVpnDevice(this), this);
linkerVpnDevice.SetVpnService(this);
tuntapTransfer.Initialize(linkerVpnDevice, this);
}
public override void OnCreate()
{
@@ -298,7 +301,13 @@ namespace linker.app
FileInputStream vpnInput;
FileOutputStream vpnOutput;
public LinkerVpnDevice(VpnService vpnService)
LinkerTunDeviceRouteItem[] routes = [];
public LinkerVpnDevice()
{
}
public void SetVpnService(VpnService vpnService)
{
this.vpnService = vpnService;
}
@@ -317,6 +326,12 @@ namespace linker.app
builder.SetMtu(1420)
.AddAddress(address.ToString(), prefixLength)
.AddDnsServer("8.8.8.8").SetBlocking(false);
foreach (var item in routes)
{
builder.AddRoute(NetworkHelper.ToNetworkIP(item.Address, item.PrefixLength).ToString(), item.PrefixLength);
}
if (OperatingSystem.IsAndroidVersionAtLeast(29))
builder.SetMetered(false);
vpnInterface = builder.SetSession(name).Establish();
@@ -350,10 +365,11 @@ namespace linker.app
catch (Exception)
{
}
return buffer;
return Helper.EmptyArray;
}
public bool Write(ReadOnlyMemory<byte> buffer)
{
if (fd == 0) return false;
try
{
buffer.CopyTo(bufferWrite);
@@ -409,6 +425,7 @@ namespace linker.app
public void AddRoute(LinkerTunDeviceRouteItem[] ips)
{
routes = ips.Select(c => new LinkerTunDeviceRouteItem { Address = c.Address, PrefixLength = c.PrefixLength }).ToArray();
}
public void RemoveRoute(LinkerTunDeviceRouteItem[] ips)
{

View File

@@ -296,7 +296,11 @@ namespace linker.libs
public static IPAddress ToNetworkIP(IPAddress ip, uint prefixIP)
{
return ToNetworkIP(BinaryPrimitives.ReadUInt32BigEndian(ip.GetAddressBytes()), prefixIP);
return ToNetworkIP(ToValue(ip), prefixIP);
}
public static IPAddress ToNetworkIP(IPAddress ip, byte prefixLength)
{
return ToNetworkIP(ToValue(ip), ToPrefixValue(prefixLength));
}
public static IPAddress ToNetworkIP(uint ip, uint prefixIP)
{

View File

@@ -1,15 +1,16 @@
<template>
<div>
<template v-if="tuntap.list[item.MachineId] && tuntap.list[item.MachineId].system">
<span :title="tuntap.list[item.MachineId].SystemInfo">
<img class="system":src="`./${tuntap.list[item.MachineId].system}.svg`" />
<img v-if="tuntap.list[item.MachineId].systemDocker" class="system" :src="`./docker.svg`" />
</span>
</template>
<a href="javascript:;" @click="handleEdit" title="此客户端的设备名" class="a-line">
<strong class="gateway" :class="{green:item.Connected}">{{item.MachineName || 'null' }}</strong>
</a>
<strong class="self gateway" v-if="item.isSelf">(<el-icon size="16"><StarFilled /></el-icon>) </strong>
<template v-if="tuntap.list[item.MachineId] && tuntap.list[item.MachineId].systems">
<template v-for="system in tuntap.list[item.MachineId].systems">
<span :title="tuntap.list[item.MachineId].SystemInfo">
<img class="system":src="`./${system}.svg`" />
</span>
</template>
</template>
</div>
</template>
@@ -57,7 +58,7 @@ export default {
img.system{
height:1.6rem;
vertical-align: middle;
margin-right:.4rem
margin-left:.4rem
}
.self{
color:#d400ff;

View File

@@ -15,15 +15,7 @@ export const provideTuntap = () => {
});
provide(tuntapSymbol, tuntap);
const systems = {
linux: ['debian', 'ubuntu', 'alpine', 'rocky', 'centos', 'fedora', 'archlinux'],
armbian: ['armbian'],
openwrt: ['openwrt'],
ubuntu: ['ubuntu'],
windows: ['windows'],
android: ['android'],
ios: ['ios'],
}
const reg = /ios|android|windows|ubuntu|openwrt|armbian|archlinux|fedora|centos|rocky|alpine|debian|linux|docker/g;
const _getTuntapInfo = () => {
clearTimeout(tuntap.value.timer);
@@ -31,29 +23,13 @@ export const provideTuntap = () => {
tuntap.value.hashcode = res.HashCode;
if (res.List) {
for (let j in res.List) {
let system = 'system';
const systemStr = res.List[j].SystemInfo.toLowerCase();
for (let jj in systems) {
if (systemStr.indexOf(jj) >= 0) {
const items = systems[jj];
if (items.length == 1) {
system = items[0];
} else {
for (let i = 0; i < items.length; i++) {
if (systemStr.indexOf(items[i]) >= 0) {
system = items[i];
break;
}
}
}
break;
}
}
const match = systemStr.match(reg);
Object.assign(res.List[j], {
running: res.List[j].Status == 2,
loading: res.List[j].Status == 1,
system: system,
systemDocker: systemStr.indexOf('docker') >= 0,
systems: match
});
}
tuntap.value.list = res.List;

View File

@@ -1,5 +1,5 @@
v1.7.4
2025-04-23 23:28:20
2025-04-24 00:55:37
1. 一些优化
2. 内置应用层SNAT用于无法使用系统NetNat的windows系统
3. 如果你设备很多,请尝试升级其中一个成功重启后再升级其它