Socket.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439
  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. int64_t fd;
  176. PollFlags events;
  177. PollFlags revents;
  178. };
  179. #if IL2CPP_SUPPORT_IPV6
  180. struct IPv6Address
  181. {
  182. uint8_t addr[16];
  183. };
  184. #endif
  185. // TODO: this should really be UNIX_PATH_MAX or SUN_LEN(n)
  186. #define END_POINT_MAX_PATH_LEN 255
  187. #if IL2CPP_COMPILER_MSVC
  188. #pragma warning( push )
  189. #pragma warning( disable : 4200 )
  190. #endif
  191. struct EndPointInfo
  192. {
  193. AddressFamily family;
  194. union
  195. {
  196. struct
  197. {
  198. uint32_t port;
  199. uint32_t address;
  200. } inet;
  201. char path[END_POINT_MAX_PATH_LEN];
  202. uint8_t raw[IL2CPP_ZERO_LEN_ARRAY];
  203. } data;
  204. };
  205. #if IL2CPP_COMPILER_MSVC
  206. #pragma warning( pop )
  207. #endif
  208. // NOTE(gab): this must be binary compatible with Windows's WSABUF
  209. struct WSABuf
  210. {
  211. uint32_t length;
  212. void *buffer;
  213. };
  214. // NOTE(gab): this must be binary compatible with Window's TRANSMIT_FILE_BUFFERS
  215. struct TransmitFileBuffers
  216. {
  217. void *head;
  218. uint32_t head_length;
  219. void *tail;
  220. uint32_t tail_length;
  221. };
  222. // Note: this callback can be invoked by the os-specific implementation when an
  223. // interrupt is received or when the native code is looping in a potentially long
  224. // loop.
  225. // If the callback retun false, the executiong of the os-specific method is
  226. // gracefully interrupted, and an error is supposed to be returned by the
  227. // os-specific implementation.
  228. // The callback is allowed to throw exceptions (for example a ThreadAborted exception):
  229. // in this case, it is up to the os-specific implementation to properly deal with
  230. // cleaning up the temporarely allocated memory (if any).
  231. typedef bool (*ThreadStatusCallback)();
  232. class Socket : public il2cpp::utils::NonCopyable
  233. {
  234. public:
  235. Socket(ThreadStatusCallback thread_status_callback);
  236. ~Socket();
  237. // Note: this Create is only used internally
  238. WaitStatus Create(int64_t fd, int32_t family, int32_t type, int32_t protocol);
  239. WaitStatus Create(AddressFamily family, SocketType type, ProtocolType protocol);
  240. bool IsClosed();
  241. void Close();
  242. int64_t GetDescriptor();
  243. ErrorCode GetLastError() const;
  244. WaitStatus SetBlocking(bool blocking);
  245. WaitStatus Listen(int32_t blacklog);
  246. WaitStatus Bind(const char *path);
  247. WaitStatus Bind(uint32_t address, uint16_t port);
  248. WaitStatus Bind(const char *address, uint16_t port);
  249. WaitStatus Bind(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port);
  250. WaitStatus Connect(const char *path);
  251. WaitStatus Connect(uint32_t address, uint16_t port);
  252. WaitStatus Connect(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port);
  253. WaitStatus Disconnect(bool reuse);
  254. WaitStatus Shutdown(int32_t how);
  255. WaitStatus GetLocalEndPointInfo(EndPointInfo &info);
  256. WaitStatus GetRemoteEndPointInfo(EndPointInfo &info);
  257. WaitStatus Receive(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  258. WaitStatus Send(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  259. WaitStatus SendArray(WSABuf *wsabufs, int32_t count, int32_t *sent, SocketFlags c_flags);
  260. WaitStatus ReceiveArray(WSABuf *wsabufs, int32_t count, int32_t *len, SocketFlags c_flags);
  261. WaitStatus SendTo(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  262. WaitStatus SendTo(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len);
  263. 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);
  264. WaitStatus RecvFrom(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep);
  265. WaitStatus RecvFrom(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep);
  266. 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);
  267. WaitStatus Available(int32_t *amount);
  268. WaitStatus Accept(Socket **socket);
  269. 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);
  270. WaitStatus GetSocketOption(SocketOptionLevel level, SocketOptionName name, uint8_t *buffer, int32_t *length);
  271. WaitStatus GetSocketOptionFull(SocketOptionLevel level, SocketOptionName name, int32_t *first, int32_t *second);
  272. WaitStatus SetSocketOption(SocketOptionLevel level, SocketOptionName name, int32_t value);
  273. WaitStatus SetSocketOptionLinger(SocketOptionLevel level, SocketOptionName name, bool enabled, int32_t seconds);
  274. WaitStatus SetSocketOptionArray(SocketOptionLevel level, SocketOptionName name, const uint8_t *buffer, int32_t length);
  275. WaitStatus SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, uint32_t group_address, uint32_t local_address);
  276. #if IL2CPP_SUPPORT_IPV6
  277. WaitStatus SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, IPv6Address ipv6, uint64_t interfaceOffset);
  278. #endif
  279. WaitStatus SendFile(const char *filename, TransmitFileBuffers *buffers, TransmitFileOptions options);
  280. static WaitStatus Poll(std::vector<PollRequest> &requests, int32_t count, int32_t timeout, int32_t *result, int32_t *error);
  281. static WaitStatus Poll(std::vector<PollRequest> &requests, int32_t timeout, int32_t *result, int32_t *error);
  282. static WaitStatus Poll(PollRequest &request, int32_t timeout, int32_t *result, int32_t *error);
  283. static WaitStatus GetHostName(std::string &name);
  284. static WaitStatus GetHostByName(const std::string &host, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addr_list);
  285. static WaitStatus GetHostByAddr(const std::string &address, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addr_list);
  286. static void Startup();
  287. static void Cleanup();
  288. private:
  289. SocketImpl* m_Socket;
  290. };
  291. /// Sockets should generally be referenced through SocketHandles for thread-safety.
  292. /// Handles are stored in a table and can be safely used even when the socket has already
  293. /// been deleted.
  294. typedef uint32_t SocketHandle;
  295. enum
  296. {
  297. kInvalidSocketHandle = 0
  298. };
  299. SocketHandle CreateSocketHandle(Socket* socket);
  300. Socket* AcquireSocketHandle(SocketHandle handle);
  301. void ReleaseSocketHandle(SocketHandle handle);
  302. inline SocketHandle PointerToSocketHandle(void* ptr)
  303. {
  304. // Double cast to avoid warnings.
  305. return static_cast<SocketHandle>(reinterpret_cast<size_t>(ptr));
  306. }
  307. /// Helper to automatically acquire and release a Socket within a scope.
  308. struct SocketHandleWrapper
  309. {
  310. SocketHandleWrapper()
  311. : m_Handle(kInvalidSocketHandle)
  312. , m_Socket(NULL) {}
  313. SocketHandleWrapper(SocketHandle handle)
  314. : m_Handle(handle)
  315. {
  316. m_Socket = AcquireSocketHandle(handle);
  317. }
  318. SocketHandleWrapper(const SocketHandleWrapper& other)
  319. {
  320. m_Handle = other.m_Handle;
  321. if (m_Handle != kInvalidSocketHandle)
  322. m_Socket = AcquireSocketHandle(m_Handle);
  323. else
  324. m_Socket = NULL;
  325. }
  326. ~SocketHandleWrapper()
  327. {
  328. Release();
  329. }
  330. void Acquire(SocketHandle handle)
  331. {
  332. Release();
  333. m_Handle = handle;
  334. m_Socket = AcquireSocketHandle(handle);
  335. }
  336. void Release()
  337. {
  338. if (m_Socket)
  339. ReleaseSocketHandle(m_Handle);
  340. m_Socket = NULL;
  341. m_Handle = kInvalidSocketHandle;
  342. }
  343. bool IsValid() const
  344. {
  345. return (m_Socket != NULL);
  346. }
  347. SocketHandle GetHandle() const
  348. {
  349. return m_Handle;
  350. }
  351. Socket* GetSocket() const
  352. {
  353. return m_Socket;
  354. }
  355. Socket* operator->() const
  356. {
  357. return GetSocket();
  358. }
  359. SocketHandleWrapper& operator=(const SocketHandleWrapper& other)
  360. {
  361. Acquire(other.GetHandle());
  362. return *this;
  363. }
  364. private:
  365. SocketHandle m_Handle;
  366. Socket* m_Socket;
  367. };
  368. }
  369. }