广播组播强制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
title: 1、首页
---
# 1、首页

View File

@@ -10,11 +10,24 @@ namespace linker.libs
/// 计算IP包的校验和
/// </summary>
/// <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)
{
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>
@@ -22,38 +35,41 @@ namespace linker.libs
/// </summary>
/// <param name="ptr">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);
//重新计算IP头校验和
*(ushort*)(ptr + 10) = 0;
*(ushort*)(ptr + 10) = Checksum((ushort*)ptr, ipHeaderLength);
ProtocolType protocol = (ProtocolType)(*(ptr + 9));
switch (protocol)
if (payload)
{
case ProtocolType.Tcp:
{
*(ushort*)(ptr + ipHeaderLength + 16) = 0;
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
*(ushort*)(ptr + ipHeaderLength + 16) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
}
break;
case ProtocolType.Udp:
{
*(ushort*)(ptr + ipHeaderLength + 6) = 0;
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
*(ushort*)(ptr + ipHeaderLength + 6) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
}
break;
case ProtocolType.Icmp:
{
*(ushort*)(ptr + ipHeaderLength + 2) = 0;
*(ushort*)(ptr + ipHeaderLength + 2) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength);
}
break;
ProtocolType protocol = (ProtocolType)(*(ptr + 9));
switch (protocol)
{
case ProtocolType.Tcp:
{
*(ushort*)(ptr + ipHeaderLength + 16) = 0;
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
*(ushort*)(ptr + ipHeaderLength + 16) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
}
break;
case ProtocolType.Udp:
{
*(ushort*)(ptr + ipHeaderLength + 6) = 0;
ulong sum = PseudoHeaderSum(ptr, (uint)(length - ipHeaderLength));
*(ushort*)(ptr + ipHeaderLength + 6) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength, sum);
}
break;
case ProtocolType.Icmp:
{
*(ushort*)(ptr + ipHeaderLength + 2) = 0;
*(ushort*)(ptr + ipHeaderLength + 2) = Checksum((ushort*)(ptr + ipHeaderLength), (uint)length - ipHeaderLength);
}
break;
}
}
}
/// <summary>

View File

@@ -6,18 +6,26 @@ namespace linker.libs.extends
{
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[3] == 255 || (ip >= 0xE0000000 && ip <= 0xEFFFFFFF) || ip == 0xFFFFFFFF;
return address.IsBroadcast() || address.IsMulticast();
}
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>
public bool InterfaceOrder => Switch.HasFlag(TuntapSwitch.InterfaceOrder);
public bool Multicast => Switch.HasFlag(TuntapSwitch.Multicast);
}
public sealed class TuntapGroup2IPInfo

View File

@@ -81,9 +81,9 @@ namespace linker.messenger.tuntap
public async Task InputPacket(LinkerTunDevicPacket packet)
{
//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)));
}

View File

@@ -195,7 +195,7 @@ namespace linker.snat
IPV4Packet ipv4 = new IPV4Packet(packet.Span);
//不是 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;
}

View File

@@ -120,7 +120,7 @@ namespace linker.tun
/// <summary>
/// MTU
/// </summary>
public int Mtu { get; set; } = 1420;
public int Mtu { get; set; } = 1420;
}
/// <summary>
@@ -231,6 +231,9 @@ namespace linker.tun
/// 协议版本4或者6
/// </summary>
public byte Version { get; private set; }
public byte TTL { get; private set; }
/// <summary>
/// 协议
/// </summary>
@@ -262,7 +265,7 @@ namespace linker.tun
/// </summary>
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 LinkerTunDevicPacket()
@@ -278,8 +281,7 @@ namespace linker.tun
Offset = offset;
Length = length;
ReadOnlyMemory<byte> packet = buffer;
ReadOnlyMemory<byte> ipPacket = packet.Slice(4);
ReadOnlyMemory<byte> ipPacket = Buffer.AsMemory(Offset + 4);
Version = (byte)(ipPacket.Span[0] >> 4 & 0b1111);
SourceIPAddress = Helper.EmptyArray;
@@ -291,6 +293,8 @@ namespace linker.tun
DistIPAddress = ipPacket.Slice(16, 4);
ProtocolType = (ProtocolType)ipPacket.Span[9];
TTL = ipPacket.Span[8];
if (ProtocolType == ProtocolType.Tcp || ProtocolType == ProtocolType.Udp)
{
SourcePort = BinaryPrimitives.ReverseEndianness(ipPacket.Slice(20, 2).ToUInt16());
@@ -303,6 +307,7 @@ namespace linker.tun
DistIPAddress = ipPacket.Slice(24, 16);
ProtocolType = (ProtocolType)ipPacket.Span[6];
TTL = ipPacket.Span[7];
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
{

View File

@@ -1,5 +1,5 @@
v1.9.0
2025-08-01 17:52:13
2025-08-05 17:16:29
1. 一些累计更新
2. 修复一些APP问题
3. 增加一些数据统计