广播组播强制TLL-1

This commit is contained in:
snltty
2025-08-05 17:16:29 +08:00
parent f029baf16a
commit e641f842f2
8 changed files with 86 additions and 41 deletions

View File

@@ -1,5 +1,6 @@
--- ---
sidebar_position: 1 sidebar_position: 1
title: 1、首页
--- ---
# 1、首页 # 1、首页

View File

@@ -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>

View File

@@ -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;
} }
} }
} }

View File

@@ -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

View File

@@ -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)));
} }

View File

@@ -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;
} }

View File

@@ -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
{ {

View File

@@ -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. 增加一些数据统计