Socket.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. #include "il2cpp-config.h"
  2. #if IL2CPP_SUPPORT_SOCKETS
  3. #include <map>
  4. #include "os/Socket.h"
  5. #include "os/Atomic.h"
  6. #include "os/Mutex.h"
  7. #include "utils/Expected.h"
  8. #include "Baselib.h"
  9. #include "Cpp/ReentrantLock.h"
  10. #if IL2CPP_TARGET_POSIX
  11. # include "os/Posix/SocketImpl.h"
  12. #elif IL2CPP_TARGET_WINDOWS
  13. # include "os/Win32/SocketImpl.h"
  14. #elif IL2CPP_TARGET_SWITCH
  15. # include "os/SocketImpl.h"
  16. #else
  17. # include "os/Generic/SocketImpl.h"
  18. #endif
  19. namespace il2cpp
  20. {
  21. namespace os
  22. {
  23. typedef std::map<SocketHandle, Socket&> SocketHandleTable;
  24. baselib::ReentrantLock g_SocketHandleTableMutex;
  25. SocketHandleTable g_SocketHandleTable;
  26. SocketHandle CreateSocketHandle(Socket* socket)
  27. {
  28. // Get the handle from the socket file descripter.
  29. SocketHandle newHandle = (SocketHandle)socket->GetDescriptor();
  30. // If the descripter is invalid we revert to the old method
  31. if (newHandle == kInvalidSocketHandle)
  32. {
  33. IL2CPP_ASSERT(0 && "Attempted to get an invalid socket handle. Should not be in this method.");
  34. return kInvalidSocketHandle;
  35. }
  36. // Add to table.
  37. {
  38. FastAutoLock lock(&g_SocketHandleTableMutex);
  39. auto insertRes = g_SocketHandleTable.insert(SocketHandleTable::value_type(newHandle, *socket));
  40. IL2CPP_ASSERT(insertRes.second && "Attempted to add a handle to the map that was already there.");
  41. }
  42. return newHandle;
  43. }
  44. Socket* AcquireSocketHandle(SocketHandle handle)
  45. {
  46. if (handle == kInvalidSocketHandle)
  47. return NULL;
  48. FastAutoLock lock(&g_SocketHandleTableMutex);
  49. // Look up in table.
  50. SocketHandleTable::iterator iter = g_SocketHandleTable.find(handle);
  51. if (iter == g_SocketHandleTable.end())
  52. return NULL;
  53. // Increase reference count.
  54. Socket& socket = iter->second;
  55. ++socket.m_RefCount;
  56. return &socket;
  57. }
  58. void ReleaseSocketHandle(SocketHandle handle, Socket* socketToRelease, bool forceTableRemove)
  59. {
  60. if (handle == kInvalidSocketHandle || !socketToRelease)
  61. {
  62. IL2CPP_ASSERT(0 && "Invalid argument in ReleaseSocketHandle");
  63. return;
  64. }
  65. Socket* socketToDelete = NULL;
  66. {
  67. FastAutoLock lock(&g_SocketHandleTableMutex);
  68. IL2CPP_ASSERT(socketToRelease->m_RefCount && "Invalid ref count for Socket");
  69. --socketToRelease->m_RefCount;
  70. // Look up in table.
  71. SocketHandleTable::iterator iter = g_SocketHandleTable.find(handle);
  72. if (iter != g_SocketHandleTable.end() &&
  73. ((socketToRelease == &iter->second && !socketToRelease->m_RefCount) || forceTableRemove))
  74. {
  75. g_SocketHandleTable.erase(iter);
  76. }
  77. if (!socketToRelease->m_RefCount)
  78. {
  79. // Kill socket. Should be the only place where we directly delete sockets that
  80. // have made it past the creation step.
  81. socketToDelete = socketToRelease;
  82. }
  83. }
  84. // Perform the deletion after we have released the lock so we don't unnecessarily
  85. // prevent other threads from accessing the table.
  86. if (socketToDelete)
  87. delete socketToDelete;
  88. }
  89. void Socket::Startup()
  90. {
  91. return SocketImpl::Startup();
  92. }
  93. void Socket::Cleanup()
  94. {
  95. return SocketImpl::Cleanup();
  96. }
  97. WaitStatus Socket::GetHostName(std::string &name)
  98. {
  99. return SocketImpl::GetHostName(name);
  100. }
  101. WaitStatus Socket::GetHostByAddr(const std::string &address, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addr_list)
  102. {
  103. return SocketImpl::GetHostByAddr(address, name, aliases, addr_list);
  104. }
  105. WaitStatus Socket::GetHostByName(const std::string &host, std::string &name, std::vector<std::string> &aliases, std::vector<std::string> &addresses)
  106. {
  107. return SocketImpl::GetHostByName(host, name, aliases, addresses);
  108. }
  109. WaitStatus Socket::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)
  110. {
  111. return SocketImpl::GetHostByName(host, name, family, aliases, addr_list, addr_size);
  112. }
  113. Socket::Socket(ThreadStatusCallback thread_status_callback)
  114. : m_Socket(new SocketImpl(thread_status_callback)), m_RefCount(1)
  115. {
  116. }
  117. Socket::~Socket()
  118. {
  119. if (!IsClosed())
  120. Close();
  121. delete m_Socket;
  122. m_Socket = 0;
  123. }
  124. int64_t Socket::GetDescriptor()
  125. {
  126. if (IsClosed())
  127. return -1;
  128. return m_Socket->GetDescriptor();
  129. }
  130. WaitStatus Socket::Create(int64_t fd, int32_t family, int32_t type, int32_t protocol)
  131. {
  132. return m_Socket->Create((SocketImpl::SocketDescriptor)fd, family, type, protocol);
  133. }
  134. WaitStatus Socket::Create(AddressFamily family, SocketType type, ProtocolType protocol)
  135. {
  136. return m_Socket->Create(family, type, protocol);
  137. }
  138. bool Socket::IsClosed()
  139. {
  140. return m_Socket->IsClosed();
  141. }
  142. void Socket::Close()
  143. {
  144. m_Socket->Close();
  145. }
  146. ErrorCode Socket::GetLastError() const
  147. {
  148. return m_Socket->GetLastError();
  149. }
  150. WaitStatus Socket::SetBlocking(bool blocking)
  151. {
  152. return m_Socket->SetBlocking(blocking);
  153. }
  154. WaitStatus Socket::Bind(const char *path)
  155. {
  156. return m_Socket->Bind(path);
  157. }
  158. WaitStatus Socket::Bind(uint32_t address, uint16_t port)
  159. {
  160. return m_Socket->Bind(address, port);
  161. }
  162. WaitStatus Socket::Bind(const char *address, uint16_t port)
  163. {
  164. return m_Socket->Bind(address, port);
  165. }
  166. utils::Expected<WaitStatus> Socket::Bind(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port)
  167. {
  168. return m_Socket->Bind(address, scope, port);
  169. }
  170. WaitStatus Socket::Connect(const char *path)
  171. {
  172. return m_Socket->Connect(path);
  173. }
  174. WaitStatus Socket::Connect(uint32_t address, uint16_t port)
  175. {
  176. return m_Socket->Connect(address, port);
  177. }
  178. utils::Expected<WaitStatus> Socket::Connect(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port)
  179. {
  180. return m_Socket->Connect(address, scope, port);
  181. }
  182. WaitStatus Socket::Disconnect(bool reuse)
  183. {
  184. return m_Socket->Disconnect(reuse);
  185. }
  186. WaitStatus Socket::Shutdown(int32_t how)
  187. {
  188. return m_Socket->Shutdown(how);
  189. }
  190. WaitStatus Socket::GetLocalEndPointInfo(EndPointInfo &info)
  191. {
  192. return m_Socket->GetLocalEndPointInfo(info);
  193. }
  194. WaitStatus Socket::GetRemoteEndPointInfo(EndPointInfo &info)
  195. {
  196. return m_Socket->GetRemoteEndPointInfo(info);
  197. }
  198. WaitStatus Socket::Listen(int32_t backlog)
  199. {
  200. return m_Socket->Listen(backlog);
  201. }
  202. WaitStatus Socket::Accept(Socket **socket)
  203. {
  204. return m_Socket->Accept(socket);
  205. }
  206. WaitStatus Socket::Receive(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  207. {
  208. return m_Socket->Receive(data, count, flags, len);
  209. }
  210. WaitStatus Socket::ReceiveArray(WSABuf *wsabufs, int32_t count, int32_t *len, SocketFlags c_flags)
  211. {
  212. return m_Socket->ReceiveArray(wsabufs, count, len, c_flags);
  213. }
  214. WaitStatus Socket::Send(const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  215. {
  216. return m_Socket->Send(data, count, flags, len);
  217. }
  218. WaitStatus Socket::SendArray(WSABuf *wsabufs, int32_t count, int32_t *sent, SocketFlags c_flags)
  219. {
  220. return m_Socket->SendArray(wsabufs, count, sent, c_flags);
  221. }
  222. WaitStatus Socket::SendTo(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  223. {
  224. return m_Socket->SendTo(address, port, data, count, flags, len);
  225. }
  226. utils::Expected<WaitStatus> Socket::SendTo(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  227. {
  228. return m_Socket->SendTo(path, data, count, flags, len);
  229. }
  230. utils::Expected<WaitStatus> Socket::SendTo(uint8_t address[ipv6AddressSize], uint32_t scope, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len)
  231. {
  232. return m_Socket->SendTo(address, scope, port, data, count, flags, len);
  233. }
  234. WaitStatus Socket::RecvFrom(uint32_t address, uint16_t port, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep)
  235. {
  236. return m_Socket->RecvFrom(address, port, data, count, flags, len, ep);
  237. }
  238. utils::Expected<WaitStatus> Socket::RecvFrom(const char *path, const uint8_t *data, int32_t count, os::SocketFlags flags, int32_t *len, os::EndPointInfo &ep)
  239. {
  240. return m_Socket->RecvFrom(path, data, count, flags, len, ep);
  241. }
  242. utils::Expected<WaitStatus> Socket::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)
  243. {
  244. return m_Socket->RecvFrom(address, scope, port, data, count, flags, len, ep);
  245. }
  246. WaitStatus Socket::Available(int32_t *amount)
  247. {
  248. return m_Socket->Available(amount);
  249. }
  250. WaitStatus Socket::Ioctl(int32_t command, const uint8_t *in_data, int32_t in_len, uint8_t *out_data, int32_t out_len, int32_t *written)
  251. {
  252. return m_Socket->Ioctl(command, in_data, in_len, out_data, out_len, written);
  253. }
  254. WaitStatus Socket::GetSocketOption(SocketOptionLevel level, SocketOptionName name, uint8_t *buffer, int32_t *length)
  255. {
  256. return m_Socket->GetSocketOption(level, name, buffer, length);
  257. }
  258. WaitStatus Socket::GetSocketOptionFull(SocketOptionLevel level, SocketOptionName name, int32_t *first, int32_t *second)
  259. {
  260. return m_Socket->GetSocketOptionFull(level, name, first, second);
  261. }
  262. WaitStatus Socket::Poll(std::vector<PollRequest> &requests, int32_t count, int32_t timeout, int32_t *result, int32_t *error)
  263. {
  264. return SocketImpl::Poll(requests, count, timeout, result, error);
  265. }
  266. WaitStatus Socket::Poll(std::vector<PollRequest> &requests, int32_t timeout, int32_t *result, int32_t *error)
  267. {
  268. return SocketImpl::Poll(requests, timeout, result, error);
  269. }
  270. WaitStatus Socket::Poll(PollRequest& request, int32_t timeout, int32_t *result, int32_t *error)
  271. {
  272. return SocketImpl::Poll(request, timeout, result, error);
  273. }
  274. WaitStatus Socket::SetSocketOption(SocketOptionLevel level, SocketOptionName name, int32_t value)
  275. {
  276. return m_Socket->SetSocketOption(level, name, value);
  277. }
  278. WaitStatus Socket::SetSocketOptionLinger(SocketOptionLevel level, SocketOptionName name, bool enabled, int32_t seconds)
  279. {
  280. return m_Socket->SetSocketOptionLinger(level, name, enabled, seconds);
  281. }
  282. WaitStatus Socket::SetSocketOptionArray(SocketOptionLevel level, SocketOptionName name, const uint8_t *buffer, int32_t length)
  283. {
  284. return m_Socket->SetSocketOptionArray(level, name, buffer, length);
  285. }
  286. WaitStatus Socket::SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, uint32_t group_address, uint32_t local_address)
  287. {
  288. return m_Socket->SetSocketOptionMembership(level, name, group_address, local_address);
  289. }
  290. #if IL2CPP_SUPPORT_IPV6
  291. WaitStatus Socket::SetSocketOptionMembership(SocketOptionLevel level, SocketOptionName name, IPv6Address ipv6, uint64_t interfaceOffset)
  292. {
  293. return m_Socket->SetSocketOptionMembership(level, name, ipv6, interfaceOffset);
  294. }
  295. #endif
  296. #if IL2CPP_SUPPORT_IPV6_SUPPORT_QUERY
  297. bool Socket::IsIPv6Supported()
  298. {
  299. return SocketImpl::IsIPv6Supported();
  300. }
  301. #endif
  302. WaitStatus Socket::SendFile(const char *filename, TransmitFileBuffers *buffers, TransmitFileOptions options)
  303. {
  304. return m_Socket->SendFile(filename, buffers, options);
  305. }
  306. }
  307. }
  308. #endif