76 lines
3.0 KiB
C#
76 lines
3.0 KiB
C#
using System;
|
|
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace kcp2k
|
|
{
|
|
public static class Common
|
|
{
|
|
// helper function to resolve host to IPAddress
|
|
public static bool ResolveHostname(string hostname, out IPAddress[] addresses)
|
|
{
|
|
try
|
|
{
|
|
// NOTE: dns lookup is blocking. this can take a second.
|
|
addresses = Dns.GetHostAddresses(hostname);
|
|
return addresses.Length >= 1;
|
|
}
|
|
catch (SocketException exception)
|
|
{
|
|
Log.Info($"[KCP] Failed to resolve host: {hostname} reason: {exception}");
|
|
addresses = null;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// if connections drop under heavy load, increase to OS limit.
|
|
// if still not enough, increase the OS limit.
|
|
public static void ConfigureSocketBuffers(Socket socket, int recvBufferSize, int sendBufferSize)
|
|
{
|
|
// log initial size for comparison.
|
|
// remember initial size for log comparison
|
|
int initialReceive = socket.ReceiveBufferSize;
|
|
int initialSend = socket.SendBufferSize;
|
|
|
|
// set to configured size
|
|
try
|
|
{
|
|
socket.ReceiveBufferSize = recvBufferSize;
|
|
socket.SendBufferSize = sendBufferSize;
|
|
}
|
|
catch (SocketException)
|
|
{
|
|
Log.Warning($"[KCP] failed to set Socket RecvBufSize = {recvBufferSize} SendBufSize = {sendBufferSize}");
|
|
}
|
|
|
|
|
|
Log.Info($"[KCP] RecvBuf = {initialReceive}=>{socket.ReceiveBufferSize} ({socket.ReceiveBufferSize/initialReceive}x) SendBuf = {initialSend}=>{socket.SendBufferSize} ({socket.SendBufferSize/initialSend}x)");
|
|
}
|
|
|
|
// generate a connection hash from IP+Port.
|
|
//
|
|
// NOTE: IPEndPoint.GetHashCode() allocates.
|
|
// it calls m_Address.GetHashCode().
|
|
// m_Address is an IPAddress.
|
|
// GetHashCode() allocates for IPv6:
|
|
// https://github.com/mono/mono/blob/bdd772531d379b4e78593587d15113c37edd4a64/mcs/class/referencesource/System/net/System/Net/IPAddress.cs#L699
|
|
//
|
|
// => using only newClientEP.Port wouldn't work, because
|
|
// different connections can have the same port.
|
|
public static int ConnectionHash(EndPoint endPoint) =>
|
|
endPoint.GetHashCode();
|
|
|
|
// cookies need to be generated with a secure random generator.
|
|
// we don't want them to be deterministic / predictable.
|
|
// RNG is cached to avoid runtime allocations.
|
|
static readonly RNGCryptoServiceProvider cryptoRandom = new RNGCryptoServiceProvider();
|
|
static readonly byte[] cryptoRandomBuffer = new byte[4];
|
|
public static uint GenerateCookie()
|
|
{
|
|
cryptoRandom.GetBytes(cryptoRandomBuffer);
|
|
return BitConverter.ToUInt32(cryptoRandomBuffer, 0);
|
|
}
|
|
}
|
|
}
|