soc_u.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. // Copyright 2014 Citra Emulator Project
  2. // Licensed under GPLv2 or any later version
  3. // Refer to the license.txt file included.
  4. #include <algorithm>
  5. #include <cstring>
  6. #include <unordered_map>
  7. #include <vector>
  8. #include "common/assert.h"
  9. #include "common/bit_field.h"
  10. #include "common/common_types.h"
  11. #include "common/logging/log.h"
  12. #include "common/scope_exit.h"
  13. #include "core/hle/kernel/session.h"
  14. #include "core/hle/result.h"
  15. #include "core/hle/service/soc_u.h"
  16. #include "core/memory.h"
  17. #ifdef _WIN32
  18. #include <winsock2.h>
  19. #include <ws2tcpip.h>
  20. // MinGW does not define several errno constants
  21. #ifndef _MSC_VER
  22. #define EBADMSG 104
  23. #define ENODATA 120
  24. #define ENOMSG 122
  25. #define ENOSR 124
  26. #define ENOSTR 125
  27. #define ETIME 137
  28. #define EIDRM 2001
  29. #define ENOLINK 2002
  30. #endif // _MSC_VER
  31. #else
  32. #include <cerrno>
  33. #include <fcntl.h>
  34. #include <netinet/in.h>
  35. #include <netdb.h>
  36. #include <poll.h>
  37. #include <sys/socket.h>
  38. #include <unistd.h>
  39. #endif
  40. #ifdef _WIN32
  41. # define WSAEAGAIN WSAEWOULDBLOCK
  42. # define WSAEMULTIHOP -1 // Invalid dummy value
  43. # define ERRNO(x) WSA##x
  44. # define GET_ERRNO WSAGetLastError()
  45. # define poll(x, y, z) WSAPoll(x, y, z);
  46. #else
  47. # define ERRNO(x) x
  48. # define GET_ERRNO errno
  49. # define closesocket(x) close(x)
  50. #endif
  51. static const s32 SOCKET_ERROR_VALUE = -1;
  52. ////////////////////////////////////////////////////////////////////////////////////////////////////
  53. // Namespace SOC_U
  54. namespace SOC_U {
  55. /// Holds the translation from system network errors to 3DS network errors
  56. static const std::unordered_map<int, int> error_map = { {
  57. { E2BIG, 1 },
  58. { ERRNO(EACCES), 2 },
  59. { ERRNO(EADDRINUSE), 3 },
  60. { ERRNO(EADDRNOTAVAIL), 4 },
  61. { ERRNO(EAFNOSUPPORT), 5 },
  62. { ERRNO(EAGAIN), 6 },
  63. { ERRNO(EALREADY), 7 },
  64. { ERRNO(EBADF), 8 },
  65. { EBADMSG, 9 },
  66. { EBUSY, 10 },
  67. { ECANCELED, 11 },
  68. { ECHILD, 12 },
  69. { ERRNO(ECONNABORTED), 13 },
  70. { ERRNO(ECONNREFUSED), 14 },
  71. { ERRNO(ECONNRESET), 15 },
  72. { EDEADLK, 16 },
  73. { ERRNO(EDESTADDRREQ), 17 },
  74. { EDOM, 18 },
  75. { ERRNO(EDQUOT), 19 },
  76. { EEXIST, 20 },
  77. { ERRNO(EFAULT), 21 },
  78. { EFBIG, 22 },
  79. { ERRNO(EHOSTUNREACH), 23 },
  80. { EIDRM, 24 },
  81. { EILSEQ, 25 },
  82. { ERRNO(EINPROGRESS), 26 },
  83. { ERRNO(EINTR), 27 },
  84. { ERRNO(EINVAL), 28 },
  85. { EIO, 29 },
  86. { ERRNO(EISCONN), 30 },
  87. { EISDIR, 31 },
  88. { ERRNO(ELOOP), 32 },
  89. { ERRNO(EMFILE), 33 },
  90. { EMLINK, 34 },
  91. { ERRNO(EMSGSIZE), 35 },
  92. { ERRNO(EMULTIHOP), 36 },
  93. { ERRNO(ENAMETOOLONG), 37 },
  94. { ERRNO(ENETDOWN), 38 },
  95. { ERRNO(ENETRESET), 39 },
  96. { ERRNO(ENETUNREACH), 40 },
  97. { ENFILE, 41 },
  98. { ERRNO(ENOBUFS), 42 },
  99. { ENODATA, 43 },
  100. { ENODEV, 44 },
  101. { ENOENT, 45 },
  102. { ENOEXEC, 46 },
  103. { ENOLCK, 47 },
  104. { ENOLINK, 48 },
  105. { ENOMEM, 49 },
  106. { ENOMSG, 50 },
  107. { ERRNO(ENOPROTOOPT), 51 },
  108. { ENOSPC, 52 },
  109. { ENOSR, 53 },
  110. { ENOSTR, 54 },
  111. { ENOSYS, 55 },
  112. { ERRNO(ENOTCONN), 56 },
  113. { ENOTDIR, 57 },
  114. { ERRNO(ENOTEMPTY), 58 },
  115. { ERRNO(ENOTSOCK), 59 },
  116. { ENOTSUP, 60 },
  117. { ENOTTY, 61 },
  118. { ENXIO, 62 },
  119. { ERRNO(EOPNOTSUPP), 63 },
  120. { EOVERFLOW, 64 },
  121. { EPERM, 65 },
  122. { EPIPE, 66 },
  123. { EPROTO, 67 },
  124. { ERRNO(EPROTONOSUPPORT), 68 },
  125. { ERRNO(EPROTOTYPE), 69 },
  126. { ERANGE, 70 },
  127. { EROFS, 71 },
  128. { ESPIPE, 72 },
  129. { ESRCH, 73 },
  130. { ERRNO(ESTALE), 74 },
  131. { ETIME, 75 },
  132. { ERRNO(ETIMEDOUT), 76 }
  133. }};
  134. /// Converts a network error from platform-specific to 3ds-specific
  135. static int TranslateError(int error) {
  136. auto found = error_map.find(error);
  137. if (found != error_map.end())
  138. return -found->second;
  139. return error;
  140. }
  141. /// Holds the translation from system network socket options to 3DS network socket options
  142. /// Note: -1 = No effect/unavailable
  143. static const std::unordered_map<int, int> sockopt_map = { {
  144. { 0x0004, SO_REUSEADDR },
  145. { 0x0080, -1 },
  146. { 0x0100, -1 },
  147. { 0x1001, SO_SNDBUF },
  148. { 0x1002, SO_RCVBUF },
  149. { 0x1003, -1 },
  150. #ifdef _WIN32
  151. /// Unsupported in WinSock2
  152. { 0x1004, -1 },
  153. #else
  154. { 0x1004, SO_RCVLOWAT },
  155. #endif
  156. { 0x1008, SO_TYPE },
  157. { 0x1009, SO_ERROR },
  158. }};
  159. /// Converts a socket option from 3ds-specific to platform-specific
  160. static int TranslateSockOpt(int console_opt_name) {
  161. auto found = sockopt_map.find(console_opt_name);
  162. if (found != sockopt_map.end()) {
  163. return found->second;
  164. }
  165. return console_opt_name;
  166. }
  167. /// Holds information about a particular socket
  168. struct SocketHolder {
  169. u32 socket_fd; ///< The socket descriptor
  170. bool blocking; ///< Whether the socket is blocking or not, it is only read on Windows.
  171. };
  172. /// Structure to represent the 3ds' pollfd structure, which is different than most implementations
  173. struct CTRPollFD {
  174. u32 fd; ///< Socket handle
  175. union Events {
  176. u32 hex; ///< The complete value formed by the flags
  177. BitField<0, 1, u32> pollin;
  178. BitField<1, 1, u32> pollpri;
  179. BitField<2, 1, u32> pollhup;
  180. BitField<3, 1, u32> pollerr;
  181. BitField<4, 1, u32> pollout;
  182. BitField<5, 1, u32> pollnval;
  183. Events& operator=(const Events& other) {
  184. hex = other.hex;
  185. return *this;
  186. }
  187. /// Translates the resulting events of a Poll operation from platform-specific to 3ds specific
  188. static Events TranslateTo3DS(u32 input_event) {
  189. Events ev = {};
  190. if (input_event & POLLIN)
  191. ev.pollin.Assign(1);
  192. if (input_event & POLLPRI)
  193. ev.pollpri.Assign(1);
  194. if (input_event & POLLHUP)
  195. ev.pollhup.Assign(1);
  196. if (input_event & POLLERR)
  197. ev.pollerr.Assign(1);
  198. if (input_event & POLLOUT)
  199. ev.pollout.Assign(1);
  200. if (input_event & POLLNVAL)
  201. ev.pollnval.Assign(1);
  202. return ev;
  203. }
  204. /// Translates the resulting events of a Poll operation from 3ds specific to platform specific
  205. static u32 TranslateToPlatform(Events input_event) {
  206. u32 ret = 0;
  207. if (input_event.pollin)
  208. ret |= POLLIN;
  209. if (input_event.pollpri)
  210. ret |= POLLPRI;
  211. if (input_event.pollhup)
  212. ret |= POLLHUP;
  213. if (input_event.pollerr)
  214. ret |= POLLERR;
  215. if (input_event.pollout)
  216. ret |= POLLOUT;
  217. if (input_event.pollnval)
  218. ret |= POLLNVAL;
  219. return ret;
  220. }
  221. };
  222. Events events; ///< Events to poll for (input)
  223. Events revents; ///< Events received (output)
  224. /// Converts a platform-specific pollfd to a 3ds specific structure
  225. static CTRPollFD FromPlatform(pollfd const& fd) {
  226. CTRPollFD result;
  227. result.events.hex = Events::TranslateTo3DS(fd.events).hex;
  228. result.revents.hex = Events::TranslateTo3DS(fd.revents).hex;
  229. result.fd = static_cast<u32>(fd.fd);
  230. return result;
  231. }
  232. /// Converts a 3ds specific pollfd to a platform-specific structure
  233. static pollfd ToPlatform(CTRPollFD const& fd) {
  234. pollfd result;
  235. result.events = Events::TranslateToPlatform(fd.events);
  236. result.revents = Events::TranslateToPlatform(fd.revents);
  237. result.fd = fd.fd;
  238. return result;
  239. }
  240. };
  241. /// Union to represent the 3ds' sockaddr structure
  242. union CTRSockAddr {
  243. /// Structure to represent a raw sockaddr
  244. struct {
  245. u8 len; ///< The length of the entire structure, only the set fields count
  246. u8 sa_family; ///< The address family of the sockaddr
  247. u8 sa_data[0x1A]; ///< The extra data, this varies, depending on the address family
  248. } raw;
  249. /// Structure to represent the 3ds' sockaddr_in structure
  250. struct CTRSockAddrIn {
  251. u8 len; ///< The length of the entire structure
  252. u8 sin_family; ///< The address family of the sockaddr_in
  253. u16 sin_port; ///< The port associated with this sockaddr_in
  254. u32 sin_addr; ///< The actual address of the sockaddr_in
  255. } in;
  256. /// Convert a 3DS CTRSockAddr to a platform-specific sockaddr
  257. static sockaddr ToPlatform(CTRSockAddr const& ctr_addr) {
  258. sockaddr result;
  259. result.sa_family = ctr_addr.raw.sa_family;
  260. memset(result.sa_data, 0, sizeof(result.sa_data));
  261. // We can not guarantee ABI compatibility between platforms so we copy the fields manually
  262. switch (result.sa_family) {
  263. case AF_INET:
  264. {
  265. sockaddr_in* result_in = reinterpret_cast<sockaddr_in*>(&result);
  266. result_in->sin_port = ctr_addr.in.sin_port;
  267. result_in->sin_addr.s_addr = ctr_addr.in.sin_addr;
  268. memset(result_in->sin_zero, 0, sizeof(result_in->sin_zero));
  269. break;
  270. }
  271. default:
  272. ASSERT_MSG(false, "Unhandled address family (sa_family) in CTRSockAddr::ToPlatform");
  273. break;
  274. }
  275. return result;
  276. }
  277. /// Convert a platform-specific sockaddr to a 3DS CTRSockAddr
  278. static CTRSockAddr FromPlatform(sockaddr const& addr) {
  279. CTRSockAddr result;
  280. result.raw.sa_family = static_cast<u8>(addr.sa_family);
  281. // We can not guarantee ABI compatibility between platforms so we copy the fields manually
  282. switch (result.raw.sa_family) {
  283. case AF_INET:
  284. {
  285. sockaddr_in const* addr_in = reinterpret_cast<sockaddr_in const*>(&addr);
  286. result.raw.len = sizeof(CTRSockAddrIn);
  287. result.in.sin_port = addr_in->sin_port;
  288. result.in.sin_addr = addr_in->sin_addr.s_addr;
  289. break;
  290. }
  291. default:
  292. ASSERT_MSG(false, "Unhandled address family (sa_family) in CTRSockAddr::ToPlatform");
  293. break;
  294. }
  295. return result;
  296. }
  297. };
  298. /// Holds info about the currently open sockets
  299. static std::unordered_map<u32, SocketHolder> open_sockets;
  300. /// Close all open sockets
  301. static void CleanupSockets() {
  302. for (auto sock : open_sockets)
  303. closesocket(sock.second.socket_fd);
  304. open_sockets.clear();
  305. }
  306. static void Socket(Service::Interface* self) {
  307. u32* cmd_buffer = Kernel::GetCommandBuffer();
  308. u32 domain = cmd_buffer[1]; // Address family
  309. u32 type = cmd_buffer[2];
  310. u32 protocol = cmd_buffer[3];
  311. // Only 0 is allowed according to 3dbrew, using 0 will let the OS decide which protocol to use
  312. if (protocol != 0) {
  313. cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
  314. return;
  315. }
  316. if (domain != AF_INET) {
  317. cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
  318. return;
  319. }
  320. if (type != SOCK_DGRAM && type != SOCK_STREAM) {
  321. cmd_buffer[1] = UnimplementedFunction(ErrorModule::SOC).raw; // TODO(Subv): Correct error code
  322. return;
  323. }
  324. u32 socket_handle = static_cast<u32>(::socket(domain, type, protocol));
  325. if ((s32)socket_handle != SOCKET_ERROR_VALUE)
  326. open_sockets[socket_handle] = { socket_handle, true };
  327. int result = 0;
  328. if ((s32)socket_handle == SOCKET_ERROR_VALUE)
  329. result = TranslateError(GET_ERRNO);
  330. cmd_buffer[0] = IPC::MakeHeader(2, 2, 0);
  331. cmd_buffer[1] = result;
  332. cmd_buffer[2] = socket_handle;
  333. }
  334. static void Bind(Service::Interface* self) {
  335. u32* cmd_buffer = Kernel::GetCommandBuffer();
  336. u32 socket_handle = cmd_buffer[1];
  337. u32 len = cmd_buffer[2];
  338. CTRSockAddr* ctr_sock_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[6]));
  339. if (ctr_sock_addr == nullptr) {
  340. cmd_buffer[1] = -1; // TODO(Subv): Correct code
  341. return;
  342. }
  343. sockaddr sock_addr = CTRSockAddr::ToPlatform(*ctr_sock_addr);
  344. int res = ::bind(socket_handle, &sock_addr, std::max<u32>(sizeof(sock_addr), len));
  345. int result = 0;
  346. if (res != 0)
  347. result = TranslateError(GET_ERRNO);
  348. cmd_buffer[0] = IPC::MakeHeader(5, 2, 0);
  349. cmd_buffer[1] = result;
  350. cmd_buffer[2] = res;
  351. }
  352. static void Fcntl(Service::Interface* self) {
  353. u32* cmd_buffer = Kernel::GetCommandBuffer();
  354. u32 socket_handle = cmd_buffer[1];
  355. u32 ctr_cmd = cmd_buffer[2];
  356. u32 ctr_arg = cmd_buffer[3];
  357. int result = 0;
  358. u32 posix_ret = 0; // TODO: Check what hardware returns for F_SETFL (unspecified by POSIX)
  359. SCOPE_EXIT({
  360. cmd_buffer[1] = result;
  361. cmd_buffer[2] = posix_ret;
  362. });
  363. if (ctr_cmd == 3) { // F_GETFL
  364. #ifdef _WIN32
  365. posix_ret = 0;
  366. auto iter = open_sockets.find(socket_handle);
  367. if (iter != open_sockets.end() && iter->second.blocking == false)
  368. posix_ret |= 4; // O_NONBLOCK
  369. #else
  370. int ret = ::fcntl(socket_handle, F_GETFL, 0);
  371. if (ret == SOCKET_ERROR_VALUE) {
  372. result = TranslateError(GET_ERRNO);
  373. posix_ret = -1;
  374. return;
  375. }
  376. posix_ret = 0;
  377. if (ret & O_NONBLOCK)
  378. posix_ret |= 4; // O_NONBLOCK
  379. #endif
  380. } else if (ctr_cmd == 4) { // F_SETFL
  381. #ifdef _WIN32
  382. unsigned long tmp = (ctr_arg & 4 /* O_NONBLOCK */) ? 1 : 0;
  383. int ret = ioctlsocket(socket_handle, FIONBIO, &tmp);
  384. if (ret == SOCKET_ERROR_VALUE) {
  385. result = TranslateError(GET_ERRNO);
  386. posix_ret = -1;
  387. return;
  388. }
  389. auto iter = open_sockets.find(socket_handle);
  390. if (iter != open_sockets.end())
  391. iter->second.blocking = (tmp == 0);
  392. #else
  393. int flags = ::fcntl(socket_handle, F_GETFL, 0);
  394. if (flags == SOCKET_ERROR_VALUE) {
  395. result = TranslateError(GET_ERRNO);
  396. posix_ret = -1;
  397. return;
  398. }
  399. flags &= ~O_NONBLOCK;
  400. if (ctr_arg & 4) // O_NONBLOCK
  401. flags |= O_NONBLOCK;
  402. int ret = ::fcntl(socket_handle, F_SETFL, flags);
  403. if (ret == SOCKET_ERROR_VALUE) {
  404. result = TranslateError(GET_ERRNO);
  405. posix_ret = -1;
  406. return;
  407. }
  408. #endif
  409. } else {
  410. LOG_ERROR(Service_SOC, "Unsupported command (%d) in fcntl call", ctr_cmd);
  411. result = TranslateError(EINVAL); // TODO: Find the correct error
  412. posix_ret = -1;
  413. return;
  414. }
  415. }
  416. static void Listen(Service::Interface* self) {
  417. u32* cmd_buffer = Kernel::GetCommandBuffer();
  418. u32 socket_handle = cmd_buffer[1];
  419. u32 backlog = cmd_buffer[2];
  420. int ret = ::listen(socket_handle, backlog);
  421. int result = 0;
  422. if (ret != 0)
  423. result = TranslateError(GET_ERRNO);
  424. cmd_buffer[0] = IPC::MakeHeader(3, 2, 0);
  425. cmd_buffer[1] = result;
  426. cmd_buffer[2] = ret;
  427. }
  428. static void Accept(Service::Interface* self) {
  429. // TODO(Subv): Calling this function on a blocking socket will block the emu thread,
  430. // preventing graceful shutdown when closing the emulator, this can be fixed by always
  431. // performing nonblocking operations and spinlock until the data is available
  432. u32* cmd_buffer = Kernel::GetCommandBuffer();
  433. u32 socket_handle = cmd_buffer[1];
  434. socklen_t max_addr_len = static_cast<socklen_t>(cmd_buffer[2]);
  435. sockaddr addr;
  436. socklen_t addr_len = sizeof(addr);
  437. u32 ret = static_cast<u32>(::accept(socket_handle, &addr, &addr_len));
  438. if ((s32)ret != SOCKET_ERROR_VALUE)
  439. open_sockets[ret] = { ret, true };
  440. int result = 0;
  441. if ((s32)ret == SOCKET_ERROR_VALUE) {
  442. result = TranslateError(GET_ERRNO);
  443. } else {
  444. CTRSockAddr ctr_addr = CTRSockAddr::FromPlatform(addr);
  445. Memory::WriteBlock(cmd_buffer[0x104 >> 2], (const u8*)&ctr_addr, max_addr_len);
  446. }
  447. cmd_buffer[0] = IPC::MakeHeader(4, 2, 2);
  448. cmd_buffer[1] = result;
  449. cmd_buffer[2] = ret;
  450. cmd_buffer[3] = IPC::StaticBufferDesc(static_cast<u32>(max_addr_len), 0);
  451. }
  452. static void GetHostId(Service::Interface* self) {
  453. u32* cmd_buffer = Kernel::GetCommandBuffer();
  454. char name[128];
  455. gethostname(name, sizeof(name));
  456. addrinfo hints = {};
  457. addrinfo* res;
  458. hints.ai_family = AF_INET;
  459. getaddrinfo(name, nullptr, &hints, &res);
  460. sockaddr_in* sock_addr = reinterpret_cast<sockaddr_in*>(res->ai_addr);
  461. in_addr* addr = &sock_addr->sin_addr;
  462. cmd_buffer[2] = addr->s_addr;
  463. cmd_buffer[1] = 0;
  464. freeaddrinfo(res);
  465. }
  466. static void Close(Service::Interface* self) {
  467. u32* cmd_buffer = Kernel::GetCommandBuffer();
  468. u32 socket_handle = cmd_buffer[1];
  469. int ret = 0;
  470. open_sockets.erase(socket_handle);
  471. ret = closesocket(socket_handle);
  472. int result = 0;
  473. if (ret != 0)
  474. result = TranslateError(GET_ERRNO);
  475. cmd_buffer[2] = ret;
  476. cmd_buffer[1] = result;
  477. }
  478. static void SendTo(Service::Interface* self) {
  479. u32* cmd_buffer = Kernel::GetCommandBuffer();
  480. u32 socket_handle = cmd_buffer[1];
  481. u32 len = cmd_buffer[2];
  482. u32 flags = cmd_buffer[3];
  483. u32 addr_len = cmd_buffer[4];
  484. u8* input_buff = Memory::GetPointer(cmd_buffer[8]);
  485. CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[10]));
  486. if (ctr_dest_addr == nullptr) {
  487. cmd_buffer[1] = -1; // TODO(Subv): Find the right error code
  488. return;
  489. }
  490. int ret = -1;
  491. if (addr_len > 0) {
  492. sockaddr dest_addr = CTRSockAddr::ToPlatform(*ctr_dest_addr);
  493. ret = ::sendto(socket_handle, (const char*)input_buff, len, flags, &dest_addr, sizeof(dest_addr));
  494. } else {
  495. ret = ::sendto(socket_handle, (const char*)input_buff, len, flags, nullptr, 0);
  496. }
  497. int result = 0;
  498. if (ret == SOCKET_ERROR_VALUE)
  499. result = TranslateError(GET_ERRNO);
  500. cmd_buffer[2] = ret;
  501. cmd_buffer[1] = result;
  502. }
  503. static void RecvFrom(Service::Interface* self) {
  504. // TODO(Subv): Calling this function on a blocking socket will block the emu thread,
  505. // preventing graceful shutdown when closing the emulator, this can be fixed by always
  506. // performing nonblocking operations and spinlock until the data is available
  507. u32* cmd_buffer = Kernel::GetCommandBuffer();
  508. u32 socket_handle = cmd_buffer[1];
  509. u32 len = cmd_buffer[2];
  510. u32 flags = cmd_buffer[3];
  511. socklen_t addr_len = static_cast<socklen_t>(cmd_buffer[4]);
  512. struct
  513. {
  514. u32 output_buffer_descriptor;
  515. u32 output_buffer_addr;
  516. u32 address_buffer_descriptor;
  517. u32 output_src_address_buffer;
  518. } buffer_parameters;
  519. std::memcpy(&buffer_parameters, &cmd_buffer[64], sizeof(buffer_parameters));
  520. u8* output_buff = Memory::GetPointer(buffer_parameters.output_buffer_addr);
  521. sockaddr src_addr;
  522. socklen_t src_addr_len = sizeof(src_addr);
  523. int ret = ::recvfrom(socket_handle, (char*)output_buff, len, flags, &src_addr, &src_addr_len);
  524. if (ret >= 0 && buffer_parameters.output_src_address_buffer != 0 && src_addr_len > 0) {
  525. CTRSockAddr* ctr_src_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(buffer_parameters.output_src_address_buffer));
  526. *ctr_src_addr = CTRSockAddr::FromPlatform(src_addr);
  527. }
  528. int result = 0;
  529. int total_received = ret;
  530. if (ret == SOCKET_ERROR_VALUE) {
  531. result = TranslateError(GET_ERRNO);
  532. total_received = 0;
  533. }
  534. cmd_buffer[1] = result;
  535. cmd_buffer[2] = ret;
  536. cmd_buffer[3] = total_received;
  537. }
  538. static void Poll(Service::Interface* self) {
  539. u32* cmd_buffer = Kernel::GetCommandBuffer();
  540. u32 nfds = cmd_buffer[1];
  541. int timeout = cmd_buffer[2];
  542. CTRPollFD* input_fds = reinterpret_cast<CTRPollFD*>(Memory::GetPointer(cmd_buffer[6]));
  543. CTRPollFD* output_fds = reinterpret_cast<CTRPollFD*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
  544. // The 3ds_pollfd and the pollfd structures may be different (Windows/Linux have different sizes)
  545. // so we have to copy the data
  546. std::vector<pollfd> platform_pollfd(nfds);
  547. std::transform(input_fds, input_fds + nfds, platform_pollfd.begin(), CTRPollFD::ToPlatform);
  548. const int ret = ::poll(platform_pollfd.data(), nfds, timeout);
  549. // Now update the output pollfd structure
  550. std::transform(platform_pollfd.begin(), platform_pollfd.end(), output_fds, CTRPollFD::FromPlatform);
  551. int result = 0;
  552. if (ret == SOCKET_ERROR_VALUE)
  553. result = TranslateError(GET_ERRNO);
  554. cmd_buffer[1] = result;
  555. cmd_buffer[2] = ret;
  556. }
  557. static void GetSockName(Service::Interface* self) {
  558. u32* cmd_buffer = Kernel::GetCommandBuffer();
  559. u32 socket_handle = cmd_buffer[1];
  560. socklen_t ctr_len = cmd_buffer[2];
  561. CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
  562. sockaddr dest_addr;
  563. socklen_t dest_addr_len = sizeof(dest_addr);
  564. int ret = ::getsockname(socket_handle, &dest_addr, &dest_addr_len);
  565. if (ctr_dest_addr != nullptr) {
  566. *ctr_dest_addr = CTRSockAddr::FromPlatform(dest_addr);
  567. } else {
  568. cmd_buffer[1] = -1; // TODO(Subv): Verify error
  569. return;
  570. }
  571. int result = 0;
  572. if (ret != 0)
  573. result = TranslateError(GET_ERRNO);
  574. cmd_buffer[2] = ret;
  575. cmd_buffer[1] = result;
  576. }
  577. static void Shutdown(Service::Interface* self) {
  578. u32* cmd_buffer = Kernel::GetCommandBuffer();
  579. u32 socket_handle = cmd_buffer[1];
  580. int how = cmd_buffer[2];
  581. int ret = ::shutdown(socket_handle, how);
  582. int result = 0;
  583. if (ret != 0)
  584. result = TranslateError(GET_ERRNO);
  585. cmd_buffer[2] = ret;
  586. cmd_buffer[1] = result;
  587. }
  588. static void GetPeerName(Service::Interface* self) {
  589. u32* cmd_buffer = Kernel::GetCommandBuffer();
  590. u32 socket_handle = cmd_buffer[1];
  591. socklen_t len = cmd_buffer[2];
  592. CTRSockAddr* ctr_dest_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
  593. sockaddr dest_addr;
  594. socklen_t dest_addr_len = sizeof(dest_addr);
  595. int ret = ::getpeername(socket_handle, &dest_addr, &dest_addr_len);
  596. if (ctr_dest_addr != nullptr) {
  597. *ctr_dest_addr = CTRSockAddr::FromPlatform(dest_addr);
  598. } else {
  599. cmd_buffer[1] = -1;
  600. return;
  601. }
  602. int result = 0;
  603. if (ret != 0)
  604. result = TranslateError(GET_ERRNO);
  605. cmd_buffer[2] = ret;
  606. cmd_buffer[1] = result;
  607. }
  608. static void Connect(Service::Interface* self) {
  609. // TODO(Subv): Calling this function on a blocking socket will block the emu thread,
  610. // preventing graceful shutdown when closing the emulator, this can be fixed by always
  611. // performing nonblocking operations and spinlock until the data is available
  612. u32* cmd_buffer = Kernel::GetCommandBuffer();
  613. u32 socket_handle = cmd_buffer[1];
  614. socklen_t len = cmd_buffer[2];
  615. CTRSockAddr* ctr_input_addr = reinterpret_cast<CTRSockAddr*>(Memory::GetPointer(cmd_buffer[6]));
  616. if (ctr_input_addr == nullptr) {
  617. cmd_buffer[1] = -1; // TODO(Subv): Verify error
  618. return;
  619. }
  620. sockaddr input_addr = CTRSockAddr::ToPlatform(*ctr_input_addr);
  621. int ret = ::connect(socket_handle, &input_addr, sizeof(input_addr));
  622. int result = 0;
  623. if (ret != 0)
  624. result = TranslateError(GET_ERRNO);
  625. cmd_buffer[0] = IPC::MakeHeader(6, 2, 0);
  626. cmd_buffer[1] = result;
  627. cmd_buffer[2] = ret;
  628. }
  629. static void InitializeSockets(Service::Interface* self) {
  630. // TODO(Subv): Implement
  631. #ifdef _WIN32
  632. WSADATA data;
  633. WSAStartup(MAKEWORD(2, 2), &data);
  634. #endif
  635. u32* cmd_buffer = Kernel::GetCommandBuffer();
  636. cmd_buffer[0] = IPC::MakeHeader(1, 1, 0);
  637. cmd_buffer[1] = RESULT_SUCCESS.raw;
  638. }
  639. static void ShutdownSockets(Service::Interface* self) {
  640. // TODO(Subv): Implement
  641. CleanupSockets();
  642. #ifdef _WIN32
  643. WSACleanup();
  644. #endif
  645. u32* cmd_buffer = Kernel::GetCommandBuffer();
  646. cmd_buffer[1] = 0;
  647. }
  648. static void GetSockOpt(Service::Interface* self) {
  649. u32* cmd_buffer = Kernel::GetCommandBuffer();
  650. u32 socket_handle = cmd_buffer[1];
  651. u32 level = cmd_buffer[2];
  652. int optname = TranslateSockOpt(cmd_buffer[3]);
  653. socklen_t optlen = (socklen_t)cmd_buffer[4];
  654. int ret = -1;
  655. int err = 0;
  656. if(optname < 0) {
  657. #ifdef _WIN32
  658. err = WSAEINVAL;
  659. #else
  660. err = EINVAL;
  661. #endif
  662. } else {
  663. // 0x100 = static buffer offset (bytes)
  664. // + 0x4 = 2nd pointer (u32) position
  665. // >> 2 = convert to u32 offset instead of byte offset (cmd_buffer = u32*)
  666. char* optval = reinterpret_cast<char *>(Memory::GetPointer(cmd_buffer[0x104 >> 2]));
  667. ret = ::getsockopt(socket_handle, level, optname, optval, &optlen);
  668. err = 0;
  669. if (ret == SOCKET_ERROR_VALUE) {
  670. err = TranslateError(GET_ERRNO);
  671. }
  672. }
  673. cmd_buffer[0] = IPC::MakeHeader(0x11, 4, 2);
  674. cmd_buffer[1] = ret;
  675. cmd_buffer[2] = err;
  676. cmd_buffer[3] = optlen;
  677. }
  678. static void SetSockOpt(Service::Interface* self) {
  679. u32* cmd_buffer = Kernel::GetCommandBuffer();
  680. u32 socket_handle = cmd_buffer[1];
  681. u32 level = cmd_buffer[2];
  682. int optname = TranslateSockOpt(cmd_buffer[3]);
  683. int ret = -1;
  684. int err = 0;
  685. if(optname < 0) {
  686. #ifdef _WIN32
  687. err = WSAEINVAL;
  688. #else
  689. err = EINVAL;
  690. #endif
  691. } else {
  692. socklen_t optlen = static_cast<socklen_t>(cmd_buffer[4]);
  693. const char* optval = reinterpret_cast<const char *>(Memory::GetPointer(cmd_buffer[8]));
  694. ret = static_cast<u32>(::setsockopt(socket_handle, level, optname, optval, optlen));
  695. err = 0;
  696. if (ret == SOCKET_ERROR_VALUE) {
  697. err = TranslateError(GET_ERRNO);
  698. }
  699. }
  700. cmd_buffer[0] = IPC::MakeHeader(0x12, 4, 4);
  701. cmd_buffer[1] = ret;
  702. cmd_buffer[2] = err;
  703. }
  704. const Interface::FunctionInfo FunctionTable[] = {
  705. {0x00010044, InitializeSockets, "InitializeSockets"},
  706. {0x000200C2, Socket, "Socket"},
  707. {0x00030082, Listen, "Listen"},
  708. {0x00040082, Accept, "Accept"},
  709. {0x00050084, Bind, "Bind"},
  710. {0x00060084, Connect, "Connect"},
  711. {0x00070104, nullptr, "recvfrom_other"},
  712. {0x00080102, RecvFrom, "RecvFrom"},
  713. {0x00090106, nullptr, "sendto_other"},
  714. {0x000A0106, SendTo, "SendTo"},
  715. {0x000B0042, Close, "Close"},
  716. {0x000C0082, Shutdown, "Shutdown"},
  717. {0x000D0082, nullptr, "GetHostByName"},
  718. {0x000E00C2, nullptr, "GetHostByAddr"},
  719. {0x000F0106, nullptr, "GetAddrInfo"},
  720. {0x00100102, nullptr, "GetNameInfo"},
  721. {0x00110102, GetSockOpt, "GetSockOpt"},
  722. {0x00120104, SetSockOpt, "SetSockOpt"},
  723. {0x001300C2, Fcntl, "Fcntl"},
  724. {0x00140084, Poll, "Poll"},
  725. {0x00150042, nullptr, "SockAtMark"},
  726. {0x00160000, GetHostId, "GetHostId"},
  727. {0x00170082, GetSockName, "GetSockName"},
  728. {0x00180082, GetPeerName, "GetPeerName"},
  729. {0x00190000, ShutdownSockets, "ShutdownSockets"},
  730. {0x001A00C0, nullptr, "GetNetworkOpt"},
  731. {0x001B0040, nullptr, "ICMPSocket"},
  732. {0x001C0104, nullptr, "ICMPPing"},
  733. {0x001D0040, nullptr, "ICMPCancel"},
  734. {0x001E0040, nullptr, "ICMPClose"},
  735. {0x001F0040, nullptr, "GetResolverInfo"},
  736. {0x00210002, nullptr, "CloseSockets"},
  737. {0x00230040, nullptr, "AddGlobalSocket"},
  738. };
  739. ////////////////////////////////////////////////////////////////////////////////////////////////////
  740. // Interface class
  741. Interface::Interface() {
  742. Register(FunctionTable);
  743. }
  744. Interface::~Interface() {
  745. CleanupSockets();
  746. #ifdef _WIN32
  747. WSACleanup();
  748. #endif
  749. }
  750. } // namespace