Common.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. using System;
  2. using System.Net;
  3. using System.Net.Sockets;
  4. using System.Security.Cryptography;
  5. namespace kcp2k
  6. {
  7. public static class Common
  8. {
  9. // helper function to resolve host to IPAddress
  10. public static bool ResolveHostname(string hostname, out IPAddress[] addresses)
  11. {
  12. try
  13. {
  14. // NOTE: dns lookup is blocking. this can take a second.
  15. addresses = Dns.GetHostAddresses(hostname);
  16. return addresses.Length >= 1;
  17. }
  18. catch (SocketException exception)
  19. {
  20. Log.Info($"Failed to resolve host: {hostname} reason: {exception}");
  21. addresses = null;
  22. return false;
  23. }
  24. }
  25. // if connections drop under heavy load, increase to OS limit.
  26. // if still not enough, increase the OS limit.
  27. public static void ConfigureSocketBuffers(Socket socket, int recvBufferSize, int sendBufferSize)
  28. {
  29. // log initial size for comparison.
  30. // remember initial size for log comparison
  31. int initialReceive = socket.ReceiveBufferSize;
  32. int initialSend = socket.SendBufferSize;
  33. // set to configured size
  34. try
  35. {
  36. socket.ReceiveBufferSize = recvBufferSize;
  37. socket.SendBufferSize = sendBufferSize;
  38. }
  39. catch (SocketException)
  40. {
  41. Log.Warning($"Kcp: failed to set Socket RecvBufSize = {recvBufferSize} SendBufSize = {sendBufferSize}");
  42. }
  43. Log.Info($"Kcp: RecvBuf = {initialReceive}=>{socket.ReceiveBufferSize} ({socket.ReceiveBufferSize/initialReceive}x) SendBuf = {initialSend}=>{socket.SendBufferSize} ({socket.SendBufferSize/initialSend}x)");
  44. }
  45. // generate a connection hash from IP+Port.
  46. //
  47. // NOTE: IPEndPoint.GetHashCode() allocates.
  48. // it calls m_Address.GetHashCode().
  49. // m_Address is an IPAddress.
  50. // GetHashCode() allocates for IPv6:
  51. // https://github.com/mono/mono/blob/bdd772531d379b4e78593587d15113c37edd4a64/mcs/class/referencesource/System/net/System/Net/IPAddress.cs#L699
  52. //
  53. // => using only newClientEP.Port wouldn't work, because
  54. // different connections can have the same port.
  55. public static int ConnectionHash(EndPoint endPoint) =>
  56. endPoint.GetHashCode();
  57. // cookies need to be generated with a secure random generator.
  58. // we don't want them to be deterministic / predictable.
  59. // RNG is cached to avoid runtime allocations.
  60. static readonly RNGCryptoServiceProvider cryptoRandom = new RNGCryptoServiceProvider();
  61. static readonly byte[] cryptoRandomBuffer = new byte[4];
  62. public static uint GenerateCookie()
  63. {
  64. cryptoRandom.GetBytes(cryptoRandomBuffer);
  65. return BitConverter.ToUInt32(cryptoRandomBuffer, 0);
  66. }
  67. }
  68. }