summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2021-03-02 17:08:47 -0800
committerGravatar GitHub2021-03-02 17:08:47 -0800
commitf8bfec31095b8ccc7883dbff49472f6c0ce2dec8 (patch)
tree0c3fe3ba20f294d1fac2c89019204eec528c57f4 /src/core
parentMerge pull request #6020 from bunnei/shutdown-crash-2 (diff)
parent[network] Error handling reform (diff)
downloadyuzu-f8bfec31095b8ccc7883dbff49472f6c0ce2dec8.tar.gz
yuzu-f8bfec31095b8ccc7883dbff49472f6c0ce2dec8.tar.xz
yuzu-f8bfec31095b8ccc7883dbff49472f6c0ce2dec8.zip
Merge pull request #5815 from comex/net-error-reform
Network error handling reform
Diffstat (limited to 'src/core')
-rw-r--r--src/core/network/network.cpp173
-rw-r--r--src/core/network/network.h6
2 files changed, 84 insertions, 95 deletions
diff --git a/src/core/network/network.cpp b/src/core/network/network.cpp
index 681e93468..526bfa110 100644
--- a/src/core/network/network.cpp
+++ b/src/core/network/network.cpp
@@ -7,6 +7,7 @@
7#include <limits> 7#include <limits>
8#include <utility> 8#include <utility>
9#include <vector> 9#include <vector>
10#include "common/common_funcs.h"
10 11
11#ifdef _WIN32 12#ifdef _WIN32
12#define _WINSOCK_DEPRECATED_NO_WARNINGS // gethostname 13#define _WINSOCK_DEPRECATED_NO_WARNINGS // gethostname
@@ -90,15 +91,36 @@ LINGER MakeLinger(bool enable, u32 linger_value) {
90 return value; 91 return value;
91} 92}
92 93
93int LastError() {
94 return WSAGetLastError();
95}
96
97bool EnableNonBlock(SOCKET fd, bool enable) { 94bool EnableNonBlock(SOCKET fd, bool enable) {
98 u_long value = enable ? 1 : 0; 95 u_long value = enable ? 1 : 0;
99 return ioctlsocket(fd, FIONBIO, &value) != SOCKET_ERROR; 96 return ioctlsocket(fd, FIONBIO, &value) != SOCKET_ERROR;
100} 97}
101 98
99Errno TranslateNativeError(int e) {
100 switch (e) {
101 case WSAEBADF:
102 return Errno::BADF;
103 case WSAEINVAL:
104 return Errno::INVAL;
105 case WSAEMFILE:
106 return Errno::MFILE;
107 case WSAENOTCONN:
108 return Errno::NOTCONN;
109 case WSAEWOULDBLOCK:
110 return Errno::AGAIN;
111 case WSAECONNREFUSED:
112 return Errno::CONNREFUSED;
113 case WSAEHOSTUNREACH:
114 return Errno::HOSTUNREACH;
115 case WSAENETDOWN:
116 return Errno::NETDOWN;
117 case WSAENETUNREACH:
118 return Errno::NETUNREACH;
119 default:
120 return Errno::OTHER;
121 }
122}
123
102#elif YUZU_UNIX // ^ _WIN32 v YUZU_UNIX 124#elif YUZU_UNIX // ^ _WIN32 v YUZU_UNIX
103 125
104using SOCKET = int; 126using SOCKET = int;
@@ -108,9 +130,6 @@ using ULONG = u64;
108constexpr SOCKET INVALID_SOCKET = -1; 130constexpr SOCKET INVALID_SOCKET = -1;
109constexpr SOCKET SOCKET_ERROR = -1; 131constexpr SOCKET SOCKET_ERROR = -1;
110 132
111constexpr int WSAEWOULDBLOCK = EAGAIN;
112constexpr int WSAENOTCONN = ENOTCONN;
113
114constexpr int SD_RECEIVE = SHUT_RD; 133constexpr int SD_RECEIVE = SHUT_RD;
115constexpr int SD_SEND = SHUT_WR; 134constexpr int SD_SEND = SHUT_WR;
116constexpr int SD_BOTH = SHUT_RDWR; 135constexpr int SD_BOTH = SHUT_RDWR;
@@ -162,10 +181,6 @@ linger MakeLinger(bool enable, u32 linger_value) {
162 return value; 181 return value;
163} 182}
164 183
165int LastError() {
166 return errno;
167}
168
169bool EnableNonBlock(int fd, bool enable) { 184bool EnableNonBlock(int fd, bool enable) {
170 int flags = fcntl(fd, F_GETFD); 185 int flags = fcntl(fd, F_GETFD);
171 if (flags == -1) { 186 if (flags == -1) {
@@ -179,8 +194,43 @@ bool EnableNonBlock(int fd, bool enable) {
179 return fcntl(fd, F_SETFD, flags) == 0; 194 return fcntl(fd, F_SETFD, flags) == 0;
180} 195}
181 196
197Errno TranslateNativeError(int e) {
198 switch (e) {
199 case EBADF:
200 return Errno::BADF;
201 case EINVAL:
202 return Errno::INVAL;
203 case EMFILE:
204 return Errno::MFILE;
205 case ENOTCONN:
206 return Errno::NOTCONN;
207 case EAGAIN:
208 return Errno::AGAIN;
209 case ECONNREFUSED:
210 return Errno::CONNREFUSED;
211 case EHOSTUNREACH:
212 return Errno::HOSTUNREACH;
213 case ENETDOWN:
214 return Errno::NETDOWN;
215 case ENETUNREACH:
216 return Errno::NETUNREACH;
217 default:
218 return Errno::OTHER;
219 }
220}
221
182#endif 222#endif
183 223
224Errno GetAndLogLastError() {
225#ifdef _WIN32
226 int e = WSAGetLastError();
227#else
228 int e = errno;
229#endif
230 LOG_ERROR(Network, "Socket operation error: {}", NativeErrorToString(e));
231 return TranslateNativeError(e);
232}
233
184int TranslateDomain(Domain domain) { 234int TranslateDomain(Domain domain) {
185 switch (domain) { 235 switch (domain) {
186 case Domain::INET: 236 case Domain::INET:
@@ -290,9 +340,7 @@ Errno SetSockOpt(SOCKET fd, int option, T value) {
290 if (result != SOCKET_ERROR) { 340 if (result != SOCKET_ERROR) {
291 return Errno::SUCCESS; 341 return Errno::SUCCESS;
292 } 342 }
293 const int ec = LastError(); 343 return GetAndLogLastError();
294 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
295 return Errno::SUCCESS;
296} 344}
297 345
298} // Anonymous namespace 346} // Anonymous namespace
@@ -308,14 +356,12 @@ NetworkInstance::~NetworkInstance() {
308std::pair<IPv4Address, Errno> GetHostIPv4Address() { 356std::pair<IPv4Address, Errno> GetHostIPv4Address() {
309 std::array<char, 256> name{}; 357 std::array<char, 256> name{};
310 if (gethostname(name.data(), static_cast<int>(name.size()) - 1) == SOCKET_ERROR) { 358 if (gethostname(name.data(), static_cast<int>(name.size()) - 1) == SOCKET_ERROR) {
311 UNIMPLEMENTED_MSG("Unhandled gethostname error"); 359 return {IPv4Address{}, GetAndLogLastError()};
312 return {IPv4Address{}, Errno::SUCCESS};
313 } 360 }
314 361
315 hostent* const ent = gethostbyname(name.data()); 362 hostent* const ent = gethostbyname(name.data());
316 if (!ent) { 363 if (!ent) {
317 UNIMPLEMENTED_MSG("Unhandled gethostbyname error"); 364 return {IPv4Address{}, GetAndLogLastError()};
318 return {IPv4Address{}, Errno::SUCCESS};
319 } 365 }
320 if (ent->h_addr_list == nullptr) { 366 if (ent->h_addr_list == nullptr) {
321 UNIMPLEMENTED_MSG("No addr provided in hostent->h_addr_list"); 367 UNIMPLEMENTED_MSG("No addr provided in hostent->h_addr_list");
@@ -359,9 +405,7 @@ std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
359 405
360 ASSERT(result == SOCKET_ERROR); 406 ASSERT(result == SOCKET_ERROR);
361 407
362 const int ec = LastError(); 408 return {-1, GetAndLogLastError()};
363 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
364 return {-1, Errno::SUCCESS};
365} 409}
366 410
367Socket::~Socket() { 411Socket::~Socket() {
@@ -380,9 +424,7 @@ Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
380 return Errno::SUCCESS; 424 return Errno::SUCCESS;
381 } 425 }
382 426
383 const int ec = LastError(); 427 return GetAndLogLastError();
384 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
385 return Errno::SUCCESS;
386} 428}
387 429
388std::pair<Socket::AcceptResult, Errno> Socket::Accept() { 430std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
@@ -391,9 +433,7 @@ std::pair<Socket::AcceptResult, Errno> Socket::Accept() {
391 const SOCKET new_socket = accept(fd, &addr, &addrlen); 433 const SOCKET new_socket = accept(fd, &addr, &addrlen);
392 434
393 if (new_socket == INVALID_SOCKET) { 435 if (new_socket == INVALID_SOCKET) {
394 const int ec = LastError(); 436 return {AcceptResult{}, GetAndLogLastError()};
395 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
396 return {AcceptResult{}, Errno::SUCCESS};
397 } 437 }
398 438
399 AcceptResult result; 439 AcceptResult result;
@@ -412,23 +452,14 @@ Errno Socket::Connect(SockAddrIn addr_in) {
412 return Errno::SUCCESS; 452 return Errno::SUCCESS;
413 } 453 }
414 454
415 switch (const int ec = LastError()) { 455 return GetAndLogLastError();
416 case WSAEWOULDBLOCK:
417 LOG_DEBUG(Service, "EAGAIN generated");
418 return Errno::AGAIN;
419 default:
420 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
421 return Errno::SUCCESS;
422 }
423} 456}
424 457
425std::pair<SockAddrIn, Errno> Socket::GetPeerName() { 458std::pair<SockAddrIn, Errno> Socket::GetPeerName() {
426 sockaddr addr; 459 sockaddr addr;
427 socklen_t addrlen = sizeof(addr); 460 socklen_t addrlen = sizeof(addr);
428 if (getpeername(fd, &addr, &addrlen) == SOCKET_ERROR) { 461 if (getpeername(fd, &addr, &addrlen) == SOCKET_ERROR) {
429 const int ec = LastError(); 462 return {SockAddrIn{}, GetAndLogLastError()};
430 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
431 return {SockAddrIn{}, Errno::SUCCESS};
432 } 463 }
433 464
434 ASSERT(addrlen == sizeof(sockaddr_in)); 465 ASSERT(addrlen == sizeof(sockaddr_in));
@@ -439,9 +470,7 @@ std::pair<SockAddrIn, Errno> Socket::GetSockName() {
439 sockaddr addr; 470 sockaddr addr;
440 socklen_t addrlen = sizeof(addr); 471 socklen_t addrlen = sizeof(addr);
441 if (getsockname(fd, &addr, &addrlen) == SOCKET_ERROR) { 472 if (getsockname(fd, &addr, &addrlen) == SOCKET_ERROR) {
442 const int ec = LastError(); 473 return {SockAddrIn{}, GetAndLogLastError()};
443 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
444 return {SockAddrIn{}, Errno::SUCCESS};
445 } 474 }
446 475
447 ASSERT(addrlen == sizeof(sockaddr_in)); 476 ASSERT(addrlen == sizeof(sockaddr_in));
@@ -454,9 +483,7 @@ Errno Socket::Bind(SockAddrIn addr) {
454 return Errno::SUCCESS; 483 return Errno::SUCCESS;
455 } 484 }
456 485
457 const int ec = LastError(); 486 return GetAndLogLastError();
458 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
459 return Errno::SUCCESS;
460} 487}
461 488
462Errno Socket::Listen(s32 backlog) { 489Errno Socket::Listen(s32 backlog) {
@@ -464,9 +491,7 @@ Errno Socket::Listen(s32 backlog) {
464 return Errno::SUCCESS; 491 return Errno::SUCCESS;
465 } 492 }
466 493
467 const int ec = LastError(); 494 return GetAndLogLastError();
468 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
469 return Errno::SUCCESS;
470} 495}
471 496
472Errno Socket::Shutdown(ShutdownHow how) { 497Errno Socket::Shutdown(ShutdownHow how) {
@@ -489,14 +514,7 @@ Errno Socket::Shutdown(ShutdownHow how) {
489 return Errno::SUCCESS; 514 return Errno::SUCCESS;
490 } 515 }
491 516
492 switch (const int ec = LastError()) { 517 return GetAndLogLastError();
493 case WSAENOTCONN:
494 LOG_ERROR(Service, "ENOTCONN generated");
495 return Errno::NOTCONN;
496 default:
497 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
498 return Errno::SUCCESS;
499 }
500} 518}
501 519
502std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) { 520std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
@@ -509,17 +527,7 @@ std::pair<s32, Errno> Socket::Recv(int flags, std::vector<u8>& message) {
509 return {static_cast<s32>(result), Errno::SUCCESS}; 527 return {static_cast<s32>(result), Errno::SUCCESS};
510 } 528 }
511 529
512 switch (const int ec = LastError()) { 530 return {-1, GetAndLogLastError()};
513 case WSAEWOULDBLOCK:
514 LOG_DEBUG(Service, "EAGAIN generated");
515 return {-1, Errno::AGAIN};
516 case WSAENOTCONN:
517 LOG_ERROR(Service, "ENOTCONN generated");
518 return {-1, Errno::NOTCONN};
519 default:
520 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
521 return {0, Errno::SUCCESS};
522 }
523} 531}
524 532
525std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) { 533std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) {
@@ -541,17 +549,7 @@ std::pair<s32, Errno> Socket::RecvFrom(int flags, std::vector<u8>& message, Sock
541 return {static_cast<s32>(result), Errno::SUCCESS}; 549 return {static_cast<s32>(result), Errno::SUCCESS};
542 } 550 }
543 551
544 switch (const int ec = LastError()) { 552 return {-1, GetAndLogLastError()};
545 case WSAEWOULDBLOCK:
546 LOG_DEBUG(Service, "EAGAIN generated");
547 return {-1, Errno::AGAIN};
548 case WSAENOTCONN:
549 LOG_ERROR(Service, "ENOTCONN generated");
550 return {-1, Errno::NOTCONN};
551 default:
552 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
553 return {-1, Errno::SUCCESS};
554 }
555} 553}
556 554
557std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) { 555std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) {
@@ -564,18 +562,7 @@ std::pair<s32, Errno> Socket::Send(const std::vector<u8>& message, int flags) {
564 return {static_cast<s32>(result), Errno::SUCCESS}; 562 return {static_cast<s32>(result), Errno::SUCCESS};
565 } 563 }
566 564
567 const int ec = LastError(); 565 return {-1, GetAndLogLastError()};
568 switch (ec) {
569 case WSAEWOULDBLOCK:
570 LOG_DEBUG(Service, "EAGAIN generated");
571 return {-1, Errno::AGAIN};
572 case WSAENOTCONN:
573 LOG_ERROR(Service, "ENOTCONN generated");
574 return {-1, Errno::NOTCONN};
575 default:
576 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
577 return {-1, Errno::SUCCESS};
578 }
579} 566}
580 567
581std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message, 568std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message,
@@ -597,9 +584,7 @@ std::pair<s32, Errno> Socket::SendTo(u32 flags, const std::vector<u8>& message,
597 return {static_cast<s32>(result), Errno::SUCCESS}; 584 return {static_cast<s32>(result), Errno::SUCCESS};
598 } 585 }
599 586
600 const int ec = LastError(); 587 return {-1, GetAndLogLastError()};
601 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
602 return {-1, Errno::SUCCESS};
603} 588}
604 589
605Errno Socket::Close() { 590Errno Socket::Close() {
@@ -642,9 +627,7 @@ Errno Socket::SetNonBlock(bool enable) {
642 if (EnableNonBlock(fd, enable)) { 627 if (EnableNonBlock(fd, enable)) {
643 return Errno::SUCCESS; 628 return Errno::SUCCESS;
644 } 629 }
645 const int ec = LastError(); 630 return GetAndLogLastError();
646 UNREACHABLE_MSG("Unhandled host socket error={}", ec);
647 return Errno::SUCCESS;
648} 631}
649 632
650bool Socket::IsOpened() const { 633bool Socket::IsOpened() const {
diff --git a/src/core/network/network.h b/src/core/network/network.h
index 76b2821f2..bd30f1899 100644
--- a/src/core/network/network.h
+++ b/src/core/network/network.h
@@ -7,6 +7,7 @@
7#include <array> 7#include <array>
8#include <utility> 8#include <utility>
9 9
10#include "common/common_funcs.h"
10#include "common/common_types.h" 11#include "common/common_types.h"
11 12
12namespace Network { 13namespace Network {
@@ -21,6 +22,11 @@ enum class Errno {
21 MFILE, 22 MFILE,
22 NOTCONN, 23 NOTCONN,
23 AGAIN, 24 AGAIN,
25 CONNREFUSED,
26 HOSTUNREACH,
27 NETDOWN,
28 NETUNREACH,
29 OTHER,
24}; 30};
25 31
26/// Address families 32/// Address families