summaryrefslogtreecommitdiff
path: root/src/core/internal_network
diff options
context:
space:
mode:
authorGravatar liamwhite2023-07-16 16:56:47 -0400
committerGravatar GitHub2023-07-16 16:56:47 -0400
commit2461c78e3f9368e4a03b4c27fae207cbb1d9cfff (patch)
tree50812311958a38d27d9ebcd1cfa443b77ff1c40c /src/core/internal_network
parentfile_sys/content_archive: Detect compressed NCAs (#11047) (diff)
parentRename variables to avoid -Wshadow warnings under GCC (diff)
downloadyuzu-2461c78e3f9368e4a03b4c27fae207cbb1d9cfff.tar.gz
yuzu-2461c78e3f9368e4a03b4c27fae207cbb1d9cfff.tar.xz
yuzu-2461c78e3f9368e4a03b4c27fae207cbb1d9cfff.zip
Merge pull request #10912 from comex/ssl
Implement SSL service
Diffstat (limited to 'src/core/internal_network')
-rw-r--r--src/core/internal_network/network.cpp286
-rw-r--r--src/core/internal_network/network.h36
-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, 292 insertions, 76 deletions
diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp
index 75ac10a9c..28f89c599 100644
--- a/src/core/internal_network/network.cpp
+++ b/src/core/internal_network/network.cpp
@@ -27,6 +27,7 @@
27 27
28#include "common/assert.h" 28#include "common/assert.h"
29#include "common/common_types.h" 29#include "common/common_types.h"
30#include "common/expected.h"
30#include "common/logging/log.h" 31#include "common/logging/log.h"
31#include "common/settings.h" 32#include "common/settings.h"
32#include "core/internal_network/network.h" 33#include "core/internal_network/network.h"
@@ -97,6 +98,8 @@ bool EnableNonBlock(SOCKET fd, bool enable) {
97 98
98Errno TranslateNativeError(int e) { 99Errno TranslateNativeError(int e) {
99 switch (e) { 100 switch (e) {
101 case 0:
102 return Errno::SUCCESS;
100 case WSAEBADF: 103 case WSAEBADF:
101 return Errno::BADF; 104 return Errno::BADF;
102 case WSAEINVAL: 105 case WSAEINVAL:
@@ -121,6 +124,8 @@ Errno TranslateNativeError(int e) {
121 return Errno::MSGSIZE; 124 return Errno::MSGSIZE;
122 case WSAETIMEDOUT: 125 case WSAETIMEDOUT:
123 return Errno::TIMEDOUT; 126 return Errno::TIMEDOUT;
127 case WSAEINPROGRESS:
128 return Errno::INPROGRESS;
124 default: 129 default:
125 UNIMPLEMENTED_MSG("Unimplemented errno={}", e); 130 UNIMPLEMENTED_MSG("Unimplemented errno={}", e);
126 return Errno::OTHER; 131 return Errno::OTHER;
@@ -195,6 +200,8 @@ bool EnableNonBlock(int fd, bool enable) {
195 200
196Errno TranslateNativeError(int e) { 201Errno TranslateNativeError(int e) {
197 switch (e) { 202 switch (e) {
203 case 0:
204 return Errno::SUCCESS;
198 case EBADF: 205 case EBADF:
199 return Errno::BADF; 206 return Errno::BADF;
200 case EINVAL: 207 case EINVAL:
@@ -219,8 +226,10 @@ Errno TranslateNativeError(int e) {
219 return Errno::MSGSIZE; 226 return Errno::MSGSIZE;
220 case ETIMEDOUT: 227 case ETIMEDOUT:
221 return Errno::TIMEDOUT; 228 return Errno::TIMEDOUT;
229 case EINPROGRESS:
230 return Errno::INPROGRESS;
222 default: 231 default:
223 UNIMPLEMENTED_MSG("Unimplemented errno={}", e); 232 UNIMPLEMENTED_MSG("Unimplemented errno={} ({})", e, strerror(e));
224 return Errno::OTHER; 233 return Errno::OTHER;
225 } 234 }
226} 235}
@@ -234,15 +243,84 @@ Errno GetAndLogLastError() {
234 int e = errno; 243 int e = errno;
235#endif 244#endif
236 const Errno err = TranslateNativeError(e); 245 const Errno err = TranslateNativeError(e);
237 if (err == Errno::AGAIN || err == Errno::TIMEDOUT) { 246 if (err == Errno::AGAIN || err == Errno::TIMEDOUT || err == Errno::INPROGRESS) {
247 // These happen during normal operation, so only log them at debug level.
248 LOG_DEBUG(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
238 return err; 249 return err;
239 } 250 }
240 LOG_ERROR(Network, "Socket operation error: {}", Common::NativeErrorToString(e)); 251 LOG_ERROR(Network, "Socket operation error: {}", Common::NativeErrorToString(e));
241 return err; 252 return err;
242} 253}
243 254
244int TranslateDomain(Domain domain) { 255GetAddrInfoError TranslateGetAddrInfoErrorFromNative(int gai_err) {
256 switch (gai_err) {
257 case 0:
258 return GetAddrInfoError::SUCCESS;
259#ifdef EAI_ADDRFAMILY
260 case EAI_ADDRFAMILY:
261 return GetAddrInfoError::ADDRFAMILY;
262#endif
263 case EAI_AGAIN:
264 return GetAddrInfoError::AGAIN;
265 case EAI_BADFLAGS:
266 return GetAddrInfoError::BADFLAGS;
267 case EAI_FAIL:
268 return GetAddrInfoError::FAIL;
269 case EAI_FAMILY:
270 return GetAddrInfoError::FAMILY;
271 case EAI_MEMORY:
272 return GetAddrInfoError::MEMORY;
273 case EAI_NONAME:
274 return GetAddrInfoError::NONAME;
275 case EAI_SERVICE:
276 return GetAddrInfoError::SERVICE;
277 case EAI_SOCKTYPE:
278 return GetAddrInfoError::SOCKTYPE;
279 // These codes may not be defined on all systems:
280#ifdef EAI_SYSTEM
281 case EAI_SYSTEM:
282 return GetAddrInfoError::SYSTEM;
283#endif
284#ifdef EAI_BADHINTS
285 case EAI_BADHINTS:
286 return GetAddrInfoError::BADHINTS;
287#endif
288#ifdef EAI_PROTOCOL
289 case EAI_PROTOCOL:
290 return GetAddrInfoError::PROTOCOL;
291#endif
292#ifdef EAI_OVERFLOW
293 case EAI_OVERFLOW:
294 return GetAddrInfoError::OVERFLOW_;
295#endif
296 default:
297#ifdef EAI_NODATA
298 // This can't be a case statement because it would create a duplicate
299 // case on Windows where EAI_NODATA is an alias for EAI_NONAME.
300 if (gai_err == EAI_NODATA) {
301 return GetAddrInfoError::NODATA;
302 }
303#endif
304 return GetAddrInfoError::OTHER;
305 }
306}
307
308Domain TranslateDomainFromNative(int domain) {
309 switch (domain) {
310 case 0:
311 return Domain::Unspecified;
312 case AF_INET:
313 return Domain::INET;
314 default:
315 UNIMPLEMENTED_MSG("Unhandled domain={}", domain);
316 return Domain::INET;
317 }
318}
319
320int TranslateDomainToNative(Domain domain) {
245 switch (domain) { 321 switch (domain) {
322 case Domain::Unspecified:
323 return 0;
246 case Domain::INET: 324 case Domain::INET:
247 return AF_INET; 325 return AF_INET;
248 default: 326 default:
@@ -251,20 +329,58 @@ int TranslateDomain(Domain domain) {
251 } 329 }
252} 330}
253 331
254int TranslateType(Type type) { 332Type TranslateTypeFromNative(int type) {
333 switch (type) {
334 case 0:
335 return Type::Unspecified;
336 case SOCK_STREAM:
337 return Type::STREAM;
338 case SOCK_DGRAM:
339 return Type::DGRAM;
340 case SOCK_RAW:
341 return Type::RAW;
342 case SOCK_SEQPACKET:
343 return Type::SEQPACKET;
344 default:
345 UNIMPLEMENTED_MSG("Unimplemented type={}", type);
346 return Type::STREAM;
347 }
348}
349
350int TranslateTypeToNative(Type type) {
255 switch (type) { 351 switch (type) {
352 case Type::Unspecified:
353 return 0;
256 case Type::STREAM: 354 case Type::STREAM:
257 return SOCK_STREAM; 355 return SOCK_STREAM;
258 case Type::DGRAM: 356 case Type::DGRAM:
259 return SOCK_DGRAM; 357 return SOCK_DGRAM;
358 case Type::RAW:
359 return SOCK_RAW;
260 default: 360 default:
261 UNIMPLEMENTED_MSG("Unimplemented type={}", type); 361 UNIMPLEMENTED_MSG("Unimplemented type={}", type);
262 return 0; 362 return 0;
263 } 363 }
264} 364}
265 365
266int TranslateProtocol(Protocol protocol) { 366Protocol TranslateProtocolFromNative(int protocol) {
367 switch (protocol) {
368 case 0:
369 return Protocol::Unspecified;
370 case IPPROTO_TCP:
371 return Protocol::TCP;
372 case IPPROTO_UDP:
373 return Protocol::UDP;
374 default:
375 UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol);
376 return Protocol::Unspecified;
377 }
378}
379
380int TranslateProtocolToNative(Protocol protocol) {
267 switch (protocol) { 381 switch (protocol) {
382 case Protocol::Unspecified:
383 return 0;
268 case Protocol::TCP: 384 case Protocol::TCP:
269 return IPPROTO_TCP; 385 return IPPROTO_TCP;
270 case Protocol::UDP: 386 case Protocol::UDP:
@@ -275,21 +391,10 @@ int TranslateProtocol(Protocol protocol) {
275 } 391 }
276} 392}
277 393
278SockAddrIn TranslateToSockAddrIn(sockaddr input_) { 394SockAddrIn TranslateToSockAddrIn(sockaddr_in input, size_t input_len) {
279 sockaddr_in input;
280 std::memcpy(&input, &input_, sizeof(input));
281
282 SockAddrIn result; 395 SockAddrIn result;
283 396
284 switch (input.sin_family) { 397 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 398
294 result.portno = ntohs(input.sin_port); 399 result.portno = ntohs(input.sin_port);
295 400
@@ -301,22 +406,33 @@ SockAddrIn TranslateToSockAddrIn(sockaddr input_) {
301short TranslatePollEvents(PollEvents events) { 406short TranslatePollEvents(PollEvents events) {
302 short result = 0; 407 short result = 0;
303 408
304 if (True(events & PollEvents::In)) { 409 const auto translate = [&result, &events](PollEvents guest, short host) {
305 events &= ~PollEvents::In; 410 if (True(events & guest)) {
306 result |= POLLIN; 411 events &= ~guest;
307 } 412 result |= host;
308 if (True(events & PollEvents::Pri)) { 413 }
309 events &= ~PollEvents::Pri; 414 };
415
416 translate(PollEvents::In, POLLIN);
417 translate(PollEvents::Pri, POLLPRI);
418 translate(PollEvents::Out, POLLOUT);
419 translate(PollEvents::Err, POLLERR);
420 translate(PollEvents::Hup, POLLHUP);
421 translate(PollEvents::Nval, POLLNVAL);
422 translate(PollEvents::RdNorm, POLLRDNORM);
423 translate(PollEvents::RdBand, POLLRDBAND);
424 translate(PollEvents::WrBand, POLLWRBAND);
425
310#ifdef _WIN32 426#ifdef _WIN32
311 LOG_WARNING(Service, "Winsock doesn't support POLLPRI"); 427 short allowed_events = POLLRDBAND | POLLRDNORM | POLLWRNORM;
312#else 428 // Unlike poll on other OSes, WSAPoll will complain if any other flags are set on input.
313 result |= POLLPRI; 429 if (result & ~allowed_events) {
430 LOG_DEBUG(Network,
431 "Removing WSAPoll input events 0x{:x} because Windows doesn't support them",
432 result & ~allowed_events);
433 }
434 result &= allowed_events;
314#endif 435#endif
315 }
316 if (True(events & PollEvents::Out)) {
317 events &= ~PollEvents::Out;
318 result |= POLLOUT;
319 }
320 436
321 UNIMPLEMENTED_IF_MSG((u16)events != 0, "Unhandled guest events=0x{:x}", (u16)events); 437 UNIMPLEMENTED_IF_MSG((u16)events != 0, "Unhandled guest events=0x{:x}", (u16)events);
322 438
@@ -337,6 +453,10 @@ PollEvents TranslatePollRevents(short revents) {
337 translate(POLLOUT, PollEvents::Out); 453 translate(POLLOUT, PollEvents::Out);
338 translate(POLLERR, PollEvents::Err); 454 translate(POLLERR, PollEvents::Err);
339 translate(POLLHUP, PollEvents::Hup); 455 translate(POLLHUP, PollEvents::Hup);
456 translate(POLLNVAL, PollEvents::Nval);
457 translate(POLLRDNORM, PollEvents::RdNorm);
458 translate(POLLRDBAND, PollEvents::RdBand);
459 translate(POLLWRBAND, PollEvents::WrBand);
340 460
341 UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents); 461 UNIMPLEMENTED_IF_MSG(revents != 0, "Unhandled host revents=0x{:x}", revents);
342 462
@@ -360,12 +480,51 @@ std::optional<IPv4Address> GetHostIPv4Address() {
360 return {}; 480 return {};
361 } 481 }
362 482
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); 483 return TranslateIPv4(network_interface->ip_address);
367} 484}
368 485
486std::string IPv4AddressToString(IPv4Address ip_addr) {
487 std::array<char, INET_ADDRSTRLEN> buf = {};
488 ASSERT(inet_ntop(AF_INET, &ip_addr, buf.data(), sizeof(buf)) == buf.data());
489 return std::string(buf.data());
490}
491
492u32 IPv4AddressToInteger(IPv4Address ip_addr) {
493 return static_cast<u32>(ip_addr[0]) << 24 | static_cast<u32>(ip_addr[1]) << 16 |
494 static_cast<u32>(ip_addr[2]) << 8 | static_cast<u32>(ip_addr[3]);
495}
496
497Common::Expected<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(
498 const std::string& host, const std::optional<std::string>& service) {
499 addrinfo hints{};
500 hints.ai_family = AF_INET; // Switch only supports IPv4.
501 addrinfo* addrinfo;
502 s32 gai_err = getaddrinfo(host.c_str(), service.has_value() ? service->c_str() : nullptr,
503 &hints, &addrinfo);
504 if (gai_err != 0) {
505 return Common::Unexpected(TranslateGetAddrInfoErrorFromNative(gai_err));
506 }
507 std::vector<AddrInfo> ret;
508 for (auto* current = addrinfo; current; current = current->ai_next) {
509 // We should only get AF_INET results due to the hints value.
510 ASSERT_OR_EXECUTE(addrinfo->ai_family == AF_INET &&
511 addrinfo->ai_addrlen == sizeof(sockaddr_in),
512 continue;);
513
514 AddrInfo& out = ret.emplace_back();
515 out.family = TranslateDomainFromNative(current->ai_family);
516 out.socket_type = TranslateTypeFromNative(current->ai_socktype);
517 out.protocol = TranslateProtocolFromNative(current->ai_protocol);
518 out.addr = TranslateToSockAddrIn(*reinterpret_cast<sockaddr_in*>(current->ai_addr),
519 current->ai_addrlen);
520 if (current->ai_canonname != nullptr) {
521 out.canon_name = current->ai_canonname;
522 }
523 }
524 freeaddrinfo(addrinfo);
525 return ret;
526}
527
369std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) { 528std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
370 const size_t num = pollfds.size(); 529 const size_t num = pollfds.size();
371 530
@@ -411,9 +570,21 @@ Socket::Socket(Socket&& rhs) noexcept {
411} 570}
412 571
413template <typename T> 572template <typename T>
414Errno Socket::SetSockOpt(SOCKET fd_, int option, T value) { 573std::pair<T, Errno> Socket::GetSockOpt(SOCKET fd_so, int option) {
574 T value{};
575 socklen_t len = sizeof(value);
576 const int result = getsockopt(fd_so, SOL_SOCKET, option, reinterpret_cast<char*>(&value), &len);
577 if (result != SOCKET_ERROR) {
578 ASSERT(len == sizeof(value));
579 return {value, Errno::SUCCESS};
580 }
581 return {value, GetAndLogLastError()};
582}
583
584template <typename T>
585Errno Socket::SetSockOpt(SOCKET fd_so, int option, T value) {
415 const int result = 586 const int result =
416 setsockopt(fd_, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value)); 587 setsockopt(fd_so, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value));
417 if (result != SOCKET_ERROR) { 588 if (result != SOCKET_ERROR) {
418 return Errno::SUCCESS; 589 return Errno::SUCCESS;
419 } 590 }
@@ -421,7 +592,8 @@ Errno Socket::SetSockOpt(SOCKET fd_, int option, T value) {
421} 592}
422 593
423Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) { 594Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
424 fd = socket(TranslateDomain(domain), TranslateType(type), TranslateProtocol(protocol)); 595 fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type),
596 TranslateProtocolToNative(protocol));
425 if (fd != INVALID_SOCKET) { 597 if (fd != INVALID_SOCKET) {
426 return Errno::SUCCESS; 598 return Errno::SUCCESS;
427 } 599 }
@@ -430,19 +602,17 @@ Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
430} 602}
431 603
432std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() { 604std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
433 sockaddr addr; 605 sockaddr_in addr;
434 socklen_t addrlen = sizeof(addr); 606 socklen_t addrlen = sizeof(addr);
435 const SOCKET new_socket = accept(fd, &addr, &addrlen); 607 const SOCKET new_socket = accept(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen);
436 608
437 if (new_socket == INVALID_SOCKET) { 609 if (new_socket == INVALID_SOCKET) {
438 return {AcceptResult{}, GetAndLogLastError()}; 610 return {AcceptResult{}, GetAndLogLastError()};
439 } 611 }
440 612
441 ASSERT(addrlen == sizeof(sockaddr_in));
442
443 AcceptResult result{ 613 AcceptResult result{
444 .socket = std::make_unique<Socket>(new_socket), 614 .socket = std::make_unique<Socket>(new_socket),
445 .sockaddr_in = TranslateToSockAddrIn(addr), 615 .sockaddr_in = TranslateToSockAddrIn(addr, addrlen),
446 }; 616 };
447 617
448 return {std::move(result), Errno::SUCCESS}; 618 return {std::move(result), Errno::SUCCESS};
@@ -458,25 +628,23 @@ Errno Socket::Connect(SockAddrIn addr_in) {
458} 628}
459 629
460std::pair<SockAddrIn, Errno> Socket::GetPeerName() { 630std::pair<SockAddrIn, Errno> Socket::GetPeerName() {
461 sockaddr addr; 631 sockaddr_in addr;
462 socklen_t addrlen = sizeof(addr); 632 socklen_t addrlen = sizeof(addr);
463 if (getpeername(fd, &addr, &addrlen) == SOCKET_ERROR) { 633 if (getpeername(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
464 return {SockAddrIn{}, GetAndLogLastError()}; 634 return {SockAddrIn{}, GetAndLogLastError()};
465 } 635 }
466 636
467 ASSERT(addrlen == sizeof(sockaddr_in)); 637 return {TranslateToSockAddrIn(addr, addrlen), Errno::SUCCESS};
468 return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
469} 638}
470 639
471std::pair<SockAddrIn, Errno> Socket::GetSockName() { 640std::pair<SockAddrIn, Errno> Socket::GetSockName() {
472 sockaddr addr; 641 sockaddr_in addr;
473 socklen_t addrlen = sizeof(addr); 642 socklen_t addrlen = sizeof(addr);
474 if (getsockname(fd, &addr, &addrlen) == SOCKET_ERROR) { 643 if (getsockname(fd, reinterpret_cast<sockaddr*>(&addr), &addrlen) == SOCKET_ERROR) {
475 return {SockAddrIn{}, GetAndLogLastError()}; 644 return {SockAddrIn{}, GetAndLogLastError()};
476 } 645 }
477 646
478 ASSERT(addrlen == sizeof(sockaddr_in)); 647 return {TranslateToSockAddrIn(addr, addrlen), Errno::SUCCESS};
479 return {TranslateToSockAddrIn(addr), Errno::SUCCESS};
480} 648}
481 649
482Errno Socket::Bind(SockAddrIn addr) { 650Errno Socket::Bind(SockAddrIn addr) {
@@ -519,7 +687,7 @@ Errno Socket::Shutdown(ShutdownHow how) {
519 return GetAndLogLastError(); 687 return GetAndLogLastError();
520} 688}
521 689
522std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) { 690std::pair<s32, Errno> Socket::Recv(int flags, std::span<u8> message) {
523 ASSERT(flags == 0); 691 ASSERT(flags == 0);
524 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); 692 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
525 693
@@ -532,21 +700,20 @@ std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
532 return {-1, GetAndLogLastError()}; 700 return {-1, GetAndLogLastError()};
533} 701}
534 702
535std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) { 703std::pair<s32, Errno> Socket::RecvFrom(int flags, std::span<u8> message, SockAddrIn* addr) {
536 ASSERT(flags == 0); 704 ASSERT(flags == 0);
537 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max())); 705 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
538 706
539 sockaddr addr_in{}; 707 sockaddr_in addr_in{};
540 socklen_t addrlen = sizeof(addr_in); 708 socklen_t addrlen = sizeof(addr_in);
541 socklen_t* const p_addrlen = addr ? &addrlen : nullptr; 709 socklen_t* const p_addrlen = addr ? &addrlen : nullptr;
542 sockaddr* const p_addr_in = addr ? &addr_in : nullptr; 710 sockaddr* const p_addr_in = addr ? reinterpret_cast<sockaddr*>(&addr_in) : nullptr;
543 711
544 const auto result = recvfrom(fd, reinterpret_cast<char*>(message.data()), 712 const auto result = recvfrom(fd, reinterpret_cast<char*>(message.data()),
545 static_cast<int>(message.size()), 0, p_addr_in, p_addrlen); 713 static_cast<int>(message.size()), 0, p_addr_in, p_addrlen);
546 if (result != SOCKET_ERROR) { 714 if (result != SOCKET_ERROR) {
547 if (addr) { 715 if (addr) {
548 ASSERT(addrlen == sizeof(addr_in)); 716 *addr = TranslateToSockAddrIn(addr_in, addrlen);
549 *addr = TranslateToSockAddrIn(addr_in);
550 } 717 }
551 return {static_cast<s32>(result), Errno::SUCCESS}; 718 return {static_cast<s32>(result), Errno::SUCCESS};
552 } 719 }
@@ -597,6 +764,11 @@ Errno Socket::Close() {
597 return Errno::SUCCESS; 764 return Errno::SUCCESS;
598} 765}
599 766
767std::pair<Errno, Errno> Socket::GetPendingError() {
768 auto [pending_err, getsockopt_err] = GetSockOpt<int>(fd, SO_ERROR);
769 return {TranslateNativeError(pending_err), getsockopt_err};
770}
771
600Errno Socket::SetLinger(bool enable, u32 linger) { 772Errno Socket::SetLinger(bool enable, u32 linger) {
601 return SetSockOpt(fd, SO_LINGER, MakeLinger(enable, linger)); 773 return SetSockOpt(fd, SO_LINGER, MakeLinger(enable, linger));
602} 774}
diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h
index 1e09a007a..badcb8369 100644
--- a/src/core/internal_network/network.h
+++ b/src/core/internal_network/network.h
@@ -5,6 +5,7 @@
5 5
6#include <array> 6#include <array>
7#include <optional> 7#include <optional>
8#include <vector>
8 9
9#include "common/common_funcs.h" 10#include "common/common_funcs.h"
10#include "common/common_types.h" 11#include "common/common_types.h"
@@ -16,6 +17,11 @@
16#include <netinet/in.h> 17#include <netinet/in.h>
17#endif 18#endif
18 19
20namespace Common {
21template <typename T, typename E>
22class Expected;
23}
24
19namespace Network { 25namespace Network {
20 26
21class SocketBase; 27class SocketBase;
@@ -36,6 +42,26 @@ enum class Errno {
36 NETUNREACH, 42 NETUNREACH,
37 TIMEDOUT, 43 TIMEDOUT,
38 MSGSIZE, 44 MSGSIZE,
45 INPROGRESS,
46 OTHER,
47};
48
49enum class GetAddrInfoError {
50 SUCCESS,
51 ADDRFAMILY,
52 AGAIN,
53 BADFLAGS,
54 FAIL,
55 FAMILY,
56 MEMORY,
57 NODATA,
58 NONAME,
59 SERVICE,
60 SOCKTYPE,
61 SYSTEM,
62 BADHINTS,
63 PROTOCOL,
64 OVERFLOW_,
39 OTHER, 65 OTHER,
40}; 66};
41 67
@@ -49,6 +75,9 @@ enum class PollEvents : u16 {
49 Err = 1 << 3, 75 Err = 1 << 3,
50 Hup = 1 << 4, 76 Hup = 1 << 4,
51 Nval = 1 << 5, 77 Nval = 1 << 5,
78 RdNorm = 1 << 6,
79 RdBand = 1 << 7,
80 WrBand = 1 << 8,
52}; 81};
53 82
54DECLARE_ENUM_FLAG_OPERATORS(PollEvents); 83DECLARE_ENUM_FLAG_OPERATORS(PollEvents);
@@ -82,4 +111,11 @@ constexpr IPv4Address TranslateIPv4(in_addr addr) {
82/// @return human ordered IPv4 address (e.g. 192.168.0.1) as an array 111/// @return human ordered IPv4 address (e.g. 192.168.0.1) as an array
83std::optional<IPv4Address> GetHostIPv4Address(); 112std::optional<IPv4Address> GetHostIPv4Address();
84 113
114std::string IPv4AddressToString(IPv4Address ip_addr);
115u32 IPv4AddressToInteger(IPv4Address ip_addr);
116
117// named to avoid name collision with Windows macro
118Common::Expected<std::vector<AddrInfo>, GetAddrInfoError> GetAddressInfo(
119 const std::string& host, const std::optional<std::string>& service);
120
85} // namespace Network 121} // 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;