Socket.h 16 KB

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