summaryrefslogtreecommitdiff
path: root/src/core/internal_network
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/internal_network')
-rw-r--r--src/core/internal_network/network.cpp274
-rw-r--r--src/core/internal_network/network.h34
-rw-r--r--src/core/internal_network/socket_proxy.cpp22
-rw-r--r--src/core/internal_network/socket_proxy.h8
-rw-r--r--src/core/internal_network/sockets.h16
5 files changed, 281 insertions, 73 deletions
diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp
index 75ac10a9c..39381e06e 100644
--- a/src/core/internal_network/network.cpp
+++ b/src/core/internal_network/network.cpp
@@ -121,6 +121,8 @@ Errno TranslateNativeError(int e) {
121 return Errno::MSGSIZE; 121 return Errno::MSGSIZE;
122 case WSAETIMEDOUT: 122 case WSAETIMEDOUT:
123 return Errno::TIMEDOUT; 123 return Errno::TIMEDOUT;
124 case WSAEINPROGRESS:
125 return Errno::INPROGRESS;
124 default: 126 default:
125 UNIMPLEMENTED_MSG("Unimplemented errno={}", e); 127 UNIMPLEMENTED_MSG("Unimplemented errno={}", e);
126 return Errno::OTHER; 128 return Errno::OTHER;
@@ -195,6 +197,8 @@ bool EnableNonBlock(int fd, bool enable) {
195 197
196Errno TranslateNativeError(int e) { 198Errno TranslateNativeError(int e) {
197 switch (e) { 199 switch (e) {
200 case 0:
201 return Errno::SUCCESS;
198 case EBADF: 202 case EBADF:
199 return Errno::BADF; 203 return Errno::BADF;
200 case EINVAL: 204 case EINVAL:
@@ -219,8 +223,10 @@ Errno TranslateNativeError(int e) {
219 return Errno::MSGSIZE; 223 return Errno::MSGSIZE;
220 case ETIMEDOUT: 224 case ETIMEDOUT:
221 return Errno::TIMEDOUT; 225 return Errno::TIMEDOUT;
226 case EINPROGRESS:
227 return Errno::INPROGRESS;
222 default: 228 default:
223 UNIMPLEMENTED_MSG("Unimplemented errno={}", e); 229 UNIMPLEMENTED_MSG("Unimplemented errno={} ({})", e, strerror(e));
224 return Errno::OTHER; 230 return Errno::OTHER;
225 } 231 }
226} 232}
@@ -234,15 +240,84 @@ Errno GetAndLogLastError() {
234 int e = errno; 240 int e = errno;
235#endif 241#endif
236 const Errno err = TranslateNativeError(e); 242 const Errno err = TranslateNativeError(e);
237 if (err == Errno::AGAIN || err == Errno::TIMEDOUT) { 243 if (err == Errno::AGAIN || err == Errno::TIMEDOUT || err == Errno::INPROGRESS) {
244 // These happen during normal operation, so only log them at debug level.
245 LOG_DEBUG(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
238 return err; 246 return err;
239 } 247 }
240 LOG_ERROR(Network, "Socket operation error: {}", Common::NativeErrorToString(e)); 248 LOG_ERROR(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
241 return err; 249 return err;
242} 250}
243 251
244int TranslateDomain(Domain domain) { 252GetAddrInfoError TranslateGetAddrInfoErrorFromNative(int gai_err) {
253 switch (gai_err) {
254 case 0:
255 return GetAddrInfoError::SUCCESS;
256#ifdef EAI_ADDRFAMILY
257 case EAI_ADDRFAMILY:
258 return GetAddrInfoError::ADDRFAMILY;
259#endif
260 case EAI_AGAIN:
261 return GetAddrInfoError::AGAIN;
262 case EAI_BADFLAGS:
263 return GetAddrInfoError::BADFLAGS;
264 case EAI_FAIL:
265 return GetAddrInfoError::FAIL;
266 case EAI_FAMILY:
267 return GetAddrInfoError::FAMILY;
268 case EAI_MEMORY:
269 return GetAddrInfoError::MEMORY;
270 case EAI_NONAME:
271 return GetAddrInfoError::NONAME;
272 case EAI_SERVICE:
273 return GetAddrInfoError::SERVICE;
274 case EAI_SOCKTYPE:
275 return GetAddrInfoError::SOCKTYPE;
276 // These codes may not be defined on all systems:
277#ifdef EAI_SYSTEM
278 case EAI_SYSTEM:
279 return GetAddrInfoError::SYSTEM;
280#endif
281#ifdef EAI_BADHINTS
282 case EAI_BADHINTS:
283 return GetAddrInfoError::BADHINTS;
284#endif
285#ifdef EAI_PROTOCOL
286 case EAI_PROTOCOL:
287 return GetAddrInfoError::PROTOCOL;
288#endif
289#ifdef EAI_OVERFLOW
290 case EAI_OVERFLOW:
291 return GetAddrInfoError::OVERFLOW_;
292#endif
293 default:
294#ifdef EAI_NODATA
295 // This can't be a case statement because it would create a duplicate
296 // case on Windows where EAI_NODATA is an alias for EAI_NONAME.
297 if (gai_err == EAI_NODATA) {
298 return GetAddrInfoError::NODATA;
299 }
300#endif
301 return GetAddrInfoError::OTHER;
302 }
303}
304
305Domain TranslateDomainFromNative(int domain) {
245 switch (domain) { 306 switch (domain) {
307 case 0:
308 return Domain::Unspecified;
309 case AF_INET:
310 return Domain::INET;
311 default:
312 UNIMPLEMENTED_MSG("Unhandled domain={}", domain);
313 return Domain::INET;
314 }
315}
316
317int TranslateDomainToNative(Domain domain) {
318 switch (domain) {
319 case Domain::Unspecified:
320 return 0;
246 case Domain::INET: 321 case Domain::INET:
247 return AF_INET; 322 return AF_INET;
248 default: 323 default:
@@ -251,20 +326,58 @@ int TranslateDomain(Domain domain) {
251 } 326 }
252} 327}
253 328
254int TranslateType(Type type) { 329Type TranslateTypeFromNative(int type) {
330 switch (type) {
331 case 0:
332 return Type::Unspecified;
333 case SOCK_STREAM:
334 return Type::STREAM;
335 case SOCK_DGRAM:
336 return Type::DGRAM;
337 case SOCK_RAW:
338 return Type::RAW;
339 case SOCK_SEQPACKET:
340 return Type::SEQPACKET;
341 default:
342 UNIMPLEMENTED_MSG("Unimplemented type={}", type);
343 return Type::STREAM;
344 }
345}
346
347int TranslateTypeToNative(Type type) {
255 switch (type) { 348 switch (type) {
349 case Type::Unspecified:
350 return 0;
256 case Type::STREAM: 351 case Type::STREAM:
257 return SOCK_STREAM; 352 return SOCK_STREAM;
258 case Type::DGRAM: 353 case Type::DGRAM:
259 return SOCK_DGRAM; 354 return SOCK_DGRAM;
355 case Type::RAW:
356 return SOCK_RAW;
260 default: 357 default:
261 UNIMPLEMENTED_MSG("Unimplemented type={}", type); 358 UNIMPLEMENTED_MSG("Unimplemented type={}", type);
262 return 0; 359 return 0;
263 } 360 }
264} 361}
265 362
266int TranslateProtocol(Protocol protocol) { 363Protocol TranslateProtocolFromNative(int protocol) {
364 switch (protocol) {
365 case 0:
366 return Protocol::Unspecified;
367 case IPPROTO_TCP:
368 return Protocol::TCP;
369 case IPPROTO_UDP:
370 return Protocol::UDP;
371 default:
372 UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol);
373 return Protocol::Unspecified;
374 }
375}
376
377int TranslateProtocolToNative(Protocol protocol) {
267 switch (protocol) { 378 switch (protocol) {
379 case Protocol::Unspecified:
380 return 0;
268 case Protocol::TCP: 381 case Protocol::TCP:
269 return IPPROTO_TCP; 382 return IPPROTO_TCP;
270 case Protocol::UDP: 383 case Protocol::UDP:
@@ -275,21 +388,10 @@ int TranslateProtocol(Protocol protocol) {
275 } 388 }
276} 389}
277 390
278SockAddrIn TranslateToSockAddrIn(sockaddr input_) { 391SockAddrIn TranslateToSockAddrIn(sockaddr_in input, size_t input_len) {
279 sockaddr_in input;
280 std::memcpy(&input, &input_, sizeof(input));
281
282 SockAddrIn result; 392 SockAddrIn result;
283 393
284 switch (input.sin_family) { 394 result.family = TranslateDomainFromNative(input.sin_family);
285 case AF_INET:
286 result.family = Domain::INET;
287 break;
288 default:
289 UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", input.sin_family);
290 result.family = Domain::INET;
291 break;
292 }
293 395
294 result.portno = ntohs(input.sin_port); 396 result.portno = ntohs(input.sin_port);
295 397
@@ -301,22 +403,28 @@ SockAddrIn TranslateToSockAddrIn(sockaddr input_) {
301short TranslatePollEvents(PollEvents events) { 403short TranslatePollEvents(PollEvents events) {
302 short result = 0; 404 short result = 0;
303 405
304 if (True(events & PollEvents::In)) { 406 const auto translate = [&result, &events](PollEvents guest, short host) {
305 events &= ~PollEvents::In; 407 if (True(events & guest)) {
306 result |= POLLIN; 408 events &= ~guest;
307 } 409 result |= host;
308 if (True(events & PollEvents::Pri)) { 410 }
309 events &= ~PollEvents::Pri; 411 };
412
413 translate(PollEvents::In, POLLIN);
414 translate(PollEvents::Pri, POLLPRI);
415 translate(PollEvents::Out, POLLOUT);
416 translate(PollEvents::Err, POLLERR);
417 translate(PollEvents::Hup, POLLHUP);
418 translate(PollEvents::Nval, POLLNVAL);
419 translate(PollEvents::RdNorm, POLLRDNORM);
420 translate(PollEvents::RdBand, POLLRDBAND);
421 translate(PollEvents::WrBand, POLLWRBAND);
422
310#ifdef _WIN32 423#ifdef _WIN32
424 if (True(events & PollEvents::Pri)) {
311 LOG_WARNING(Service, "Winsock doesn't support POLLPRI"); 425 LOG_WARNING(Service, "Winsock doesn't support POLLPRI");
312#else
313 result |= POLLPRI;
314#endif
315 }
316 if (True(events & PollEvents::Out)) {
317 events &= ~PollEvents::Out;
318 result |= POLLOUT;
319 } 426 }
427#endif
320 428
321 UNIMPLEMENTED_IF_MSG((u16)events != 0, "Unhandled guest events=0x{:x}", (u16)events); 429 UNIMPLEMENTED_IF_MSG((u16)events != 0, "Unhandled guest events=0x{:x}", (u16)events);
322 430
@@ -337,6 +445,10 @@ PollEvents TranslatePollRevents(short revents) {
337 translate(POLLOUT, PollEvents::Out); 445 translate(POLLOUT, PollEvents::Out);
338 translate(POLLERR, PollEvents::Err); 446 translate(POLLERR, PollEvents::Err);
339 translate(POLLHUP, PollEvents::Hup); 447 translate(POLLHUP, PollEvents::Hup);
448 translate(POLLNVAL, PollEvents::Nval);
449 translate(POLLRDNORM, PollEvents::RdNorm);
450 translate(POLLRDBAND, PollEvents::RdBand);
451 translate(POLLWRBAND, PollEvents::WrBand);
340 452
341 UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents); 453 UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents);
342 454
@@ -360,12 +472,53 @@ std::optional<IPv4Address> GetHostIPv4Address() {
360 return {}; 472 return {};
361 } 473 }
362 474
363 std::array<char, 16> ip_addr = {};
364 ASSERT(inet_ntop(AF_INET, &network_interface->ip_address, ip_addr.data(), sizeof(ip_addr)) !=
365 nullptr);
366 return TranslateIPv4(network_interface->ip_address); 475 return TranslateIPv4(network_interface->ip_address);
367} 476}
368 477
478std::string IPv4AddressToString(IPv4Address ip_addr) {
479 std::array<char, INET_ADDRSTRLEN> buf = {};
480 ASSERT(inet_ntop(AF_INET, &ip_addr, buf.data(), sizeof(buf)) == buf.data());
481 return std::string(buf.data());
482}
483
484u32 IPv4AddressToInteger(IPv4Address ip_addr) {
485 return static_cast<u32>(ip_addr[0]) << 24 | static_cast<u32>(ip_addr[1]) << 16 |
486 static_cast<u32>(ip_addr[2]) << 8 | static_cast<u32>(ip_addr[3]);
487}
488
489#undef GetAddrInfo // Windows defines it as a macro
490
491Common::Expected<std::vector<AddrInfo>, GetAddrInfoError> GetAddrInfo(
492 const std::string& host, const std::optional<std::string>& service) {
493 addrinfo hints{};
494 hints.ai_family = AF_INET; // Switch only supports IPv4.
495 addrinfo* addrinfo;
496 s32 gai_err = getaddrinfo(host.c_str(), service.has_value() ? service->c_str() : nullptr,
497 &hints, &addrinfo);
498 if (gai_err != 0) {
499 return Common::Unexpected(TranslateGetAddrInfoErrorFromNative(gai_err));
500 }
501 std::vector<AddrInfo> ret;
502 for (auto* current = addrinfo; current; current = current->ai_next) {
503 // We should only get AF_INET results due to the hints value.
504 ASSERT_OR_EXECUTE(addrinfo->ai_family == AF_INET &&
505 addrinfo->ai_addrlen == sizeof(sockaddr_in),
506 continue;);
507
508 AddrInfo& out = ret.emplace_back();
509 out.family = TranslateDomainFromNative(current->ai_family);
510 out.socket_type = TranslateTypeFromNative(current->ai_socktype);
511 out.protocol = TranslateProtocolFromNative(current->ai_protocol);
512 out.addr = TranslateToSockAddrIn(*reinterpret_cast<sockaddr_in*>(current->ai_addr),
513 current->ai_addrlen);
514 if (current->ai_canonname != nullptr) {
515 out.canon_name = current->ai_canonname;
516 }
517 }
518 freeaddrinfo(addrinfo);
519 return ret;
520}
521
369std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) { 522std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
370 const size_t num = pollfds.size(); 523 const size_t num = pollfds.size();
371 524
@@ -411,6 +564,18 @@ Socket::Socket(Socket&& rhs) noexcept {
411} 564}
412 565
413template <typename T> 566template <typename T>
567std::pair<T, Errno> Socket::GetSockOpt(SOCKET fd_, int option) {
568 T value{};
569 socklen_t len = sizeof(value);
570 const int result = getsockopt(fd_, SOL_SOCKET, option, reinterpret_cast<char*>(&value), &len);
571 if (result != SOCKET_ERROR) {
572 ASSERT(len == sizeof(value));
573 return {value, Errno::SUCCESS};
574 }
575 return {value, GetAndLogLastError()};
576}
577
578template <typename T>
414Errno Socket::SetSockOpt(SOCKET fd_, int option, T value) { 579Errno Socket::SetSockOpt(SOCKET fd_, int option, T value) {
415 const int result = 580 const int result =
416 setsockopt(fd_, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value)); 581 setsockopt(fd_, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value));
@@ -421,7 +586,8 @@ Errno Socket::SetSockOpt(SOCKET fd_, int option, T value) {
421} 586}
422 587
423Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) { 588Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
424 fd = socket(TranslateDomain(domain), TranslateType(type), TranslateProtocol(protocol)); 589 fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type),
590 TranslateProtocolToNative(protocol));
425 if (fd != INVALID_SOCKET) { 591 if (fd != INVALID_SOCKET) {
426 return Errno::SUCCESS; 592 return Errno::SUCCESS;
427 } 593 }
@@ -430,19 +596,17 @@ Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
430} 596}
431 597
432std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() { 598std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
433 sockaddr addr; 599 sockaddr_in addr;
434 socklen_t addrlen = sizeof(addr); 600 socklen_t addrlen = sizeof(addr);
435 const SOCKET new_socket = accept(fd, &addr, &addrlen); 601 const SOCKET new_socket = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
436 602
437 if (new_socket == INVALID_SOCKET) { 603 if (new_socket == INVALID_SOCKET) {
438 return {AcceptResult{}, GetAndLogLastError()}; 604 return {AcceptResult{}, GetAndLogLastError()};
439 } 605 }
440 606
441 ASSERT(addrlen == sizeof(sockaddr_in));
442
443 AcceptResult result{ 607 AcceptResult result{
444 .socket = std::make_unique<Socket>(new_socket), 608 .socket = std::make_unique<Socket>(new_socket),
445 .sockaddr_in = TranslateToSockAddrIn(addr), 609 .sockaddr_in = TranslateToSockAddrIn(addr, addrlen),
446 }; 610 };
447 611
448 return {std::move(result), Errno::SUCCESS}; 612 return {std::move(result), Errno::SUCCESS};
@@ -458,25 +622,23 @@ Errno Socket::Connect(SockAddrIn addr_in) {
458} 622}
459 623
460std::pair<SockAddrIn, Errno> Socket::GetPeerName() { 624std::pair<SockAddrIn, Errno> Socket::GetPeerName() {
461 sockaddr addr; 625 sockaddr_in addr;
462 socklen_t addrlen = sizeof(addr); 626 socklen_t addrlen = sizeof(addr);
463 if (getpeername(fd, &addr, &addrlen) == SOCKET_ERROR) { 627 if (getpeername(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
464 return {SockAddrIn{}, GetAndLogLastError()}; 628 return {SockAddrIn{}, GetAndLogLastError()};
465 } 629 }
466 630
467 ASSERT(addrlen == sizeof(sockaddr_in)); 631 return {TranslateToSockAddrIn(addr, addrlen), Errno::SUCCESS};
468 return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
469} 632}
470 633
471std::pair<SockAddrIn, Errno> Socket::GetSockName() { 634std::pair<SockAddrIn, Errno> Socket::GetSockName() {
472 sockaddr addr; 635 sockaddr_in addr;
473 socklen_t addrlen = sizeof(addr); 636 socklen_t addrlen = sizeof(addr);
474 if (getsockname(fd, &addr, &addrlen) == SOCKET_ERROR) { 637 if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
475 return {SockAddrIn{}, GetAndLogLastError()}; 638 return {SockAddrIn{}, GetAndLogLastError()};
476 } 639 }
477 640
478 ASSERT(addrlen == sizeof(sockaddr_in)); 641 return {TranslateToSockAddrIn(addr, addrlen), Errno::SUCCESS};
479 return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
480} 642}
481 643
482Errno Socket::Bind(SockAddrIn addr) { 644Errno Socket::Bind(SockAddrIn addr) {
@@ -519,7 +681,7 @@ Errno Socket::Shutdown(ShutdownHow how) {
519 return GetAndLogLastError(); 681 return GetAndLogLastError();
520} 682}
521 683
522std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) { 684std::pair<s32, Errno> Socket::Recv(int flags, std::span<u8> message) {
523 ASSERT(flags == 0); 685 ASSERT(flags == 0);
524 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); 686 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
525 687
@@ -532,21 +694,20 @@ std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
532 return {-1, GetAndLogLastError()}; 694 return {-1, GetAndLogLastError()};
533} 695}
534 696
535std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) { 697std::pair<s32, Errno> Socket::RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) {
536 ASSERT(flags == 0); 698 ASSERT(flags == 0);
537 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); 699 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
538 700
539 sockaddr addr_in{}; 701 sockaddr_in addr_in{};
540 socklen_t addrlen = sizeof(addr_in); 702 socklen_t addrlen = sizeof(addr_in);
541 socklen_t* const p_addrlen = addr ? &addrlen : nullptr; 703 socklen_t* const p_addrlen = addr ? &addrlen : nullptr;
542 sockaddr* const p_addr_in = addr ? &addr_in : nullptr; 704 sockaddr* const p_addr_in = addr ? reinterpret_cast<sockaddr*>(&addr_in) : nullptr;
543 705
544 const auto result = recvfrom(fd, reinterpret_cast<char*>(message.data()), 706 const auto result = recvfrom(fd, reinterpret_cast<char*>(message.data()),
545 static_cast<int>(message.size()), 0, p_addr_in, p_addrlen); 707 static_cast<int>(message.size()), 0, p_addr_in, p_addrlen);
546 if (result != SOCKET_ERROR) { 708 if (result != SOCKET_ERROR) {
547 if (addr) { 709 if (addr) {
548 ASSERT(addrlen == sizeof(addr_in)); 710 *addr = TranslateToSockAddrIn(addr_in, addrlen);
549 *addr = TranslateToSockAddrIn(addr_in);
550 } 711 }
551 return {static_cast<s32>(result), Errno::SUCCESS}; 712 return {static_cast<s32>(result), Errno::SUCCESS};
552 } 713 }
@@ -597,6 +758,11 @@ Errno Socket::Close() {
597 return Errno::SUCCESS; 758 return Errno::SUCCESS;
598} 759}
599 760
761std::pair<Errno, Errno> Socket::GetPendingError() {
762 auto [pending_err, getsockopt_err] = GetSockOpt<int>(fd, SO_ERROR);
763 return {TranslateNativeError(pending_err), getsockopt_err};
764}
765
600Errno Socket::SetLinger(bool enable, u32 linger) { 766Errno Socket::SetLinger(bool enable, u32 linger) {
601 return SetSockOpt(fd, SO_LINGER, MakeLinger(enable, linger)); 767 return SetSockOpt(fd, SO_LINGER, MakeLinger(enable, linger));
602} 768}
diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h
index 1e09a007a..96319bfc8 100644
--- a/src/core/internal_network/network.h
+++ b/src/core/internal_network/network.h
@@ -16,6 +16,11 @@
16#include <netinet/in.h> 16#include <netinet/in.h>
17#endif 17#endif
18 18
19namespace Common {
20template <typename T, typename E>
21class Expected;
22}
23
19namespace Network { 24namespace Network {
20 25
21class SocketBase; 26class SocketBase;
@@ -36,6 +41,26 @@ enum class Errno {
36 NETUNREACH, 41 NETUNREACH,
37 TIMEDOUT, 42 TIMEDOUT,
38 MSGSIZE, 43 MSGSIZE,
44 INPROGRESS,
45 OTHER,
46};
47
48enum class GetAddrInfoError {
49 SUCCESS,
50 ADDRFAMILY,
51 AGAIN,
52 BADFLAGS,
53 FAIL,
54 FAMILY,
55 MEMORY,
56 NODATA,
57 NONAME,
58 SERVICE,
59 SOCKTYPE,
60 SYSTEM,
61 BADHINTS,
62 PROTOCOL,
63 OVERFLOW_,
39 OTHER, 64 OTHER,
40}; 65};
41 66
@@ -49,6 +74,9 @@ enum class PollEvents : u16 {
49 Err = 1 << 3, 74 Err = 1 << 3,
50 Hup = 1 << 4, 75 Hup = 1 << 4,
51 Nval = 1 << 5, 76 Nval = 1 << 5,
77 RdNorm = 1 << 6,
78 RdBand = 1 << 7,
79 WrBand = 1 << 8,
52}; 80};
53 81
54DECLARE_ENUM_FLAG_OPERATORS(PollEvents); 82DECLARE_ENUM_FLAG_OPERATORS(PollEvents);
@@ -82,4 +110,10 @@ constexpr IPv4Address TranslateIPv4(in_addr addr) {
82/// @return human ordered IPv4 address (e.g. 192.168.0.1) as an array 110/// @return human ordered IPv4 address (e.g. 192.168.0.1) as an array
83std::optional<IPv4Address> GetHostIPv4Address(); 111std::optional<IPv4Address> GetHostIPv4Address();
84 112
113std::string IPv4AddressToString(IPv4Address ip_addr);
114u32 IPv4AddressToInteger(IPv4Address ip_addr);
115
116Common::Expected<std::vector<AddrInfo>, GetAddrInfoError> GetAddrInfo(
117 const std::string& host, const std::optional<std::string>& service);
118
85} // namespace Network 119} // namespace Network
diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp
index 7a77171c2..44e9e3093 100644
--- a/src/core/internal_network/socket_proxy.cpp
+++ b/src/core/internal_network/socket_proxy.cpp
@@ -98,7 +98,7 @@ Errno ProxySocket::Shutdown(ShutdownHow how) {
98 return Errno::SUCCESS; 98 return Errno::SUCCESS;
99} 99}
100 100
101std::pair<s32, Errno> ProxySocket::Recv(int flags, std::vector<u8>& message) { 101std::pair<s32, Errno> ProxySocket::Recv(int flags, std::span<u8> message) {
102 LOG_WARNING(Network, "(STUBBED) called"); 102 LOG_WARNING(Network, "(STUBBED) called");
103 ASSERT(flags == 0); 103 ASSERT(flags == 0);
104 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); 104 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
@@ -106,7 +106,7 @@ std::pair<s32, Errno> ProxySocket::Recv(int flags, std::vector<u8>& message) {
106 return {static_cast<s32>(0), Errno::SUCCESS}; 106 return {static_cast<s32>(0), Errno::SUCCESS};
107} 107}
108 108
109std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) { 109std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) {
110 ASSERT(flags == 0); 110 ASSERT(flags == 0);
111 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); 111 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
112 112
@@ -140,8 +140,8 @@ std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::vector<u8>& message,
140 } 140 }
141} 141}
142 142
143std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::vector<u8>& message, 143std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::span<u8> message, SockAddrIn* addr,
144 SockAddrIn* addr, std::size_t max_length) { 144 std::size_t max_length) {
145 ProxyPacket& packet = received_packets.front(); 145 ProxyPacket& packet = received_packets.front();
146 if (addr) { 146 if (addr) {
147 addr->family = Domain::INET; 147 addr->family = Domain::INET;
@@ -153,10 +153,7 @@ std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::vector<u8>& mes
153 std::size_t read_bytes; 153 std::size_t read_bytes;
154 if (packet.data.size() > max_length) { 154 if (packet.data.size() > max_length) {
155 read_bytes = max_length; 155 read_bytes = max_length;
156 message.clear(); 156 memcpy(message.data(), packet.data.data(), max_length);
157 std::copy(packet.data.begin(), packet.data.begin() + read_bytes,
158 std::back_inserter(message));
159 message.resize(max_length);
160 157
161 if (protocol == Protocol::UDP) { 158 if (protocol == Protocol::UDP) {
162 if (!peek) { 159 if (!peek) {
@@ -171,9 +168,7 @@ std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::vector<u8>& mes
171 } 168 }
172 } else { 169 } else {
173 read_bytes = packet.data.size(); 170 read_bytes = packet.data.size();
174 message.clear(); 171 memcpy(message.data(), packet.data.data(), read_bytes);
175 std::copy(packet.data.begin(), packet.data.end(), std::back_inserter(message));
176 message.resize(max_length);
177 if (!peek) { 172 if (!peek) {
178 received_packets.pop(); 173 received_packets.pop();
179 } 174 }
@@ -293,6 +288,11 @@ Errno ProxySocket::SetNonBlock(bool enable) {
293 return Errno::SUCCESS; 288 return Errno::SUCCESS;
294} 289}
295 290
291std::pair<Errno, Errno> ProxySocket::GetPendingError() {
292 LOG_DEBUG(Network, "(STUBBED) called");
293 return {Errno::SUCCESS, Errno::SUCCESS};
294}
295
296bool ProxySocket::IsOpened() const { 296bool ProxySocket::IsOpened() const {
297 return fd != INVALID_SOCKET; 297 return fd != INVALID_SOCKET;
298} 298}
diff --git a/src/core/internal_network/socket_proxy.h b/src/core/internal_network/socket_proxy.h
index 6e991fa38..e12c413d1 100644
--- a/src/core/internal_network/socket_proxy.h
+++ b/src/core/internal_network/socket_proxy.h
@@ -39,11 +39,11 @@ public:
39 39
40 Errno Shutdown(ShutdownHow how) override; 40 Errno Shutdown(ShutdownHow how) override;
41 41
42 std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message) override; 42 std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
43 43
44 std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) override; 44 std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) override;
45 45
46 std::pair<s32, Errno> ReceivePacket(int flags, std::vector<u8>& message, SockAddrIn* addr, 46 std::pair<s32, Errno> ReceivePacket(int flags, std::span<u8> message, SockAddrIn* addr,
47 std::size_t max_length); 47 std::size_t max_length);
48 48
49 std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override; 49 std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
@@ -74,6 +74,8 @@ public:
74 template <typename T> 74 template <typename T>
75 Errno SetSockOpt(SOCKET fd, int option, T value); 75 Errno SetSockOpt(SOCKET fd, int option, T value);
76 76
77 std::pair<Errno, Errno> GetPendingError() override;
78
77 bool IsOpened() const override; 79 bool IsOpened() const override;
78 80
79private: 81private:
diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h
index 11e479e50..46a53ef79 100644
--- a/src/core/internal_network/sockets.h
+++ b/src/core/internal_network/sockets.h
@@ -59,10 +59,9 @@ public:
59 59
60 virtual Errno Shutdown(ShutdownHow how) = 0; 60 virtual Errno Shutdown(ShutdownHow how) = 0;
61 61
62 virtual std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message) = 0; 62 virtual std::pair<s32, Errno> Recv(int flags, std::span<u8> message) = 0;
63 63
64 virtual std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, 64 virtual std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) = 0;
65 SockAddrIn* addr) = 0;
66 65
67 virtual std::pair<s32, Errno> Send(std::span<const u8> message, int flags) = 0; 66 virtual std::pair<s32, Errno> Send(std::span<const u8> message, int flags) = 0;
68 67
@@ -87,6 +86,8 @@ public:
87 86
88 virtual Errno SetNonBlock(bool enable) = 0; 87 virtual Errno SetNonBlock(bool enable) = 0;
89 88
89 virtual std::pair<Errno, Errno> GetPendingError() = 0;
90
90 virtual bool IsOpened() const = 0; 91 virtual bool IsOpened() const = 0;
91 92
92 virtual void HandleProxyPacket(const ProxyPacket& packet) = 0; 93 virtual void HandleProxyPacket(const ProxyPacket& packet) = 0;
@@ -126,9 +127,9 @@ public:
126 127
127 Errno Shutdown(ShutdownHow how) override; 128 Errno Shutdown(ShutdownHow how) override;
128 129
129 std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message) override; 130 std::pair<s32, Errno> Recv(int flags, std::span<u8> message) override;
130 131
131 std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) override; 132 std::pair<s32, Errno> RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) override;
132 133
133 std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override; 134 std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
134 135
@@ -156,6 +157,11 @@ public:
156 template <typename T> 157 template <typename T>
157 Errno SetSockOpt(SOCKET fd, int option, T value); 158 Errno SetSockOpt(SOCKET fd, int option, T value);
158 159
160 std::pair<Errno, Errno> GetPendingError() override;
161
162 template <typename T>
163 std::pair<T, Errno> GetSockOpt(SOCKET fd, int option);
164
159 bool IsOpened() const override; 165 bool IsOpened() const override;
160 166
161 void HandleProxyPacket(const ProxyPacket& packet) override; 167 void HandleProxyPacket(const ProxyPacket& packet) override;