soc_u.cpp 28 KB

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