Socket.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. #pragma once
  2. #include <string>
  3. #include <vector>
  4. #include "il2cpp-config.h"
  5. #include "os/ErrorCodes.h"
  6. #include "os/Atomic.h"
  7. #include "os/Mutex.h"
  8. #include "os/WaitStatus.h"
  9. #include "utils/Expected.h"
  10. #include "utils/NonCopyable.h"
  11. namespace il2cpp
  12. {
  13. namespace os
  14. {
  15. class SocketImpl;
  16. enum AddressFamily
  17. {
  18. kAddressFamilyError = -1,
  19. kAddressFamilyUnspecified = 0,// AF_UNSPEC
  20. kAddressFamilyUnix = 1,// AF_UNIX
  21. kAddressFamilyInterNetwork = 2,// AF_INET
  22. kAddressFamilyIpx = 3,// AF_IPX
  23. kAddressFamilySna = 4,// AF_SNA
  24. kAddressFamilyDecNet = 5,// AF_DECnet
  25. kAddressFamilyAppleTalk = 6,// AF_APPLETALK
  26. kAddressFamilyInterNetworkV6 = 7,// AF_INET6
  27. kAddressFamilyIrda = 8,// AF_IRDA
  28. };
  29. enum SocketType
  30. {
  31. kSocketTypeError = -1,
  32. kSocketTypeStream = 0,// SOCK_STREAM
  33. kSocketTypeDgram = 1,// SOCK_DGRAM
  34. kSocketTypeRaw = 2,// SOCK_RAW
  35. kSocketTypeRdm = 3,// SOCK_RDM
  36. kSocketTypeSeqpacket = 4,// SOCK_SEQPACKET
  37. };
  38. enum ProtocolType
  39. {
  40. kProtocolTypeUnknown = -1,
  41. kProtocolTypeIP = 0,
  42. kProtocolTypeIcmp = 1,
  43. kProtocolTypeIgmp = 2,
  44. kProtocolTypeGgp = 3,
  45. kProtocolTypeTcp = 6,
  46. kProtocolTypePup = 12,
  47. kProtocolTypeUdp = 17,
  48. kProtocolTypeIdp = 22,
  49. kProtocolTypeND = 77,
  50. kProtocolTypeRaw = 255,
  51. kProtocolTypeUnspecified = 0,
  52. kProtocolTypeIpx = 1000,
  53. kProtocolTypeSpx = 1256,
  54. kProtocolTypeSpxII = 1257,
  55. // #if NET_1_1
  56. kProtocolTypeIPv6 = 41,
  57. // #endif
  58. // #if NET_2_0
  59. kProtocolTypeIPv4 = 4,
  60. kProtocolTypeIPv6RoutingHeader = 43,
  61. kProtocolTypeIPv6FragmentHeader = 44,
  62. kProtocolTypeIPSecEncapsulatingSecurityPayload = 50,
  63. kProtocolTypeIPSecAuthenticationHeader = 51,
  64. kProtocolTypeIcmpV6 = 58,
  65. kProtocolTypeIPv6NoNextHeader = 59,
  66. kProtocolTypeIPv6DestinationOptions = 60,
  67. kProtocolTypeIPv6HopByHopOptions = 0,
  68. // #endif
  69. };
  70. enum SocketFlags
  71. {
  72. kSocketFlagsNone = 0x00000000,
  73. kSocketFlagsOutOfBand = 0x00000001,
  74. kSocketFlagsPeek = 0x00000002,
  75. kSocketFlagsDontRoute = 0x00000004,
  76. kSocketFlagsMaxIOVectorLength = 0x00000010,
  77. // #if NET_2_0
  78. kSocketFlagsTruncated = 0x00000100,
  79. kSocketFlagsControlDataTruncated = 0x00000200,
  80. kSocketFlagsBroadcast = 0x00000400,
  81. kSocketFlagsMulticast = 0x00000800,
  82. // #endif
  83. kSocketFlagsPartial = 0x00008000,
  84. };
  85. enum SocketOptionLevel
  86. {
  87. kSocketOptionLevelSocket = 65535,
  88. kSocketOptionLevelIP = 0,
  89. kSocketOptionLevelTcp = 6,
  90. kSocketOptionLevelUdp = 17,
  91. //#if NET_1_1
  92. kSocketOptionLevelIPv6 = 41,
  93. //#endif
  94. };
  95. enum SocketOptionName
  96. {
  97. kSocketOptionNameDebug = 1,
  98. kSocketOptionNameAcceptConnection = 2,
  99. kSocketOptionNameReuseAddress = 4,
  100. kSocketOptionNameKeepAlive = 8,
  101. kSocketOptionNameDontRoute = 16,
  102. kSocketOptionNameBroadcast = 32,
  103. kSocketOptionNameUseLoopback = 64,
  104. kSocketOptionNameLinger = 128,
  105. kSocketOptionNameOutOfBandInline = 256,
  106. kSocketOptionNameDontLinger = -129,
  107. kSocketOptionNameExclusiveAddressUse = -5,
  108. kSocketOptionNameSendBuffer = 4097,
  109. kSocketOptionNameReceiveBuffer = 4098,
  110. kSocketOptionNameSendLowWater = 4099,
  111. kSocketOptionNameReceiveLowWater = 4100,
  112. kSocketOptionNameSendTimeout = 4101,
  113. kSocketOptionNameReceiveTimeout = 4102,
  114. kSocketOptionNameError = 4103,
  115. kSocketOptionNameType = 4104,
  116. kSocketOptionNameMaxConnections = 2147483647,
  117. kSocketOptionNameIPOptions = 1,
  118. kSocketOptionNameHeaderIncluded = 2,
  119. kSocketOptionNameTypeOfService = 3,
  120. kSocketOptionNameIpTimeToLive = 4,
  121. kSocketOptionNameMulticastInterface = 9,
  122. kSocketOptionNameMulticastTimeToLive = 10,
  123. kSocketOptionNameMulticastLoopback = 11,
  124. kSocketOptionNameAddMembership = 12,
  125. kSocketOptionNameDropMembership = 13,
  126. kSocketOptionNameDontFragment = 14,
  127. kSocketOptionNameAddSourceMembership = 15,
  128. kSocketOptionNameDropSourceMembership = 16,
  129. kSocketOptionNameBlockSource = 17,
  130. kSocketOptionNameUnblockSource = 18,
  131. kSocketOptionNamePacketInformation = 19,
  132. kSocketOptionNameNoDelay = 1,
  133. kSocketOptionNameBsdUrgent = 2,
  134. kSocketOptionNameExpedited = 2,
  135. kSocketOptionNameNoChecksum = 1,
  136. kSocketOptionNameChecksumCoverage = 20,
  137. kSocketOptionNameIPv6Only = 27,
  138. // #if NET_2_0
  139. kSocketOptionNameHopLimit = 21,
  140. kSocketOptionNameUpdateAcceptContext = 28683,
  141. kSocketOptionNameUpdateConnectContext = 28688,
  142. // #endif
  143. };
  144. enum PollFlags
  145. {
  146. kPollFlagsNone = 0,
  147. kPollFlagsIn = 1,
  148. kPollFlagsPri = 2,
  149. kPollFlagsOut = 4,
  150. kPollFlagsErr = 8,
  151. kPollFlagsHup = 0x10,
  152. kPollFlagsNVal = 0x20,
  153. kPollFlagsAny = 0xffffffff
  154. };
  155. enum SocketError
  156. {
  157. kInterrupted = 4,// EINTR on POSIX and WSAEINTR on Windows
  158. kInvalidHandle = 9 // EBADF on POSIX and WSAEBADF on Windows
  159. };
  160. inline void operator|=(PollFlags& left, PollFlags right)
  161. {
  162. left = static_cast<PollFlags>(static_cast<int>(left) | static_cast<int>(right));
  163. }
  164. enum TransmitFileOptions
  165. {
  166. kTransmitFileOptionsUseDefaultWorkerThread = 0x00000000,
  167. kTransmitFileOptionsDisconnect = 0x00000001,
  168. kTransmitFileOptionsReuseSocket = 0x00000002,
  169. kTransmitFileOptionsWriteBehind = 0x00000004,
  170. kTransmitFileOptionsUseSystemThread = 0x00000010,
  171. kTransmitFileOptionsUseKernelApc = 0x00000020,
  172. };
  173. class Socket;
  174. struct PollRequest
  175. {
  176. PollRequest()
  177. : fd(-1)
  178. , events(kPollFlagsNone)
  179. , revents(kPollFlagsNone)
  180. {}
  181. PollRequest(int64_t value)
  182. : fd(value)
  183. , events(kPollFlagsNone)
  184. , revents(kPollFlagsNone)
  185. {}
  186. int64_t fd;
  187. PollFlags events;
  188. PollFlags revents;
  189. };
  190. #if IL2CPP_SUPPORT_IPV6
  191. struct IPv6Address
  192. {
  193. uint8_t addr[16];
  194. };
  195. #endif
  196. // TODO: this should really be UNIX_PATH_MAX or SUN_LEN(n)
  197. #define END_POINT_MAX_PATH_LEN 255
  198. #if IL2CPP_COMPILER_MSVC
  199. #pragma warning( push )
  200. #pragma warning( disable : 4200 )
  201. #endif
  202. struct EndPointInfo
  203. {
  204. AddressFamily family;
  205. union
  206. {
  207. struct
  208. {
  209. uint32_t port;
  210. uint32_t address;
  211. } inet;
  212. char path[END_POINT_MAX_PATH_LEN];
  213. uint8_t raw[IL2CPP_ZERO_LEN_ARRAY];
  214. } data;
  215. };
  216. #if IL2CPP_COMPILER_MSVC
  217. #pragma warning( pop )
  218. #endif
  219. // NOTE(gab): this must be binary compatible with Windows's WSABUF
  220. struct WSABuf
  221. {
  222. uint32_t length;
  223. void *buffer;
  224. };
  225. // NOTE(gab): this must be binary compatible with Window's TRANSMIT_FILE_BUFFERS
  226. struct TransmitFileBuffers
  227. {
  228. void *head;
  229. uint32_t head_length;
  230. void *tail;
  231. uint32_t tail_length;
  232. };
  233. // Note: this callback can be invoked by the os-specific implementation when an
  234. // interrupt is received or when the native code is looping in a potentially long
  235. // loop.
  236. // If the callback retun false, the executiong of the os-specific method is
  237. // gracefully interrupted, and an error is supposed to be returned by the
  238. // os-specific implementation.
  239. // The callback is allowed to throw exceptions (for example a ThreadAborted exception):
  240. // in this case, it is up to the os-specific implementation to properly deal with
  241. // cleaning up the temporarely allocated memory (if any).
  242. typedef bool (*ThreadStatusCallback)();
  243. /// Sockets should generally be referenced through SocketHandles for thread-safety.
  244. /// Handles are stored in a table and can be safely used even when the socket has already
  245. /// been deleted.
  246. typedef intptr_t SocketHandle;
  247. class Socket : public il2cpp::utils::NonCopyable
  248. {
  249. public:
  250. Socket(ThreadStatusCallback thread_status_callback);
  251. ~Socket();
  252. // Note: this Create is only used internally
  253. WaitStatus Create(int64_t fd, int32_t family, int32_t type, int32_t protocol);
  254. WaitStatus Create(AddressFamily family, SocketType type, ProtocolType protocol);
  255. bool IsClosed();
  256. void Close();
  257. int64_t GetDescriptor();
  258. ErrorCode GetLastError() const;
  259. WaitStatus SetBlocking(bool blocking);
  260. WaitStatus Listen(int32_t blacklog);
  261. WaitStatus Bind(const char *path);
  262. WaitStatus Bind(uint32_t address, uint16_t port);
  263. WaitStatus Bind(const char *address, uint16_t port);
  264. utils::Expected<WaitStatus> Bind(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port);
  265. WaitStatus Connect(const char *path);
  266. WaitStatus Connect(uint32_t address, uint16_t port);
  267. utils::Expected<WaitStatus> Connect(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port);
  268. WaitStatus Disconnect(bool reuse);
  269. WaitStatus Shutdown(int32_t how);
  270. WaitStatus GetLocalEndPointInfo(EndPointInfo &info);
  271. WaitStatus GetRemoteEndPointInfo(EndPointInfo &info);
  272. WaitStatus Receive(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  273. WaitStatus Send(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  274. WaitStatus SendArray(WSABuf *wsabufs, int32_t count, int32_t *sent, SocketFlags c_flags);
  275. WaitStatus ReceiveArray(WSABuf *wsabufs, int32_t count, int32_t *len, SocketFlags c_flags);
  276. WaitStatus SendTo(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  277. utils::Expected<WaitStatus> SendTo(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  278. utils::Expected<WaitStatus> SendTo(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  279. WaitStatus RecvFrom(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep);
  280. utils::Expected<WaitStatus> RecvFrom(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep);
  281. utils::Expected<WaitStatus> RecvFrom(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep);
  282. WaitStatus Available(int32_t *amount);
  283. WaitStatus Accept(Socket **socket);
  284. WaitStatus Ioctl(int32_t command, const uint8_t *in_data, int32_t in_len, uint8_t *out_data, int32_t out_len, int32_t *written);
  285. WaitStatus GetSocketOption(SocketOptionLevel level, SocketOptionName name, uint8_t *buffer, int32_t *length);
  286. WaitStatus GetSocketOptionFull(SocketOptionLevel level, SocketOptionName name, int32_t *first, int32_t *second);
  287. WaitStatus SetSocketOption(SocketOptionLevel level, SocketOptionName name, int32_t value);
  288. WaitStatus SetSocketOptionLinger(SocketOptionLevel level, SocketOptionName name, bool enabled, int32_t seconds);
  289. WaitStatus SetSocketOptionArray(SocketOptionLevel level, SocketOptionName name, const uint8_t *buffer, int32_t length);
  290. WaitStatus SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, uint32_t group_address, uint32_t local_address);
  291. #if IL2CPP_SUPPORT_IPV6
  292. WaitStatus SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, IPv6Address ipv6, uint64_t interfaceOffset);
  293. #endif
  294. WaitStatus SendFile(const char *filename, TransmitFileBuffers *buffers, TransmitFileOptions options);
  295. #if IL2CPP_SUPPORT_IPV6_SUPPORT_QUERY
  296. static bool IsIPv6Supported();
  297. #endif
  298. static WaitStatus Poll(std::vector<PollRequest> &requests, int32_t count, int32_t timeout, int32_t *result, int32_t *error);
  299. static WaitStatus Poll(std::vector<PollRequest> &requests, int32_t timeout, int32_t *result, int32_t *error);
  300. static WaitStatus Poll(PollRequest &request, int32_t timeout, int32_t *result, int32_t *error);
  301. static WaitStatus GetHostName(std::string &name);
  302. static WaitStatus GetHostByName(const std::string &host, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addresses);
  303. // The pointers in addr_list are allocated with the il2cpp::utils::Memory::Malloc method. They should he freed by the caller using il2cpp::utils::Memory::Free.
  304. static WaitStatus GetHostByName(const std::string &host, std::string &name, int32_t &family, std::vector<std::string> &aliases, std::vector<void*> &addr_list, int32_t &addr_size);
  305. static WaitStatus GetHostByAddr(const std::string &address, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addr_list);
  306. static void Startup();
  307. static void Cleanup();
  308. private:
  309. SocketImpl* m_Socket;
  310. friend Socket* AcquireSocketHandle(SocketHandle handle);
  311. friend void ReleaseSocketHandle(SocketHandle handle, Socket* socketToRelease, bool forceTableRemove);
  312. uint32_t m_RefCount;
  313. };
  314. enum
  315. {
  316. kInvalidSocketHandle = -1
  317. };
  318. SocketHandle CreateSocketHandle(Socket* socket);
  319. Socket* AcquireSocketHandle(SocketHandle handle);
  320. void ReleaseSocketHandle(SocketHandle handle, Socket* socketToRelease, bool forceTableRemove = false);
  321. inline SocketHandle PointerToSocketHandle(void* ptr)
  322. {
  323. // Double cast to avoid warnings.
  324. return static_cast<SocketHandle>(reinterpret_cast<size_t>(ptr));
  325. }
  326. /// Helper to automatically acquire and release a Socket within a scope.
  327. struct SocketHandleWrapper
  328. {
  329. SocketHandleWrapper()
  330. : m_Handle(kInvalidSocketHandle)
  331. , m_Socket(NULL) {}
  332. SocketHandleWrapper(SocketHandle handle)
  333. : m_Handle(handle)
  334. {
  335. m_Socket = AcquireSocketHandle(handle);
  336. }
  337. SocketHandleWrapper(const SocketHandleWrapper& other)
  338. {
  339. m_Handle = other.m_Handle;
  340. if (m_Handle != kInvalidSocketHandle)
  341. m_Socket = AcquireSocketHandle(m_Handle);
  342. else
  343. m_Socket = NULL;
  344. }
  345. ~SocketHandleWrapper()
  346. {
  347. Release();
  348. }
  349. void Acquire(SocketHandle handle)
  350. {
  351. Release();
  352. m_Handle = handle;
  353. m_Socket = AcquireSocketHandle(handle);
  354. }
  355. void Release()
  356. {
  357. if (m_Socket)
  358. ReleaseSocketHandle(m_Handle, m_Socket);
  359. m_Socket = NULL;
  360. m_Handle = kInvalidSocketHandle;
  361. }
  362. bool IsValid() const
  363. {
  364. return (m_Socket != NULL);
  365. }
  366. SocketHandle GetHandle() const
  367. {
  368. return m_Handle;
  369. }
  370. Socket* GetSocket() const
  371. {
  372. return m_Socket;
  373. }
  374. Socket* operator->() const
  375. {
  376. return GetSocket();
  377. }
  378. SocketHandleWrapper& operator=(const SocketHandleWrapper& other)
  379. {
  380. Acquire(other.GetHandle());
  381. return *this;
  382. }
  383. private:
  384. SocketHandle m_Handle;
  385. Socket* m_Socket;
  386. };
  387. }
  388. }