mirror of
https://github.com/Kaveinator/NetickProForUnity.git
synced 2025-10-27 02:09:06 -07:00
auto
This commit is contained in:
301
Transport/LiteNetLib Transport/LiteNetLib/NativeSocket.cs
Normal file
301
Transport/LiteNetLib Transport/LiteNetLib/NativeSocket.cs
Normal file
@@ -0,0 +1,301 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LiteNetLib
|
||||
{
|
||||
internal readonly struct NativeAddr : IEquatable<NativeAddr>
|
||||
{
|
||||
//common parts
|
||||
private readonly long _part1; //family, port, etc
|
||||
private readonly long _part2;
|
||||
//ipv6 parts
|
||||
private readonly long _part3;
|
||||
private readonly int _part4;
|
||||
|
||||
private readonly int _hash;
|
||||
|
||||
public NativeAddr(byte[] address, int len)
|
||||
{
|
||||
_part1 = BitConverter.ToInt64(address, 0);
|
||||
_part2 = BitConverter.ToInt64(address, 8);
|
||||
if (len > 16)
|
||||
{
|
||||
_part3 = BitConverter.ToInt64(address, 16);
|
||||
_part4 = BitConverter.ToInt32(address, 24);
|
||||
}
|
||||
else
|
||||
{
|
||||
_part3 = 0;
|
||||
_part4 = 0;
|
||||
}
|
||||
_hash = (int)(_part1 >> 32) ^ (int)_part1 ^
|
||||
(int)(_part2 >> 32) ^ (int)_part2 ^
|
||||
(int)(_part3 >> 32) ^ (int)_part3 ^
|
||||
_part4;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return _hash;
|
||||
}
|
||||
|
||||
public bool Equals(NativeAddr other)
|
||||
{
|
||||
return _part1 == other._part1 &&
|
||||
_part2 == other._part2 &&
|
||||
_part3 == other._part3 &&
|
||||
_part4 == other._part4;
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is NativeAddr other && Equals(other);
|
||||
}
|
||||
|
||||
public static bool operator ==(NativeAddr left, NativeAddr right)
|
||||
{
|
||||
return left.Equals(right);
|
||||
}
|
||||
|
||||
public static bool operator !=(NativeAddr left, NativeAddr right)
|
||||
{
|
||||
return !left.Equals(right);
|
||||
}
|
||||
}
|
||||
|
||||
internal class NativeEndPoint : IPEndPoint
|
||||
{
|
||||
public readonly byte[] NativeAddress;
|
||||
|
||||
public NativeEndPoint(byte[] address) : base(IPAddress.Any, 0)
|
||||
{
|
||||
NativeAddress = new byte[address.Length];
|
||||
Buffer.BlockCopy(address, 0, NativeAddress, 0, address.Length);
|
||||
|
||||
short family = (short)((address[1] << 8) | address[0]);
|
||||
Port =(ushort)((address[2] << 8) | address[3]);
|
||||
|
||||
if ((NativeSocket.UnixMode && family == NativeSocket.AF_INET6) || (!NativeSocket.UnixMode && (AddressFamily)family == AddressFamily.InterNetworkV6))
|
||||
{
|
||||
uint scope = unchecked((uint)(
|
||||
(address[27] << 24) +
|
||||
(address[26] << 16) +
|
||||
(address[25] << 8) +
|
||||
(address[24])));
|
||||
#if NETCOREAPP || NETSTANDARD2_1 || NETSTANDARD2_1_OR_GREATER
|
||||
Address = new IPAddress(new ReadOnlySpan<byte>(address, 8, 16), scope);
|
||||
#else
|
||||
byte[] addrBuffer = new byte[16];
|
||||
Buffer.BlockCopy(address, 8, addrBuffer, 0, 16);
|
||||
Address = new IPAddress(addrBuffer, scope);
|
||||
#endif
|
||||
}
|
||||
else //IPv4
|
||||
{
|
||||
long ipv4Addr = unchecked((uint)((address[4] & 0x000000FF) |
|
||||
(address[5] << 8 & 0x0000FF00) |
|
||||
(address[6] << 16 & 0x00FF0000) |
|
||||
(address[7] << 24)));
|
||||
Address = new IPAddress(ipv4Addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static class NativeSocket
|
||||
{
|
||||
static
|
||||
#if LITENETLIB_UNSAFE
|
||||
unsafe
|
||||
#endif
|
||||
class WinSock
|
||||
{
|
||||
private const string LibName = "ws2_32.dll";
|
||||
|
||||
[DllImport(LibName, SetLastError = true)]
|
||||
public static extern int recvfrom(
|
||||
IntPtr socketHandle,
|
||||
[In, Out] byte[] pinnedBuffer,
|
||||
[In] int len,
|
||||
[In] SocketFlags socketFlags,
|
||||
[Out] byte[] socketAddress,
|
||||
[In, Out] ref int socketAddressSize);
|
||||
|
||||
[DllImport(LibName, SetLastError = true)]
|
||||
internal static extern int sendto(
|
||||
IntPtr socketHandle,
|
||||
#if LITENETLIB_UNSAFE
|
||||
byte* pinnedBuffer,
|
||||
#else
|
||||
[In] byte[] pinnedBuffer,
|
||||
#endif
|
||||
[In] int len,
|
||||
[In] SocketFlags socketFlags,
|
||||
[In] byte[] socketAddress,
|
||||
[In] int socketAddressSize);
|
||||
}
|
||||
|
||||
static
|
||||
#if LITENETLIB_UNSAFE
|
||||
unsafe
|
||||
#endif
|
||||
class UnixSock
|
||||
{
|
||||
private const string LibName = "libc";
|
||||
|
||||
[DllImport(LibName, SetLastError = true)]
|
||||
public static extern int recvfrom(
|
||||
IntPtr socketHandle,
|
||||
[In, Out] byte[] pinnedBuffer,
|
||||
[In] int len,
|
||||
[In] SocketFlags socketFlags,
|
||||
[Out] byte[] socketAddress,
|
||||
[In, Out] ref int socketAddressSize);
|
||||
|
||||
[DllImport(LibName, SetLastError = true)]
|
||||
internal static extern int sendto(
|
||||
IntPtr socketHandle,
|
||||
#if LITENETLIB_UNSAFE
|
||||
byte* pinnedBuffer,
|
||||
#else
|
||||
[In] byte[] pinnedBuffer,
|
||||
#endif
|
||||
[In] int len,
|
||||
[In] SocketFlags socketFlags,
|
||||
[In] byte[] socketAddress,
|
||||
[In] int socketAddressSize);
|
||||
}
|
||||
|
||||
public static readonly bool IsSupported = false;
|
||||
public static readonly bool UnixMode = false;
|
||||
|
||||
public const int IPv4AddrSize = 16;
|
||||
public const int IPv6AddrSize = 28;
|
||||
public const int AF_INET = 2;
|
||||
public const int AF_INET6 = 10;
|
||||
|
||||
private static readonly Dictionary<int, SocketError> NativeErrorToSocketError = new Dictionary<int, SocketError>
|
||||
{
|
||||
{ 13, SocketError.AccessDenied }, //EACCES
|
||||
{ 98, SocketError.AddressAlreadyInUse }, //EADDRINUSE
|
||||
{ 99, SocketError.AddressNotAvailable }, //EADDRNOTAVAIL
|
||||
{ 97, SocketError.AddressFamilyNotSupported }, //EAFNOSUPPORT
|
||||
{ 11, SocketError.WouldBlock }, //EAGAIN
|
||||
{ 114, SocketError.AlreadyInProgress }, //EALREADY
|
||||
{ 9, SocketError.OperationAborted }, //EBADF
|
||||
{ 125, SocketError.OperationAborted }, //ECANCELED
|
||||
{ 103, SocketError.ConnectionAborted }, //ECONNABORTED
|
||||
{ 111, SocketError.ConnectionRefused }, //ECONNREFUSED
|
||||
{ 104, SocketError.ConnectionReset }, //ECONNRESET
|
||||
{ 89, SocketError.DestinationAddressRequired }, //EDESTADDRREQ
|
||||
{ 14, SocketError.Fault }, //EFAULT
|
||||
{ 112, SocketError.HostDown }, //EHOSTDOWN
|
||||
{ 6, SocketError.HostNotFound }, //ENXIO
|
||||
{ 113, SocketError.HostUnreachable }, //EHOSTUNREACH
|
||||
{ 115, SocketError.InProgress }, //EINPROGRESS
|
||||
{ 4, SocketError.Interrupted }, //EINTR
|
||||
{ 22, SocketError.InvalidArgument }, //EINVAL
|
||||
{ 106, SocketError.IsConnected }, //EISCONN
|
||||
{ 24, SocketError.TooManyOpenSockets }, //EMFILE
|
||||
{ 90, SocketError.MessageSize }, //EMSGSIZE
|
||||
{ 100, SocketError.NetworkDown }, //ENETDOWN
|
||||
{ 102, SocketError.NetworkReset }, //ENETRESET
|
||||
{ 101, SocketError.NetworkUnreachable }, //ENETUNREACH
|
||||
{ 23, SocketError.TooManyOpenSockets }, //ENFILE
|
||||
{ 105, SocketError.NoBufferSpaceAvailable }, //ENOBUFS
|
||||
{ 61, SocketError.NoData }, //ENODATA
|
||||
{ 2, SocketError.AddressNotAvailable }, //ENOENT
|
||||
{ 92, SocketError.ProtocolOption }, //ENOPROTOOPT
|
||||
{ 107, SocketError.NotConnected }, //ENOTCONN
|
||||
{ 88, SocketError.NotSocket }, //ENOTSOCK
|
||||
{ 3440, SocketError.OperationNotSupported }, //ENOTSUP
|
||||
{ 1, SocketError.AccessDenied }, //EPERM
|
||||
{ 32, SocketError.Shutdown }, //EPIPE
|
||||
{ 96, SocketError.ProtocolFamilyNotSupported }, //EPFNOSUPPORT
|
||||
{ 93, SocketError.ProtocolNotSupported }, //EPROTONOSUPPORT
|
||||
{ 91, SocketError.ProtocolType }, //EPROTOTYPE
|
||||
{ 94, SocketError.SocketNotSupported }, //ESOCKTNOSUPPORT
|
||||
{ 108, SocketError.Disconnecting }, //ESHUTDOWN
|
||||
{ 110, SocketError.TimedOut }, //ETIMEDOUT
|
||||
{ 0, SocketError.Success }
|
||||
};
|
||||
|
||||
static NativeSocket()
|
||||
{
|
||||
if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
|
||||
{
|
||||
IsSupported = true;
|
||||
UnixMode = true;
|
||||
}
|
||||
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
IsSupported = true;
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static int RecvFrom(
|
||||
IntPtr socketHandle,
|
||||
byte[] pinnedBuffer,
|
||||
int len,
|
||||
byte[] socketAddress,
|
||||
ref int socketAddressSize)
|
||||
{
|
||||
return UnixMode
|
||||
? UnixSock.recvfrom(socketHandle, pinnedBuffer, len, 0, socketAddress, ref socketAddressSize)
|
||||
: WinSock.recvfrom(socketHandle, pinnedBuffer, len, 0, socketAddress, ref socketAddressSize);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public
|
||||
#if LITENETLIB_UNSAFE
|
||||
unsafe
|
||||
#endif
|
||||
static int SendTo(
|
||||
IntPtr socketHandle,
|
||||
#if LITENETLIB_UNSAFE
|
||||
byte* pinnedBuffer,
|
||||
#else
|
||||
byte[] pinnedBuffer,
|
||||
#endif
|
||||
int len,
|
||||
byte[] socketAddress,
|
||||
int socketAddressSize)
|
||||
{
|
||||
return UnixMode
|
||||
? UnixSock.sendto(socketHandle, pinnedBuffer, len, 0, socketAddress, socketAddressSize)
|
||||
: WinSock.sendto(socketHandle, pinnedBuffer, len, 0, socketAddress, socketAddressSize);
|
||||
}
|
||||
|
||||
public static SocketError GetSocketError()
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
if (UnixMode)
|
||||
return NativeErrorToSocketError.TryGetValue(error, out var err)
|
||||
? err
|
||||
: SocketError.SocketError;
|
||||
return (SocketError)error;
|
||||
}
|
||||
|
||||
public static SocketException GetSocketException()
|
||||
{
|
||||
int error = Marshal.GetLastWin32Error();
|
||||
if (UnixMode)
|
||||
return NativeErrorToSocketError.TryGetValue(error, out var err)
|
||||
? new SocketException((int)err)
|
||||
: new SocketException((int)SocketError.SocketError);
|
||||
return new SocketException(error);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static short GetNativeAddressFamily(IPEndPoint remoteEndPoint)
|
||||
{
|
||||
return UnixMode
|
||||
? (short)(remoteEndPoint.AddressFamily == AddressFamily.InterNetwork ? AF_INET : AF_INET6)
|
||||
: (short)remoteEndPoint.AddressFamily;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user