mirror of
https://github.com/snltty/linker.git
synced 2025-09-27 05:25:57 +08:00
广播组播强制TLL-1
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
---
|
---
|
||||||
sidebar_position: 1
|
sidebar_position: 1
|
||||||
|
title: 1、首页
|
||||||
---
|
---
|
||||||
|
|
||||||
# 1、首页
|
# 1、首页
|
@@ -10,11 +10,24 @@ namespace linker.libs
|
|||||||
/// 计算IP包的校验和
|
/// 计算IP包的校验和
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="packet">一个完整的IP包</param>
|
/// <param name="packet">一个完整的IP包</param>
|
||||||
public static unsafe void Checksum(ReadOnlyMemory<byte> packet)
|
/// <param name="payload">是否计算荷载协议校验和</param>
|
||||||
|
public static unsafe void Checksum(ReadOnlyMemory<byte> packet,bool payload = true)
|
||||||
{
|
{
|
||||||
fixed (byte* ptr = packet.Span)
|
fixed (byte* ptr = packet.Span)
|
||||||
{
|
{
|
||||||
Checksum(ptr, packet.Length);
|
Checksum(ptr, packet.Length, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 计算IP包的校验和
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="packet">一个完整的IP包</param>
|
||||||
|
/// <param name="payload">是否计算荷载协议校验和</param>
|
||||||
|
public static unsafe void Checksum(ReadOnlySpan<byte> packet, bool payload = true)
|
||||||
|
{
|
||||||
|
fixed (byte* ptr = packet)
|
||||||
|
{
|
||||||
|
Checksum(ptr, packet.Length, payload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -22,38 +35,41 @@ namespace linker.libs
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="ptr">IP包指针</param>
|
/// <param name="ptr">IP包指针</param>
|
||||||
/// <param name="length">IP包长度</param>
|
/// <param name="length">IP包长度</param>
|
||||||
public static unsafe void Checksum(byte* ptr, int length)
|
/// <param name="payload">是否计算荷载协议校验和</param>
|
||||||
|
public static unsafe void Checksum(byte* ptr, int length, bool payload = true)
|
||||||
{
|
{
|
||||||
byte ipHeaderLength = (byte)((*ptr & 0b1111) * 4);
|
byte ipHeaderLength = (byte)((*ptr & 0b1111) * 4);
|
||||||
//重新计算IP头校验和
|
//重新计算IP头校验和
|
||||||
*(ushort*)(ptr + 10) = 0;
|
*(ushort*)(ptr + 10) = 0;
|
||||||
*(ushort*)(ptr + 10) = Checksum((ushort*)ptr, ipHeaderLength);
|
*(ushort*)(ptr + 10) = Checksum((ushort*)ptr, ipHeaderLength);
|
||||||
|
|
||||||
ProtocolType protocol = (ProtocolType)(*(ptr + 9));
|
if (payload)
|
||||||
switch (protocol)
|
|
||||||
{
|
{
|
||||||
case ProtocolType.Tcp:
|
ProtocolType protocol = (ProtocolType)(*(ptr + 9));
|
||||||
{
|
switch (protocol)
|
||||||
*(ushort*)(ptr + ipHeaderLength + 16) = 0;
|
{
|
||||||
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
|
case ProtocolType.Tcp:
|
||||||
*(ushort*)(ptr + ipHeaderLength + 16) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
|
{
|
||||||
}
|
*(ushort*)(ptr + ipHeaderLength + 16) = 0;
|
||||||
break;
|
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
|
||||||
case ProtocolType.Udp:
|
*(ushort*)(ptr + ipHeaderLength + 16) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
|
||||||
{
|
}
|
||||||
*(ushort*)(ptr + ipHeaderLength + 6) = 0;
|
break;
|
||||||
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
|
case ProtocolType.Udp:
|
||||||
*(ushort*)(ptr + ipHeaderLength + 6) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
|
{
|
||||||
}
|
*(ushort*)(ptr + ipHeaderLength + 6) = 0;
|
||||||
break;
|
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
|
||||||
case ProtocolType.Icmp:
|
*(ushort*)(ptr + ipHeaderLength + 6) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
|
||||||
{
|
}
|
||||||
*(ushort*)(ptr + ipHeaderLength + 2) = 0;
|
break;
|
||||||
*(ushort*)(ptr + ipHeaderLength + 2) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength);
|
case ProtocolType.Icmp:
|
||||||
}
|
{
|
||||||
break;
|
*(ushort*)(ptr + ipHeaderLength + 2) = 0;
|
||||||
|
*(ushort*)(ptr + ipHeaderLength + 2) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@@ -6,18 +6,26 @@ namespace linker.libs.extends
|
|||||||
{
|
{
|
||||||
public static class IPEndPointExtends
|
public static class IPEndPointExtends
|
||||||
{
|
{
|
||||||
public static bool GetIsBroadcastAddress(this IPAddress address)
|
public static bool IsCast(this IPAddress address)
|
||||||
{
|
{
|
||||||
return new ReadOnlySpan<byte>(address.GetAddressBytes()).GetIsBroadcastAddress();
|
return new ReadOnlySpan<byte>(address.GetAddressBytes()).IsCast();
|
||||||
}
|
}
|
||||||
public static bool GetIsBroadcastAddress(this ReadOnlyMemory<byte> address)
|
public static bool IsCast(this ReadOnlyMemory<byte> address)
|
||||||
{
|
{
|
||||||
return address.Span.GetIsBroadcastAddress();
|
return address.Span.IsCast();
|
||||||
}
|
}
|
||||||
public static bool GetIsBroadcastAddress(this ReadOnlySpan<byte> address)
|
public static bool IsCast(this ReadOnlySpan<byte> address)
|
||||||
{
|
{
|
||||||
uint ip = BinaryPrimitives.ReadUInt32BigEndian(address);
|
return address.IsBroadcast() || address.IsMulticast();
|
||||||
return address[3] == 255 || (ip >= 0xE0000000 && ip <= 0xEFFFFFFF) || ip == 0xFFFFFFFF;
|
}
|
||||||
|
|
||||||
|
public static bool IsBroadcast(this ReadOnlySpan<byte> address)
|
||||||
|
{
|
||||||
|
return address[3] == 255 || BinaryPrimitives.ReadUInt32BigEndian(address) == 0xFFFFFFFF;
|
||||||
|
}
|
||||||
|
public static bool IsMulticast(this ReadOnlySpan<byte> address)
|
||||||
|
{
|
||||||
|
return address[0] >= 0xE0 && address[0] <= 0xEF;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -53,6 +53,7 @@ namespace linker.messenger.tuntap
|
|||||||
/// 调整网卡顺序
|
/// 调整网卡顺序
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool InterfaceOrder => Switch.HasFlag(TuntapSwitch.InterfaceOrder);
|
public bool InterfaceOrder => Switch.HasFlag(TuntapSwitch.InterfaceOrder);
|
||||||
|
public bool Multicast => Switch.HasFlag(TuntapSwitch.Multicast);
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class TuntapGroup2IPInfo
|
public sealed class TuntapGroup2IPInfo
|
||||||
|
@@ -81,9 +81,9 @@ namespace linker.messenger.tuntap
|
|||||||
public async Task InputPacket(LinkerTunDevicPacket packet)
|
public async Task InputPacket(LinkerTunDevicPacket packet)
|
||||||
{
|
{
|
||||||
//IPV4广播组播、IPV6 多播
|
//IPV4广播组播、IPV6 多播
|
||||||
if (packet.IPV4Broadcast || packet.IPV6Multicast)
|
if ((packet.IPV4Broadcast || packet.IPV6Multicast) && tuntapConfigTransfer.Info.Multicast == false && connections.IsEmpty == false)
|
||||||
{
|
{
|
||||||
if (tuntapConfigTransfer.Info.Switch.HasFlag(TuntapSwitch.Multicast) == false && connections.IsEmpty == false)
|
if (packet.DecrementTtl())
|
||||||
{
|
{
|
||||||
await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Buffer, packet.Offset, packet.Length)));
|
await Task.WhenAll(connections.Values.Where(c => c != null && c.Connected).Select(c => c.SendAsync(packet.Buffer, packet.Offset, packet.Length)));
|
||||||
}
|
}
|
||||||
|
@@ -195,7 +195,7 @@ namespace linker.snat
|
|||||||
|
|
||||||
IPV4Packet ipv4 = new IPV4Packet(packet.Span);
|
IPV4Packet ipv4 = new IPV4Packet(packet.Span);
|
||||||
//不是 ipv4,是虚拟网卡ip,是广播,不nat
|
//不是 ipv4,是虚拟网卡ip,是广播,不nat
|
||||||
if (ipv4.Version != 4 || ipv4.DstAddr == srcIp || ipv4.DstAddrSpan.GetIsBroadcastAddress())
|
if (ipv4.Version != 4 || ipv4.DstAddr == srcIp || ipv4.DstAddrSpan.IsCast())
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -120,7 +120,7 @@ namespace linker.tun
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// MTU
|
/// MTU
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Mtu { get; set; } = 1420;
|
public int Mtu { get; set; } = 1420;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -231,6 +231,9 @@ namespace linker.tun
|
|||||||
/// 协议版本,4或者6
|
/// 协议版本,4或者6
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public byte Version { get; private set; }
|
public byte Version { get; private set; }
|
||||||
|
|
||||||
|
public byte TTL { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 协议
|
/// 协议
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -262,7 +265,7 @@ namespace linker.tun
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public IPEndPoint Dist => new IPEndPoint(new IPAddress(DistIPAddress.Span), DistPort);
|
public IPEndPoint Dist => new IPEndPoint(new IPAddress(DistIPAddress.Span), DistPort);
|
||||||
|
|
||||||
public bool IPV4Broadcast => Version == 4 && DistIPAddress.GetIsBroadcastAddress();
|
public bool IPV4Broadcast => Version == 4 && DistIPAddress.IsCast();
|
||||||
public bool IPV6Multicast => Version == 6 && (DistIPAddress.Span[0] & 0xFF) == 0xFF;
|
public bool IPV6Multicast => Version == 6 && (DistIPAddress.Span[0] & 0xFF) == 0xFF;
|
||||||
|
|
||||||
public LinkerTunDevicPacket()
|
public LinkerTunDevicPacket()
|
||||||
@@ -278,8 +281,7 @@ namespace linker.tun
|
|||||||
Offset = offset;
|
Offset = offset;
|
||||||
Length = length;
|
Length = length;
|
||||||
|
|
||||||
ReadOnlyMemory<byte> packet = buffer;
|
ReadOnlyMemory<byte> ipPacket = Buffer.AsMemory(Offset + 4);
|
||||||
ReadOnlyMemory<byte> ipPacket = packet.Slice(4);
|
|
||||||
Version = (byte)(ipPacket.Span[0] >> 4 & 0b1111);
|
Version = (byte)(ipPacket.Span[0] >> 4 & 0b1111);
|
||||||
|
|
||||||
SourceIPAddress = Helper.EmptyArray;
|
SourceIPAddress = Helper.EmptyArray;
|
||||||
@@ -291,6 +293,8 @@ namespace linker.tun
|
|||||||
DistIPAddress = ipPacket.Slice(16, 4);
|
DistIPAddress = ipPacket.Slice(16, 4);
|
||||||
|
|
||||||
ProtocolType = (ProtocolType)ipPacket.Span[9];
|
ProtocolType = (ProtocolType)ipPacket.Span[9];
|
||||||
|
TTL = ipPacket.Span[8];
|
||||||
|
|
||||||
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
|
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
|
||||||
{
|
{
|
||||||
SourcePort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(20, 2).ToUInt16());
|
SourcePort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(20, 2).ToUInt16());
|
||||||
@@ -303,6 +307,7 @@ namespace linker.tun
|
|||||||
DistIPAddress = ipPacket.Slice(24, 16);
|
DistIPAddress = ipPacket.Slice(24, 16);
|
||||||
|
|
||||||
ProtocolType = (ProtocolType)ipPacket.Span[6];
|
ProtocolType = (ProtocolType)ipPacket.Span[6];
|
||||||
|
TTL = ipPacket.Span[7];
|
||||||
|
|
||||||
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
|
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
|
||||||
{
|
{
|
||||||
@@ -311,6 +316,20 @@ namespace linker.tun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool DecrementTtl()
|
||||||
|
{
|
||||||
|
if (TTL <= 0) return false;
|
||||||
|
|
||||||
|
Span<byte> ipPacket = Buffer.AsSpan(Offset + 4);
|
||||||
|
if (Version == 4) TTL = --ipPacket[8];
|
||||||
|
else if (Version == 6) TTL = --ipPacket[7];
|
||||||
|
ChecksumHelper.Checksum(ipPacket, false);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
public struct LinkerTunDevicValidatePacket
|
public struct LinkerTunDevicValidatePacket
|
||||||
{
|
{
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
v1.9.0
|
v1.9.0
|
||||||
2025-08-01 17:52:13
|
2025-08-05 17:16:29
|
||||||
1. 一些累计更新
|
1. 一些累计更新
|
||||||
2. 修复一些APP问题
|
2. 修复一些APP问题
|
||||||
3. 增加一些数据统计
|
3. 增加一些数据统计
|
||||||
|
Reference in New Issue
Block a user