WinSockHelper.cs 7.7 KB

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