WinSockHelper.cs 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. using System.Collections.Generic;
  2. using System.Net.Sockets;
  3. namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
  4. {
  5. static class WinSockHelper
  6. {
  7. private static readonly Dictionary<WsaError, LinuxError> _errorMap = new()
  8. {
  9. // WSAEINTR
  10. {WsaError.WSAEINTR, LinuxError.EINTR},
  11. // WSAEWOULDBLOCK
  12. {WsaError.WSAEWOULDBLOCK, LinuxError.EWOULDBLOCK},
  13. // WSAEINPROGRESS
  14. {WsaError.WSAEINPROGRESS, LinuxError.EINPROGRESS},
  15. // WSAEALREADY
  16. {WsaError.WSAEALREADY, LinuxError.EALREADY},
  17. // WSAENOTSOCK
  18. {WsaError.WSAENOTSOCK, LinuxError.ENOTSOCK},
  19. // WSAEDESTADDRREQ
  20. {WsaError.WSAEDESTADDRREQ, LinuxError.EDESTADDRREQ},
  21. // WSAEMSGSIZE
  22. {WsaError.WSAEMSGSIZE, LinuxError.EMSGSIZE},
  23. // WSAEPROTOTYPE
  24. {WsaError.WSAEPROTOTYPE, LinuxError.EPROTOTYPE},
  25. // WSAENOPROTOOPT
  26. {WsaError.WSAENOPROTOOPT, LinuxError.ENOPROTOOPT},
  27. // WSAEPROTONOSUPPORT
  28. {WsaError.WSAEPROTONOSUPPORT, LinuxError.EPROTONOSUPPORT},
  29. // WSAESOCKTNOSUPPORT
  30. {WsaError.WSAESOCKTNOSUPPORT, LinuxError.ESOCKTNOSUPPORT},
  31. // WSAEOPNOTSUPP
  32. {WsaError.WSAEOPNOTSUPP, LinuxError.EOPNOTSUPP},
  33. // WSAEPFNOSUPPORT
  34. {WsaError.WSAEPFNOSUPPORT, LinuxError.EPFNOSUPPORT},
  35. // WSAEAFNOSUPPORT
  36. {WsaError.WSAEAFNOSUPPORT, LinuxError.EAFNOSUPPORT},
  37. // WSAEADDRINUSE
  38. {WsaError.WSAEADDRINUSE, LinuxError.EADDRINUSE},
  39. // WSAEADDRNOTAVAIL
  40. {WsaError.WSAEADDRNOTAVAIL, LinuxError.EADDRNOTAVAIL},
  41. // WSAENETDOWN
  42. {WsaError.WSAENETDOWN, LinuxError.ENETDOWN},
  43. // WSAENETUNREACH
  44. {WsaError.WSAENETUNREACH, LinuxError.ENETUNREACH},
  45. // WSAENETRESET
  46. {WsaError.WSAENETRESET, LinuxError.ENETRESET},
  47. // WSAECONNABORTED
  48. {WsaError.WSAECONNABORTED, LinuxError.ECONNABORTED},
  49. // WSAECONNRESET
  50. {WsaError.WSAECONNRESET, LinuxError.ECONNRESET},
  51. // WSAENOBUFS
  52. {WsaError.WSAENOBUFS, LinuxError.ENOBUFS},
  53. // WSAEISCONN
  54. {WsaError.WSAEISCONN, LinuxError.EISCONN},
  55. // WSAENOTCONN
  56. {WsaError.WSAENOTCONN, LinuxError.ENOTCONN},
  57. // WSAESHUTDOWN
  58. {WsaError.WSAESHUTDOWN, LinuxError.ESHUTDOWN},
  59. // WSAETOOMANYREFS
  60. {WsaError.WSAETOOMANYREFS, LinuxError.ETOOMANYREFS},
  61. // WSAETIMEDOUT
  62. {WsaError.WSAETIMEDOUT, LinuxError.ETIMEDOUT},
  63. // WSAECONNREFUSED
  64. {WsaError.WSAECONNREFUSED, LinuxError.ECONNREFUSED},
  65. // WSAELOOP
  66. {WsaError.WSAELOOP, LinuxError.ELOOP},
  67. // WSAENAMETOOLONG
  68. {WsaError.WSAENAMETOOLONG, LinuxError.ENAMETOOLONG},
  69. // WSAEHOSTDOWN
  70. {WsaError.WSAEHOSTDOWN, LinuxError.EHOSTDOWN},
  71. // WSAEHOSTUNREACH
  72. {WsaError.WSAEHOSTUNREACH, LinuxError.EHOSTUNREACH},
  73. // WSAENOTEMPTY
  74. {WsaError.WSAENOTEMPTY, LinuxError.ENOTEMPTY},
  75. // WSAEUSERS
  76. {WsaError.WSAEUSERS, LinuxError.EUSERS},
  77. // WSAEDQUOT
  78. {WsaError.WSAEDQUOT, LinuxError.EDQUOT},
  79. // WSAESTALE
  80. {WsaError.WSAESTALE, LinuxError.ESTALE},
  81. // WSAEREMOTE
  82. {WsaError.WSAEREMOTE, LinuxError.EREMOTE},
  83. // WSAEINVAL
  84. {WsaError.WSAEINVAL, LinuxError.EINVAL},
  85. // WSAEFAULT
  86. {WsaError.WSAEFAULT, LinuxError.EFAULT},
  87. // NOERROR
  88. {0, 0}
  89. };
  90. private static readonly Dictionary<BsdSocketOption, SocketOptionName> _soSocketOptionMap = new()
  91. {
  92. { BsdSocketOption.SoDebug, SocketOptionName.Debug },
  93. { BsdSocketOption.SoReuseAddr, SocketOptionName.ReuseAddress },
  94. { BsdSocketOption.SoKeepAlive, SocketOptionName.KeepAlive },
  95. { BsdSocketOption.SoDontRoute, SocketOptionName.DontRoute },
  96. { BsdSocketOption.SoBroadcast, SocketOptionName.Broadcast },
  97. { BsdSocketOption.SoUseLoopBack, SocketOptionName.UseLoopback },
  98. { BsdSocketOption.SoLinger, SocketOptionName.Linger },
  99. { BsdSocketOption.SoOobInline, SocketOptionName.OutOfBandInline },
  100. { BsdSocketOption.SoReusePort, SocketOptionName.ReuseAddress },
  101. { BsdSocketOption.SoSndBuf, SocketOptionName.SendBuffer },
  102. { BsdSocketOption.SoRcvBuf, SocketOptionName.ReceiveBuffer },
  103. { BsdSocketOption.SoSndLoWat, SocketOptionName.SendLowWater },
  104. { BsdSocketOption.SoRcvLoWat, SocketOptionName.ReceiveLowWater },
  105. { BsdSocketOption.SoSndTimeo, SocketOptionName.SendTimeout },
  106. { BsdSocketOption.SoRcvTimeo, SocketOptionName.ReceiveTimeout },
  107. { BsdSocketOption.SoError, SocketOptionName.Error },
  108. { BsdSocketOption.SoType, SocketOptionName.Type }
  109. };
  110. private static readonly Dictionary<BsdSocketOption, SocketOptionName> _ipSocketOptionMap = new()
  111. {
  112. { BsdSocketOption.IpOptions, SocketOptionName.IPOptions },
  113. { BsdSocketOption.IpHdrIncl, SocketOptionName.HeaderIncluded },
  114. { BsdSocketOption.IpTtl, SocketOptionName.IpTimeToLive },
  115. { BsdSocketOption.IpMulticastIf, SocketOptionName.MulticastInterface },
  116. { BsdSocketOption.IpMulticastTtl, SocketOptionName.MulticastTimeToLive },
  117. { BsdSocketOption.IpMulticastLoop, SocketOptionName.MulticastLoopback },
  118. { BsdSocketOption.IpAddMembership, SocketOptionName.AddMembership },
  119. { BsdSocketOption.IpDropMembership, SocketOptionName.DropMembership },
  120. { BsdSocketOption.IpDontFrag, SocketOptionName.DontFragment },
  121. { BsdSocketOption.IpAddSourceMembership, SocketOptionName.AddSourceMembership },
  122. { BsdSocketOption.IpDropSourceMembership, SocketOptionName.DropSourceMembership }
  123. };
  124. private static readonly Dictionary<BsdSocketOption, SocketOptionName> _tcpSocketOptionMap = new()
  125. {
  126. { BsdSocketOption.TcpNoDelay, SocketOptionName.NoDelay },
  127. { BsdSocketOption.TcpKeepIdle, SocketOptionName.TcpKeepAliveTime },
  128. { BsdSocketOption.TcpKeepIntvl, SocketOptionName.TcpKeepAliveInterval },
  129. { BsdSocketOption.TcpKeepCnt, SocketOptionName.TcpKeepAliveRetryCount }
  130. };
  131. public static LinuxError ConvertError(WsaError errorCode)
  132. {
  133. if (!_errorMap.TryGetValue(errorCode, out LinuxError errno))
  134. {
  135. errno = (LinuxError)errorCode;
  136. }
  137. return errno;
  138. }
  139. public static bool TryConvertSocketOption(BsdSocketOption option, SocketOptionLevel level, out SocketOptionName name)
  140. {
  141. var table = level switch
  142. {
  143. SocketOptionLevel.Socket => _soSocketOptionMap,
  144. SocketOptionLevel.IP => _ipSocketOptionMap,
  145. SocketOptionLevel.Tcp => _tcpSocketOptionMap,
  146. _ => null
  147. };
  148. if (table == null)
  149. {
  150. name = default;
  151. return false;
  152. }
  153. return table.TryGetValue(option, out name);
  154. }
  155. }
  156. }