bsd.cpp 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  1. // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
  2. // SPDX-License-Identifier: GPL-2.0-or-later
  3. #include <array>
  4. #include <memory>
  5. #include <utility>
  6. #include <vector>
  7. #include <fmt/format.h>
  8. #include "common/microprofile.h"
  9. #include "common/socket_types.h"
  10. #include "core/core.h"
  11. #include "core/hle/kernel/k_thread.h"
  12. #include "core/hle/service/ipc_helpers.h"
  13. #include "core/hle/service/sockets/bsd.h"
  14. #include "core/hle/service/sockets/sockets_translate.h"
  15. #include "core/internal_network/network.h"
  16. #include "core/internal_network/socket_proxy.h"
  17. #include "core/internal_network/sockets.h"
  18. #include "network/network.h"
  19. using Common::Expected;
  20. using Common::Unexpected;
  21. namespace Service::Sockets {
  22. namespace {
  23. bool IsConnectionBased(Type type) {
  24. switch (type) {
  25. case Type::STREAM:
  26. return true;
  27. case Type::DGRAM:
  28. return false;
  29. default:
  30. UNIMPLEMENTED_MSG("Unimplemented type={}", type);
  31. return false;
  32. }
  33. }
  34. template <typename T>
  35. T GetValue(std::span<const u8> buffer) {
  36. T t{};
  37. std::memcpy(&t, buffer.data(), std::min(sizeof(T), buffer.size()));
  38. return t;
  39. }
  40. template <typename T>
  41. void PutValue(std::span<u8> buffer, const T& t) {
  42. std::memcpy(buffer.data(), &t, std::min(sizeof(T), buffer.size()));
  43. }
  44. } // Anonymous namespace
  45. void BSD::PollWork::Execute(BSD* bsd) {
  46. std::tie(ret, bsd_errno) = bsd->PollImpl(write_buffer, read_buffer, nfds, timeout);
  47. }
  48. void BSD::PollWork::Response(HLERequestContext& ctx) {
  49. if (write_buffer.size() > 0) {
  50. ctx.WriteBuffer(write_buffer);
  51. }
  52. IPC::ResponseBuilder rb{ctx, 4};
  53. rb.Push(ResultSuccess);
  54. rb.Push<s32>(ret);
  55. rb.PushEnum(bsd_errno);
  56. }
  57. void BSD::AcceptWork::Execute(BSD* bsd) {
  58. std::tie(ret, bsd_errno) = bsd->AcceptImpl(fd, write_buffer);
  59. }
  60. void BSD::AcceptWork::Response(HLERequestContext& ctx) {
  61. if (write_buffer.size() > 0) {
  62. ctx.WriteBuffer(write_buffer);
  63. }
  64. IPC::ResponseBuilder rb{ctx, 5};
  65. rb.Push(ResultSuccess);
  66. rb.Push<s32>(ret);
  67. rb.PushEnum(bsd_errno);
  68. rb.Push<u32>(static_cast<u32>(write_buffer.size()));
  69. }
  70. void BSD::ConnectWork::Execute(BSD* bsd) {
  71. bsd_errno = bsd->ConnectImpl(fd, addr);
  72. }
  73. void BSD::ConnectWork::Response(HLERequestContext& ctx) {
  74. IPC::ResponseBuilder rb{ctx, 4};
  75. rb.Push(ResultSuccess);
  76. rb.Push<s32>(bsd_errno == Errno::SUCCESS ? 0 : -1);
  77. rb.PushEnum(bsd_errno);
  78. }
  79. void BSD::RecvWork::Execute(BSD* bsd) {
  80. std::tie(ret, bsd_errno) = bsd->RecvImpl(fd, flags, message);
  81. }
  82. void BSD::RecvWork::Response(HLERequestContext& ctx) {
  83. ctx.WriteBuffer(message);
  84. IPC::ResponseBuilder rb{ctx, 4};
  85. rb.Push(ResultSuccess);
  86. rb.Push<s32>(ret);
  87. rb.PushEnum(bsd_errno);
  88. }
  89. void BSD::RecvFromWork::Execute(BSD* bsd) {
  90. std::tie(ret, bsd_errno) = bsd->RecvFromImpl(fd, flags, message, addr);
  91. }
  92. void BSD::RecvFromWork::Response(HLERequestContext& ctx) {
  93. ctx.WriteBuffer(message, 0);
  94. if (!addr.empty()) {
  95. ctx.WriteBuffer(addr, 1);
  96. }
  97. IPC::ResponseBuilder rb{ctx, 5};
  98. rb.Push(ResultSuccess);
  99. rb.Push<s32>(ret);
  100. rb.PushEnum(bsd_errno);
  101. rb.Push<u32>(static_cast<u32>(addr.size()));
  102. }
  103. void BSD::SendWork::Execute(BSD* bsd) {
  104. std::tie(ret, bsd_errno) = bsd->SendImpl(fd, flags, message);
  105. }
  106. void BSD::SendWork::Response(HLERequestContext& ctx) {
  107. IPC::ResponseBuilder rb{ctx, 4};
  108. rb.Push(ResultSuccess);
  109. rb.Push<s32>(ret);
  110. rb.PushEnum(bsd_errno);
  111. }
  112. void BSD::SendToWork::Execute(BSD* bsd) {
  113. std::tie(ret, bsd_errno) = bsd->SendToImpl(fd, flags, message, addr);
  114. }
  115. void BSD::SendToWork::Response(HLERequestContext& ctx) {
  116. IPC::ResponseBuilder rb{ctx, 4};
  117. rb.Push(ResultSuccess);
  118. rb.Push<s32>(ret);
  119. rb.PushEnum(bsd_errno);
  120. }
  121. void BSD::RegisterClient(HLERequestContext& ctx) {
  122. LOG_WARNING(Service, "(STUBBED) called");
  123. IPC::ResponseBuilder rb{ctx, 3};
  124. rb.Push(ResultSuccess);
  125. rb.Push<s32>(0); // bsd errno
  126. }
  127. void BSD::StartMonitoring(HLERequestContext& ctx) {
  128. LOG_WARNING(Service, "(STUBBED) called");
  129. IPC::ResponseBuilder rb{ctx, 2};
  130. rb.Push(ResultSuccess);
  131. }
  132. void BSD::Socket(HLERequestContext& ctx) {
  133. IPC::RequestParser rp{ctx};
  134. const u32 domain = rp.Pop<u32>();
  135. const u32 type = rp.Pop<u32>();
  136. const u32 protocol = rp.Pop<u32>();
  137. LOG_DEBUG(Service, "called. domain={} type={} protocol={}", domain, type, protocol);
  138. const auto [fd, bsd_errno] = SocketImpl(static_cast<Domain>(domain), static_cast<Type>(type),
  139. static_cast<Protocol>(protocol));
  140. IPC::ResponseBuilder rb{ctx, 4};
  141. rb.Push(ResultSuccess);
  142. rb.Push<s32>(fd);
  143. rb.PushEnum(bsd_errno);
  144. }
  145. void BSD::Select(HLERequestContext& ctx) {
  146. LOG_DEBUG(Service, "(STUBBED) called");
  147. IPC::ResponseBuilder rb{ctx, 4};
  148. rb.Push(ResultSuccess);
  149. rb.Push<u32>(0); // ret
  150. rb.Push<u32>(0); // bsd errno
  151. }
  152. void BSD::Poll(HLERequestContext& ctx) {
  153. IPC::RequestParser rp{ctx};
  154. const s32 nfds = rp.Pop<s32>();
  155. const s32 timeout = rp.Pop<s32>();
  156. LOG_DEBUG(Service, "called. nfds={} timeout={}", nfds, timeout);
  157. ExecuteWork(ctx, PollWork{
  158. .nfds = nfds,
  159. .timeout = timeout,
  160. .read_buffer = ctx.ReadBuffer(),
  161. .write_buffer = std::vector<u8>(ctx.GetWriteBufferSize()),
  162. });
  163. }
  164. void BSD::Accept(HLERequestContext& ctx) {
  165. IPC::RequestParser rp{ctx};
  166. const s32 fd = rp.Pop<s32>();
  167. LOG_DEBUG(Service, "called. fd={}", fd);
  168. ExecuteWork(ctx, AcceptWork{
  169. .fd = fd,
  170. .write_buffer = std::vector<u8>(ctx.GetWriteBufferSize()),
  171. });
  172. }
  173. void BSD::Bind(HLERequestContext& ctx) {
  174. IPC::RequestParser rp{ctx};
  175. const s32 fd = rp.Pop<s32>();
  176. LOG_DEBUG(Service, "called. fd={} addrlen={}", fd, ctx.GetReadBufferSize());
  177. BuildErrnoResponse(ctx, BindImpl(fd, ctx.ReadBuffer()));
  178. }
  179. void BSD::Connect(HLERequestContext& ctx) {
  180. IPC::RequestParser rp{ctx};
  181. const s32 fd = rp.Pop<s32>();
  182. LOG_DEBUG(Service, "called. fd={} addrlen={}", fd, ctx.GetReadBufferSize());
  183. ExecuteWork(ctx, ConnectWork{
  184. .fd = fd,
  185. .addr = ctx.ReadBuffer(),
  186. });
  187. }
  188. void BSD::GetPeerName(HLERequestContext& ctx) {
  189. IPC::RequestParser rp{ctx};
  190. const s32 fd = rp.Pop<s32>();
  191. LOG_DEBUG(Service, "called. fd={}", fd);
  192. std::vector<u8> write_buffer(ctx.GetWriteBufferSize());
  193. const Errno bsd_errno = GetPeerNameImpl(fd, write_buffer);
  194. ctx.WriteBuffer(write_buffer);
  195. IPC::ResponseBuilder rb{ctx, 5};
  196. rb.Push(ResultSuccess);
  197. rb.Push<s32>(bsd_errno != Errno::SUCCESS ? -1 : 0);
  198. rb.PushEnum(bsd_errno);
  199. rb.Push<u32>(static_cast<u32>(write_buffer.size()));
  200. }
  201. void BSD::GetSockName(HLERequestContext& ctx) {
  202. IPC::RequestParser rp{ctx};
  203. const s32 fd = rp.Pop<s32>();
  204. LOG_DEBUG(Service, "called. fd={}", fd);
  205. std::vector<u8> write_buffer(ctx.GetWriteBufferSize());
  206. const Errno bsd_errno = GetSockNameImpl(fd, write_buffer);
  207. ctx.WriteBuffer(write_buffer);
  208. IPC::ResponseBuilder rb{ctx, 5};
  209. rb.Push(ResultSuccess);
  210. rb.Push<s32>(bsd_errno != Errno::SUCCESS ? -1 : 0);
  211. rb.PushEnum(bsd_errno);
  212. rb.Push<u32>(static_cast<u32>(write_buffer.size()));
  213. }
  214. void BSD::GetSockOpt(HLERequestContext& ctx) {
  215. IPC::RequestParser rp{ctx};
  216. const s32 fd = rp.Pop<s32>();
  217. const u32 level = rp.Pop<u32>();
  218. const auto optname = static_cast<OptName>(rp.Pop<u32>());
  219. std::vector<u8> optval(ctx.GetWriteBufferSize());
  220. LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} len=0x{:x}", fd, level, optname,
  221. optval.size());
  222. const Errno err = GetSockOptImpl(fd, level, optname, optval);
  223. ctx.WriteBuffer(optval);
  224. IPC::ResponseBuilder rb{ctx, 5};
  225. rb.Push(ResultSuccess);
  226. rb.Push<s32>(err == Errno::SUCCESS ? 0 : -1);
  227. rb.PushEnum(err);
  228. rb.Push<u32>(static_cast<u32>(optval.size()));
  229. }
  230. void BSD::Listen(HLERequestContext& ctx) {
  231. IPC::RequestParser rp{ctx};
  232. const s32 fd = rp.Pop<s32>();
  233. const s32 backlog = rp.Pop<s32>();
  234. LOG_DEBUG(Service, "called. fd={} backlog={}", fd, backlog);
  235. BuildErrnoResponse(ctx, ListenImpl(fd, backlog));
  236. }
  237. void BSD::Fcntl(HLERequestContext& ctx) {
  238. IPC::RequestParser rp{ctx};
  239. const s32 fd = rp.Pop<s32>();
  240. const s32 cmd = rp.Pop<s32>();
  241. const s32 arg = rp.Pop<s32>();
  242. LOG_DEBUG(Service, "called. fd={} cmd={} arg={}", fd, cmd, arg);
  243. const auto [ret, bsd_errno] = FcntlImpl(fd, static_cast<FcntlCmd>(cmd), arg);
  244. IPC::ResponseBuilder rb{ctx, 4};
  245. rb.Push(ResultSuccess);
  246. rb.Push<s32>(ret);
  247. rb.PushEnum(bsd_errno);
  248. }
  249. void BSD::SetSockOpt(HLERequestContext& ctx) {
  250. IPC::RequestParser rp{ctx};
  251. const s32 fd = rp.Pop<s32>();
  252. const u32 level = rp.Pop<u32>();
  253. const OptName optname = static_cast<OptName>(rp.Pop<u32>());
  254. const auto optval = ctx.ReadBuffer();
  255. LOG_DEBUG(Service, "called. fd={} level={} optname=0x{:x} optlen={}", fd, level,
  256. static_cast<u32>(optname), optval.size());
  257. BuildErrnoResponse(ctx, SetSockOptImpl(fd, level, optname, optval));
  258. }
  259. void BSD::Shutdown(HLERequestContext& ctx) {
  260. IPC::RequestParser rp{ctx};
  261. const s32 fd = rp.Pop<s32>();
  262. const s32 how = rp.Pop<s32>();
  263. LOG_DEBUG(Service, "called. fd={} how={}", fd, how);
  264. BuildErrnoResponse(ctx, ShutdownImpl(fd, how));
  265. }
  266. void BSD::Recv(HLERequestContext& ctx) {
  267. IPC::RequestParser rp{ctx};
  268. const s32 fd = rp.Pop<s32>();
  269. const u32 flags = rp.Pop<u32>();
  270. LOG_DEBUG(Service, "called. fd={} flags=0x{:x} len={}", fd, flags, ctx.GetWriteBufferSize());
  271. ExecuteWork(ctx, RecvWork{
  272. .fd = fd,
  273. .flags = flags,
  274. .message = std::vector<u8>(ctx.GetWriteBufferSize()),
  275. });
  276. }
  277. void BSD::RecvFrom(HLERequestContext& ctx) {
  278. IPC::RequestParser rp{ctx};
  279. const s32 fd = rp.Pop<s32>();
  280. const u32 flags = rp.Pop<u32>();
  281. LOG_DEBUG(Service, "called. fd={} flags=0x{:x} len={} addrlen={}", fd, flags,
  282. ctx.GetWriteBufferSize(0), ctx.GetWriteBufferSize(1));
  283. ExecuteWork(ctx, RecvFromWork{
  284. .fd = fd,
  285. .flags = flags,
  286. .message = std::vector<u8>(ctx.GetWriteBufferSize(0)),
  287. .addr = std::vector<u8>(ctx.GetWriteBufferSize(1)),
  288. });
  289. }
  290. void BSD::Send(HLERequestContext& ctx) {
  291. IPC::RequestParser rp{ctx};
  292. const s32 fd = rp.Pop<s32>();
  293. const u32 flags = rp.Pop<u32>();
  294. LOG_DEBUG(Service, "called. fd={} flags=0x{:x} len={}", fd, flags, ctx.GetReadBufferSize());
  295. ExecuteWork(ctx, SendWork{
  296. .fd = fd,
  297. .flags = flags,
  298. .message = ctx.ReadBuffer(),
  299. });
  300. }
  301. void BSD::SendTo(HLERequestContext& ctx) {
  302. IPC::RequestParser rp{ctx};
  303. const s32 fd = rp.Pop<s32>();
  304. const u32 flags = rp.Pop<u32>();
  305. LOG_DEBUG(Service, "called. fd={} flags=0x{} len={} addrlen={}", fd, flags,
  306. ctx.GetReadBufferSize(0), ctx.GetReadBufferSize(1));
  307. ExecuteWork(ctx, SendToWork{
  308. .fd = fd,
  309. .flags = flags,
  310. .message = ctx.ReadBuffer(0),
  311. .addr = ctx.ReadBuffer(1),
  312. });
  313. }
  314. void BSD::Write(HLERequestContext& ctx) {
  315. IPC::RequestParser rp{ctx};
  316. const s32 fd = rp.Pop<s32>();
  317. LOG_DEBUG(Service, "called. fd={} len={}", fd, ctx.GetReadBufferSize());
  318. ExecuteWork(ctx, SendWork{
  319. .fd = fd,
  320. .flags = 0,
  321. .message = ctx.ReadBuffer(),
  322. });
  323. }
  324. void BSD::Read(HLERequestContext& ctx) {
  325. IPC::RequestParser rp{ctx};
  326. const s32 fd = rp.Pop<s32>();
  327. LOG_WARNING(Service, "(STUBBED) called. fd={} len={}", fd, ctx.GetWriteBufferSize());
  328. IPC::ResponseBuilder rb{ctx, 4};
  329. rb.Push(ResultSuccess);
  330. rb.Push<u32>(0); // ret
  331. rb.Push<u32>(0); // bsd errno
  332. }
  333. void BSD::Close(HLERequestContext& ctx) {
  334. IPC::RequestParser rp{ctx};
  335. const s32 fd = rp.Pop<s32>();
  336. LOG_DEBUG(Service, "called. fd={}", fd);
  337. BuildErrnoResponse(ctx, CloseImpl(fd));
  338. }
  339. void BSD::DuplicateSocket(HLERequestContext& ctx) {
  340. struct InputParameters {
  341. s32 fd;
  342. u64 reserved;
  343. };
  344. static_assert(sizeof(InputParameters) == 0x10);
  345. struct OutputParameters {
  346. s32 ret;
  347. Errno bsd_errno;
  348. };
  349. static_assert(sizeof(OutputParameters) == 0x8);
  350. IPC::RequestParser rp{ctx};
  351. auto input = rp.PopRaw<InputParameters>();
  352. Expected<s32, Errno> res = DuplicateSocketImpl(input.fd);
  353. IPC::ResponseBuilder rb{ctx, 4};
  354. rb.Push(ResultSuccess);
  355. rb.PushRaw(OutputParameters{
  356. .ret = res.value_or(0),
  357. .bsd_errno = res ? Errno::SUCCESS : res.error(),
  358. });
  359. }
  360. void BSD::EventFd(HLERequestContext& ctx) {
  361. IPC::RequestParser rp{ctx};
  362. const u64 initval = rp.Pop<u64>();
  363. const u32 flags = rp.Pop<u32>();
  364. LOG_WARNING(Service, "(STUBBED) called. initval={}, flags={}", initval, flags);
  365. BuildErrnoResponse(ctx, Errno::SUCCESS);
  366. }
  367. template <typename Work>
  368. void BSD::ExecuteWork(HLERequestContext& ctx, Work work) {
  369. work.Execute(this);
  370. work.Response(ctx);
  371. }
  372. std::pair<s32, Errno> BSD::SocketImpl(Domain domain, Type type, Protocol protocol) {
  373. if (type == Type::SEQPACKET) {
  374. UNIMPLEMENTED_MSG("SOCK_SEQPACKET errno management");
  375. } else if (type == Type::RAW && (domain != Domain::INET || protocol != Protocol::ICMP)) {
  376. UNIMPLEMENTED_MSG("SOCK_RAW errno management");
  377. }
  378. [[maybe_unused]] const bool unk_flag = (static_cast<u32>(type) & 0x20000000) != 0;
  379. UNIMPLEMENTED_IF_MSG(unk_flag, "Unknown flag in type");
  380. type = static_cast<Type>(static_cast<u32>(type) & ~0x20000000);
  381. const s32 fd = FindFreeFileDescriptorHandle();
  382. if (fd < 0) {
  383. LOG_ERROR(Service, "No more file descriptors available");
  384. return {-1, Errno::MFILE};
  385. }
  386. file_descriptors[fd] = FileDescriptor{};
  387. FileDescriptor& descriptor = *file_descriptors[fd];
  388. // ENONMEM might be thrown here
  389. LOG_INFO(Service, "New socket fd={}", fd);
  390. auto room_member = room_network.GetRoomMember().lock();
  391. if (room_member && room_member->IsConnected()) {
  392. descriptor.socket = std::make_shared<Network::ProxySocket>(room_network);
  393. } else {
  394. descriptor.socket = std::make_shared<Network::Socket>();
  395. }
  396. descriptor.socket->Initialize(Translate(domain), Translate(type), Translate(protocol));
  397. descriptor.is_connection_based = IsConnectionBased(type);
  398. return {fd, Errno::SUCCESS};
  399. }
  400. std::pair<s32, Errno> BSD::PollImpl(std::vector<u8>& write_buffer, std::span<const u8> read_buffer,
  401. s32 nfds, s32 timeout) {
  402. if (nfds <= 0) {
  403. // When no entries are provided, -1 is returned with errno zero
  404. return {-1, Errno::SUCCESS};
  405. }
  406. if (read_buffer.size() < nfds * sizeof(PollFD)) {
  407. return {-1, Errno::INVAL};
  408. }
  409. if (write_buffer.size() < nfds * sizeof(PollFD)) {
  410. return {-1, Errno::INVAL};
  411. }
  412. std::vector<PollFD> fds(nfds);
  413. std::memcpy(fds.data(), read_buffer.data(), nfds * sizeof(PollFD));
  414. if (timeout >= 0) {
  415. const s64 seconds = timeout / 1000;
  416. const u64 nanoseconds = 1'000'000 * (static_cast<u64>(timeout) % 1000);
  417. if (seconds < 0) {
  418. return {-1, Errno::INVAL};
  419. }
  420. if (nanoseconds > 999'999'999) {
  421. return {-1, Errno::INVAL};
  422. }
  423. } else if (timeout != -1) {
  424. return {-1, Errno::INVAL};
  425. }
  426. for (PollFD& pollfd : fds) {
  427. ASSERT(False(pollfd.revents));
  428. if (pollfd.fd > static_cast<s32>(MAX_FD) || pollfd.fd < 0) {
  429. LOG_ERROR(Service, "File descriptor handle={} is invalid", pollfd.fd);
  430. pollfd.revents = PollEvents{};
  431. return {0, Errno::SUCCESS};
  432. }
  433. const std::optional<FileDescriptor>& descriptor = file_descriptors[pollfd.fd];
  434. if (!descriptor) {
  435. LOG_TRACE(Service, "File descriptor handle={} is not allocated", pollfd.fd);
  436. pollfd.revents = PollEvents::Nval;
  437. return {0, Errno::SUCCESS};
  438. }
  439. }
  440. std::vector<Network::PollFD> host_pollfds(fds.size());
  441. std::transform(fds.begin(), fds.end(), host_pollfds.begin(), [this](PollFD pollfd) {
  442. Network::PollFD result;
  443. result.socket = file_descriptors[pollfd.fd]->socket.get();
  444. result.events = Translate(pollfd.events);
  445. result.revents = Network::PollEvents{};
  446. return result;
  447. });
  448. const auto result = Network::Poll(host_pollfds, timeout);
  449. const size_t num = host_pollfds.size();
  450. for (size_t i = 0; i < num; ++i) {
  451. fds[i].revents = Translate(host_pollfds[i].revents);
  452. }
  453. std::memcpy(write_buffer.data(), fds.data(), nfds * sizeof(PollFD));
  454. return Translate(result);
  455. }
  456. std::pair<s32, Errno> BSD::AcceptImpl(s32 fd, std::vector<u8>& write_buffer) {
  457. if (!IsFileDescriptorValid(fd)) {
  458. return {-1, Errno::BADF};
  459. }
  460. const s32 new_fd = FindFreeFileDescriptorHandle();
  461. if (new_fd < 0) {
  462. LOG_ERROR(Service, "No more file descriptors available");
  463. return {-1, Errno::MFILE};
  464. }
  465. FileDescriptor& descriptor = *file_descriptors[fd];
  466. auto [result, bsd_errno] = descriptor.socket->Accept();
  467. if (bsd_errno != Network::Errno::SUCCESS) {
  468. return {-1, Translate(bsd_errno)};
  469. }
  470. file_descriptors[new_fd] = FileDescriptor{};
  471. FileDescriptor& new_descriptor = *file_descriptors[new_fd];
  472. new_descriptor.socket = std::move(result.socket);
  473. new_descriptor.is_connection_based = descriptor.is_connection_based;
  474. const SockAddrIn guest_addr_in = Translate(result.sockaddr_in);
  475. PutValue(write_buffer, guest_addr_in);
  476. return {new_fd, Errno::SUCCESS};
  477. }
  478. Errno BSD::BindImpl(s32 fd, std::span<const u8> addr) {
  479. if (!IsFileDescriptorValid(fd)) {
  480. return Errno::BADF;
  481. }
  482. ASSERT(addr.size() == sizeof(SockAddrIn));
  483. auto addr_in = GetValue<SockAddrIn>(addr);
  484. return Translate(file_descriptors[fd]->socket->Bind(Translate(addr_in)));
  485. }
  486. Errno BSD::ConnectImpl(s32 fd, std::span<const u8> addr) {
  487. if (!IsFileDescriptorValid(fd)) {
  488. return Errno::BADF;
  489. }
  490. UNIMPLEMENTED_IF(addr.size() != sizeof(SockAddrIn));
  491. auto addr_in = GetValue<SockAddrIn>(addr);
  492. return Translate(file_descriptors[fd]->socket->Connect(Translate(addr_in)));
  493. }
  494. Errno BSD::GetPeerNameImpl(s32 fd, std::vector<u8>& write_buffer) {
  495. if (!IsFileDescriptorValid(fd)) {
  496. return Errno::BADF;
  497. }
  498. const auto [addr_in, bsd_errno] = file_descriptors[fd]->socket->GetPeerName();
  499. if (bsd_errno != Network::Errno::SUCCESS) {
  500. return Translate(bsd_errno);
  501. }
  502. const SockAddrIn guest_addrin = Translate(addr_in);
  503. ASSERT(write_buffer.size() >= sizeof(guest_addrin));
  504. write_buffer.resize(sizeof(guest_addrin));
  505. PutValue(write_buffer, guest_addrin);
  506. return Translate(bsd_errno);
  507. }
  508. Errno BSD::GetSockNameImpl(s32 fd, std::vector<u8>& write_buffer) {
  509. if (!IsFileDescriptorValid(fd)) {
  510. return Errno::BADF;
  511. }
  512. const auto [addr_in, bsd_errno] = file_descriptors[fd]->socket->GetSockName();
  513. if (bsd_errno != Network::Errno::SUCCESS) {
  514. return Translate(bsd_errno);
  515. }
  516. const SockAddrIn guest_addrin = Translate(addr_in);
  517. ASSERT(write_buffer.size() >= sizeof(guest_addrin));
  518. write_buffer.resize(sizeof(guest_addrin));
  519. PutValue(write_buffer, guest_addrin);
  520. return Translate(bsd_errno);
  521. }
  522. Errno BSD::ListenImpl(s32 fd, s32 backlog) {
  523. if (!IsFileDescriptorValid(fd)) {
  524. return Errno::BADF;
  525. }
  526. return Translate(file_descriptors[fd]->socket->Listen(backlog));
  527. }
  528. std::pair<s32, Errno> BSD::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) {
  529. if (!IsFileDescriptorValid(fd)) {
  530. return {-1, Errno::BADF};
  531. }
  532. FileDescriptor& descriptor = *file_descriptors[fd];
  533. switch (cmd) {
  534. case FcntlCmd::GETFL:
  535. ASSERT(arg == 0);
  536. return {descriptor.flags, Errno::SUCCESS};
  537. case FcntlCmd::SETFL: {
  538. const bool enable = (arg & Network::FLAG_O_NONBLOCK) != 0;
  539. const Errno bsd_errno = Translate(descriptor.socket->SetNonBlock(enable));
  540. if (bsd_errno != Errno::SUCCESS) {
  541. return {-1, bsd_errno};
  542. }
  543. descriptor.flags = arg;
  544. return {0, Errno::SUCCESS};
  545. }
  546. default:
  547. UNIMPLEMENTED_MSG("Unimplemented cmd={}", cmd);
  548. return {-1, Errno::SUCCESS};
  549. }
  550. }
  551. Errno BSD::GetSockOptImpl(s32 fd, u32 level, OptName optname, std::vector<u8>& optval) {
  552. if (!IsFileDescriptorValid(fd)) {
  553. return Errno::BADF;
  554. }
  555. if (level != static_cast<u32>(SocketLevel::SOCKET)) {
  556. UNIMPLEMENTED_MSG("Unknown getsockopt level");
  557. return Errno::SUCCESS;
  558. }
  559. Network::SocketBase* const socket = file_descriptors[fd]->socket.get();
  560. switch (optname) {
  561. case OptName::ERROR_: {
  562. auto [pending_err, getsockopt_err] = socket->GetPendingError();
  563. if (getsockopt_err == Network::Errno::SUCCESS) {
  564. Errno translated_pending_err = Translate(pending_err);
  565. ASSERT_OR_EXECUTE_MSG(
  566. optval.size() == sizeof(Errno), { return Errno::INVAL; },
  567. "Incorrect getsockopt option size");
  568. optval.resize(sizeof(Errno));
  569. PutValue(optval, translated_pending_err);
  570. }
  571. return Translate(getsockopt_err);
  572. }
  573. default:
  574. UNIMPLEMENTED_MSG("Unimplemented optname={}", optname);
  575. return Errno::SUCCESS;
  576. }
  577. }
  578. Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, std::span<const u8> optval) {
  579. if (!IsFileDescriptorValid(fd)) {
  580. return Errno::BADF;
  581. }
  582. if (level != static_cast<u32>(SocketLevel::SOCKET)) {
  583. UNIMPLEMENTED_MSG("Unknown setsockopt level");
  584. return Errno::SUCCESS;
  585. }
  586. Network::SocketBase* const socket = file_descriptors[fd]->socket.get();
  587. if (optname == OptName::LINGER) {
  588. ASSERT(optval.size() == sizeof(Linger));
  589. auto linger = GetValue<Linger>(optval);
  590. ASSERT(linger.onoff == 0 || linger.onoff == 1);
  591. return Translate(socket->SetLinger(linger.onoff != 0, linger.linger));
  592. }
  593. ASSERT(optval.size() == sizeof(u32));
  594. auto value = GetValue<u32>(optval);
  595. switch (optname) {
  596. case OptName::REUSEADDR:
  597. ASSERT(value == 0 || value == 1);
  598. return Translate(socket->SetReuseAddr(value != 0));
  599. case OptName::KEEPALIVE:
  600. ASSERT(value == 0 || value == 1);
  601. return Translate(socket->SetKeepAlive(value != 0));
  602. case OptName::BROADCAST:
  603. ASSERT(value == 0 || value == 1);
  604. return Translate(socket->SetBroadcast(value != 0));
  605. case OptName::SNDBUF:
  606. return Translate(socket->SetSndBuf(value));
  607. case OptName::RCVBUF:
  608. return Translate(socket->SetRcvBuf(value));
  609. case OptName::SNDTIMEO:
  610. return Translate(socket->SetSndTimeo(value));
  611. case OptName::RCVTIMEO:
  612. return Translate(socket->SetRcvTimeo(value));
  613. case OptName::NOSIGPIPE:
  614. LOG_WARNING(Service, "(STUBBED) setting NOSIGPIPE to {}", value);
  615. return Errno::SUCCESS;
  616. default:
  617. UNIMPLEMENTED_MSG("Unimplemented optname={}", optname);
  618. return Errno::SUCCESS;
  619. }
  620. }
  621. Errno BSD::ShutdownImpl(s32 fd, s32 how) {
  622. if (!IsFileDescriptorValid(fd)) {
  623. return Errno::BADF;
  624. }
  625. const Network::ShutdownHow host_how = Translate(static_cast<ShutdownHow>(how));
  626. return Translate(file_descriptors[fd]->socket->Shutdown(host_how));
  627. }
  628. std::pair<s32, Errno> BSD::RecvImpl(s32 fd, u32 flags, std::vector<u8>& message) {
  629. if (!IsFileDescriptorValid(fd)) {
  630. return {-1, Errno::BADF};
  631. }
  632. FileDescriptor& descriptor = *file_descriptors[fd];
  633. // Apply flags
  634. using Network::FLAG_MSG_DONTWAIT;
  635. using Network::FLAG_O_NONBLOCK;
  636. if ((flags & FLAG_MSG_DONTWAIT) != 0) {
  637. flags &= ~FLAG_MSG_DONTWAIT;
  638. if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
  639. descriptor.socket->SetNonBlock(true);
  640. }
  641. }
  642. const auto [ret, bsd_errno] = Translate(descriptor.socket->Recv(flags, message));
  643. // Restore original state
  644. if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
  645. descriptor.socket->SetNonBlock(false);
  646. }
  647. return {ret, bsd_errno};
  648. }
  649. std::pair<s32, Errno> BSD::RecvFromImpl(s32 fd, u32 flags, std::vector<u8>& message,
  650. std::vector<u8>& addr) {
  651. if (!IsFileDescriptorValid(fd)) {
  652. return {-1, Errno::BADF};
  653. }
  654. FileDescriptor& descriptor = *file_descriptors[fd];
  655. Network::SockAddrIn addr_in{};
  656. Network::SockAddrIn* p_addr_in = nullptr;
  657. if (descriptor.is_connection_based) {
  658. // Connection based file descriptors (e.g. TCP) zero addr
  659. addr.clear();
  660. } else {
  661. p_addr_in = &addr_in;
  662. }
  663. // Apply flags
  664. using Network::FLAG_MSG_DONTWAIT;
  665. using Network::FLAG_O_NONBLOCK;
  666. if ((flags & FLAG_MSG_DONTWAIT) != 0) {
  667. flags &= ~FLAG_MSG_DONTWAIT;
  668. if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
  669. descriptor.socket->SetNonBlock(true);
  670. }
  671. }
  672. const auto [ret, bsd_errno] = Translate(descriptor.socket->RecvFrom(flags, message, p_addr_in));
  673. // Restore original state
  674. if ((descriptor.flags & FLAG_O_NONBLOCK) == 0) {
  675. descriptor.socket->SetNonBlock(false);
  676. }
  677. if (p_addr_in) {
  678. if (ret < 0) {
  679. addr.clear();
  680. } else {
  681. ASSERT(addr.size() == sizeof(SockAddrIn));
  682. const SockAddrIn result = Translate(addr_in);
  683. PutValue(addr, result);
  684. }
  685. }
  686. return {ret, bsd_errno};
  687. }
  688. std::pair<s32, Errno> BSD::SendImpl(s32 fd, u32 flags, std::span<const u8> message) {
  689. if (!IsFileDescriptorValid(fd)) {
  690. return {-1, Errno::BADF};
  691. }
  692. return Translate(file_descriptors[fd]->socket->Send(message, flags));
  693. }
  694. std::pair<s32, Errno> BSD::SendToImpl(s32 fd, u32 flags, std::span<const u8> message,
  695. std::span<const u8> addr) {
  696. if (!IsFileDescriptorValid(fd)) {
  697. return {-1, Errno::BADF};
  698. }
  699. Network::SockAddrIn addr_in;
  700. Network::SockAddrIn* p_addr_in = nullptr;
  701. if (!addr.empty()) {
  702. ASSERT(addr.size() == sizeof(SockAddrIn));
  703. auto guest_addr_in = GetValue<SockAddrIn>(addr);
  704. addr_in = Translate(guest_addr_in);
  705. p_addr_in = &addr_in;
  706. }
  707. return Translate(file_descriptors[fd]->socket->SendTo(flags, message, p_addr_in));
  708. }
  709. Errno BSD::CloseImpl(s32 fd) {
  710. if (!IsFileDescriptorValid(fd)) {
  711. return Errno::BADF;
  712. }
  713. const Errno bsd_errno = Translate(file_descriptors[fd]->socket->Close());
  714. if (bsd_errno != Errno::SUCCESS) {
  715. return bsd_errno;
  716. }
  717. LOG_INFO(Service, "Close socket fd={}", fd);
  718. file_descriptors[fd].reset();
  719. return bsd_errno;
  720. }
  721. Expected<s32, Errno> BSD::DuplicateSocketImpl(s32 fd) {
  722. if (!IsFileDescriptorValid(fd)) {
  723. return Unexpected(Errno::BADF);
  724. }
  725. const s32 new_fd = FindFreeFileDescriptorHandle();
  726. if (new_fd < 0) {
  727. LOG_ERROR(Service, "No more file descriptors available");
  728. return Unexpected(Errno::MFILE);
  729. }
  730. file_descriptors[new_fd] = file_descriptors[fd];
  731. return new_fd;
  732. }
  733. std::optional<std::shared_ptr<Network::SocketBase>> BSD::GetSocket(s32 fd) {
  734. if (!IsFileDescriptorValid(fd)) {
  735. return std::nullopt;
  736. }
  737. return file_descriptors[fd]->socket;
  738. }
  739. s32 BSD::FindFreeFileDescriptorHandle() noexcept {
  740. for (s32 fd = 0; fd < static_cast<s32>(file_descriptors.size()); ++fd) {
  741. if (!file_descriptors[fd]) {
  742. return fd;
  743. }
  744. }
  745. return -1;
  746. }
  747. bool BSD::IsFileDescriptorValid(s32 fd) const noexcept {
  748. if (fd > static_cast<s32>(MAX_FD) || fd < 0) {
  749. LOG_ERROR(Service, "Invalid file descriptor handle={}", fd);
  750. return false;
  751. }
  752. if (!file_descriptors[fd]) {
  753. LOG_ERROR(Service, "File descriptor handle={} is not allocated", fd);
  754. return false;
  755. }
  756. return true;
  757. }
  758. void BSD::BuildErrnoResponse(HLERequestContext& ctx, Errno bsd_errno) const noexcept {
  759. IPC::ResponseBuilder rb{ctx, 4};
  760. rb.Push(ResultSuccess);
  761. rb.Push<s32>(bsd_errno == Errno::SUCCESS ? 0 : -1);
  762. rb.PushEnum(bsd_errno);
  763. }
  764. void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
  765. for (auto& optional_descriptor : file_descriptors) {
  766. if (!optional_descriptor.has_value()) {
  767. continue;
  768. }
  769. FileDescriptor& descriptor = *optional_descriptor;
  770. descriptor.socket.get()->HandleProxyPacket(packet);
  771. }
  772. }
  773. BSD::BSD(Core::System& system_, const char* name)
  774. : ServiceFramework{system_, name}, room_network{system_.GetRoomNetwork()} {
  775. // clang-format off
  776. static const FunctionInfo functions[] = {
  777. {0, &BSD::RegisterClient, "RegisterClient"},
  778. {1, &BSD::StartMonitoring, "StartMonitoring"},
  779. {2, &BSD::Socket, "Socket"},
  780. {3, nullptr, "SocketExempt"},
  781. {4, nullptr, "Open"},
  782. {5, &BSD::Select, "Select"},
  783. {6, &BSD::Poll, "Poll"},
  784. {7, nullptr, "Sysctl"},
  785. {8, &BSD::Recv, "Recv"},
  786. {9, &BSD::RecvFrom, "RecvFrom"},
  787. {10, &BSD::Send, "Send"},
  788. {11, &BSD::SendTo, "SendTo"},
  789. {12, &BSD::Accept, "Accept"},
  790. {13, &BSD::Bind, "Bind"},
  791. {14, &BSD::Connect, "Connect"},
  792. {15, &BSD::GetPeerName, "GetPeerName"},
  793. {16, &BSD::GetSockName, "GetSockName"},
  794. {17, &BSD::GetSockOpt, "GetSockOpt"},
  795. {18, &BSD::Listen, "Listen"},
  796. {19, nullptr, "Ioctl"},
  797. {20, &BSD::Fcntl, "Fcntl"},
  798. {21, &BSD::SetSockOpt, "SetSockOpt"},
  799. {22, &BSD::Shutdown, "Shutdown"},
  800. {23, nullptr, "ShutdownAllSockets"},
  801. {24, &BSD::Write, "Write"},
  802. {25, &BSD::Read, "Read"},
  803. {26, &BSD::Close, "Close"},
  804. {27, &BSD::DuplicateSocket, "DuplicateSocket"},
  805. {28, nullptr, "GetResourceStatistics"},
  806. {29, nullptr, "RecvMMsg"},
  807. {30, nullptr, "SendMMsg"},
  808. {31, &BSD::EventFd, "EventFd"},
  809. {32, nullptr, "RegisterResourceStatisticsName"},
  810. {33, nullptr, "Initialize2"},
  811. };
  812. // clang-format on
  813. RegisterHandlers(functions);
  814. if (auto room_member = room_network.GetRoomMember().lock()) {
  815. proxy_packet_received = room_member->BindOnProxyPacketReceived(
  816. [this](const Network::ProxyPacket& packet) { OnProxyPacketReceived(packet); });
  817. } else {
  818. LOG_ERROR(Service, "Network isn't initialized");
  819. }
  820. }
  821. BSD::~BSD() {
  822. if (auto room_member = room_network.GetRoomMember().lock()) {
  823. room_member->Unbind(proxy_packet_received);
  824. }
  825. }
  826. std::unique_lock<std::mutex> BSD::LockService() {
  827. // Do not lock socket IClient instances.
  828. return {};
  829. }
  830. BSDCFG::BSDCFG(Core::System& system_) : ServiceFramework{system_, "bsdcfg"} {
  831. // clang-format off
  832. static const FunctionInfo functions[] = {
  833. {0, nullptr, "SetIfUp"},
  834. {1, nullptr, "SetIfUpWithEvent"},
  835. {2, nullptr, "CancelIf"},
  836. {3, nullptr, "SetIfDown"},
  837. {4, nullptr, "GetIfState"},
  838. {5, nullptr, "DhcpRenew"},
  839. {6, nullptr, "AddStaticArpEntry"},
  840. {7, nullptr, "RemoveArpEntry"},
  841. {8, nullptr, "LookupArpEntry"},
  842. {9, nullptr, "LookupArpEntry2"},
  843. {10, nullptr, "ClearArpEntries"},
  844. {11, nullptr, "ClearArpEntries2"},
  845. {12, nullptr, "PrintArpEntries"},
  846. {13, nullptr, "Unknown13"},
  847. {14, nullptr, "Unknown14"},
  848. {15, nullptr, "Unknown15"},
  849. };
  850. // clang-format on
  851. RegisterHandlers(functions);
  852. }
  853. BSDCFG::~BSDCFG() = default;
  854. } // namespace Service::Sockets