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.cpp61
-rw-r--r--src/core/internal_network/network.h43
-rw-r--r--src/core/internal_network/socket_proxy.cpp282
-rw-r--r--src/core/internal_network/socket_proxy.h102
-rw-r--r--src/core/internal_network/sockets.h136
5 files changed, 524 insertions, 100 deletions
diff --git a/src/core/internal_network/network.cpp b/src/core/internal_network/network.cpp
index 36c43cc8f..160cc83e4 100644
--- a/src/core/internal_network/network.cpp
+++ b/src/core/internal_network/network.cpp
@@ -32,6 +32,7 @@
32#include "core/internal_network/network.h" 32#include "core/internal_network/network.h"
33#include "core/internal_network/network_interface.h" 33#include "core/internal_network/network_interface.h"
34#include "core/internal_network/sockets.h" 34#include "core/internal_network/sockets.h"
35#include "network/network.h"
35 36
36namespace Network { 37namespace Network {
37 38
@@ -114,7 +115,10 @@ Errno TranslateNativeError(int e) {
114 return Errno::NETDOWN; 115 return Errno::NETDOWN;
115 case WSAENETUNREACH: 116 case WSAENETUNREACH:
116 return Errno::NETUNREACH; 117 return Errno::NETUNREACH;
118 case WSAEMSGSIZE:
119 return Errno::MSGSIZE;
117 default: 120 default:
121 UNIMPLEMENTED_MSG("Unimplemented errno={}", e);
118 return Errno::OTHER; 122 return Errno::OTHER;
119 } 123 }
120} 124}
@@ -125,7 +129,6 @@ using SOCKET = int;
125using WSAPOLLFD = pollfd; 129using WSAPOLLFD = pollfd;
126using ULONG = u64; 130using ULONG = u64;
127 131
128constexpr SOCKET INVALID_SOCKET = -1;
129constexpr SOCKET SOCKET_ERROR = -1; 132constexpr SOCKET SOCKET_ERROR = -1;
130 133
131constexpr int SD_RECEIVE = SHUT_RD; 134constexpr int SD_RECEIVE = SHUT_RD;
@@ -206,7 +209,10 @@ Errno TranslateNativeError(int e) {
206 return Errno::NETDOWN; 209 return Errno::NETDOWN;
207 case ENETUNREACH: 210 case ENETUNREACH:
208 return Errno::NETUNREACH; 211 return Errno::NETUNREACH;
212 case EMSGSIZE:
213 return Errno::MSGSIZE;
209 default: 214 default:
215 UNIMPLEMENTED_MSG("Unimplemented errno={}", e);
210 return Errno::OTHER; 216 return Errno::OTHER;
211 } 217 }
212} 218}
@@ -329,16 +335,6 @@ PollEvents TranslatePollRevents(short revents) {
329 return result; 335 return result;
330} 336}
331 337
332template <typename T>
333Errno SetSockOpt(SOCKET fd, int option, T value) {
334 const int result =
335 setsockopt(fd, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value));
336 if (result != SOCKET_ERROR) {
337 return Errno::SUCCESS;
338 }
339 return GetAndLogLastError();
340}
341
342} // Anonymous namespace 338} // Anonymous namespace
343 339
344NetworkInstance::NetworkInstance() { 340NetworkInstance::NetworkInstance() {
@@ -350,26 +346,15 @@ NetworkInstance::~NetworkInstance() {
350} 346}
351 347
352std::optional<IPv4Address> GetHostIPv4Address() { 348std::optional<IPv4Address> GetHostIPv4Address() {
353 const std::string& selected_network_interface = Settings::values.network_interface.GetValue(); 349 const auto interface = Network::GetSelectedNetworkInterface();
354 const auto network_interfaces = Network::GetAvailableNetworkInterfaces(); 350 if (!interface.has_value()) {
355 if (network_interfaces.size() == 0) { 351 LOG_ERROR(Network, "GetSelectedNetworkInterface returned no interface");
356 LOG_ERROR(Network, "GetAvailableNetworkInterfaces returned no interfaces");
357 return {}; 352 return {};
358 } 353 }
359 354
360 const auto res = 355 char ip_addr[16] = {};
361 std::ranges::find_if(network_interfaces, [&selected_network_interface](const auto& iface) { 356 ASSERT(inet_ntop(AF_INET, &interface->ip_address, ip_addr, sizeof(ip_addr)) != nullptr);
362 return iface.name == selected_network_interface; 357 return TranslateIPv4(interface->ip_address);
363 });
364
365 if (res != network_interfaces.end()) {
366 char ip_addr[16] = {};
367 ASSERT(inet_ntop(AF_INET, &res->ip_address, ip_addr, sizeof(ip_addr)) != nullptr);
368 return TranslateIPv4(res->ip_address);
369 } else {
370 LOG_ERROR(Network, "Couldn't find selected interface \"{}\"", selected_network_interface);
371 return {};
372 }
373} 358}
374 359
375std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) { 360std::pair<s32, Errno> Poll(std::vector<PollFD>& pollfds, s32 timeout) {
@@ -412,7 +397,19 @@ Socket::~Socket() {
412 fd = INVALID_SOCKET; 397 fd = INVALID_SOCKET;
413} 398}
414 399
415Socket::Socket(Socket&& rhs) noexcept : fd{std::exchange(rhs.fd, INVALID_SOCKET)} {} 400Socket::Socket(Socket&& rhs) noexcept {
401 fd = std::exchange(rhs.fd, INVALID_SOCKET);
402}
403
404template <typename T>
405Errno Socket::SetSockOpt(SOCKET _fd, int option, T value) {
406 const int result =
407 setsockopt(_fd, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value));
408 if (result != SOCKET_ERROR) {
409 return Errno::SUCCESS;
410 }
411 return GetAndLogLastError();
412}
416 413
417Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) { 414Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
418 fd = socket(TranslateDomain(domain), TranslateType(type), TranslateProtocol(protocol)); 415 fd = socket(TranslateDomain(domain), TranslateType(type), TranslateProtocol(protocol));
@@ -423,7 +420,7 @@ Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
423 return GetAndLogLastError(); 420 return GetAndLogLastError();
424} 421}
425 422
426std::pair<Socket::AcceptResult, Errno> Socket::Accept() { 423std::pair<SocketBase::AcceptResult, Errno> Socket::Accept() {
427 sockaddr addr; 424 sockaddr addr;
428 socklen_t addrlen = sizeof(addr); 425 socklen_t addrlen = sizeof(addr);
429 const SOCKET new_socket = accept(fd, &addr, &addrlen); 426 const SOCKET new_socket = accept(fd, &addr, &addrlen);
@@ -634,4 +631,8 @@ bool Socket::IsOpened() const {
634 return fd != INVALID_SOCKET; 631 return fd != INVALID_SOCKET;
635} 632}
636 633
634void Socket::HandleProxyPacket(const ProxyPacket& packet) {
635 LOG_WARNING(Network, "ProxyPacket received, but not in Proxy mode!");
636}
637
637} // namespace Network 638} // namespace Network
diff --git a/src/core/internal_network/network.h b/src/core/internal_network/network.h
index 10e5ef10d..36994c22e 100644
--- a/src/core/internal_network/network.h
+++ b/src/core/internal_network/network.h
@@ -8,6 +8,7 @@
8 8
9#include "common/common_funcs.h" 9#include "common/common_funcs.h"
10#include "common/common_types.h" 10#include "common/common_types.h"
11#include "common/socket_types.h"
11 12
12#ifdef _WIN32 13#ifdef _WIN32
13#include <winsock2.h> 14#include <winsock2.h>
@@ -17,6 +18,7 @@
17 18
18namespace Network { 19namespace Network {
19 20
21class SocketBase;
20class Socket; 22class Socket;
21 23
22/// Error code for network functions 24/// Error code for network functions
@@ -31,46 +33,11 @@ enum class Errno {
31 HOSTUNREACH, 33 HOSTUNREACH,
32 NETDOWN, 34 NETDOWN,
33 NETUNREACH, 35 NETUNREACH,
36 TIMEDOUT,
37 MSGSIZE,
34 OTHER, 38 OTHER,
35}; 39};
36 40
37/// Address families
38enum class Domain {
39 INET, ///< Address family for IPv4
40};
41
42/// Socket types
43enum class Type {
44 STREAM,
45 DGRAM,
46 RAW,
47 SEQPACKET,
48};
49
50/// Protocol values for sockets
51enum class Protocol {
52 ICMP,
53 TCP,
54 UDP,
55};
56
57/// Shutdown mode
58enum class ShutdownHow {
59 RD,
60 WR,
61 RDWR,
62};
63
64/// Array of IPv4 address
65using IPv4Address = std::array<u8, 4>;
66
67/// Cross-platform sockaddr structure
68struct SockAddrIn {
69 Domain family;
70 IPv4Address ip;
71 u16 portno;
72};
73
74/// Cross-platform poll fd structure 41/// Cross-platform poll fd structure
75 42
76enum class PollEvents : u16 { 43enum class PollEvents : u16 {
@@ -86,7 +53,7 @@ enum class PollEvents : u16 {
86DECLARE_ENUM_FLAG_OPERATORS(PollEvents); 53DECLARE_ENUM_FLAG_OPERATORS(PollEvents);
87 54
88struct PollFD { 55struct PollFD {
89 Socket* socket; 56 SocketBase* socket;
90 PollEvents events; 57 PollEvents events;
91 PollEvents revents; 58 PollEvents revents;
92}; 59};
diff --git a/src/core/internal_network/socket_proxy.cpp b/src/core/internal_network/socket_proxy.cpp
new file mode 100644
index 000000000..6e8924822
--- /dev/null
+++ b/src/core/internal_network/socket_proxy.cpp
@@ -0,0 +1,282 @@
1// Copyright 2022 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <chrono>
6#include <thread>
7
8#include "common/assert.h"
9#include "common/logging/log.h"
10#include "core/internal_network/network.h"
11#include "core/internal_network/network_interface.h"
12#include "core/internal_network/socket_proxy.h"
13
14namespace Network {
15
16ProxySocket::ProxySocket(RoomNetwork& room_network_) noexcept : room_network{room_network_} {}
17
18ProxySocket::ProxySocket(ProxySocket&& rhs) noexcept : room_network{rhs.room_network} {
19 fd = std::exchange(rhs.fd, INVALID_SOCKET);
20}
21
22ProxySocket::~ProxySocket() {
23 if (fd == INVALID_SOCKET) {
24 return;
25 }
26 fd = INVALID_SOCKET;
27}
28
29void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) {
30 if (protocol != packet.protocol || local_endpoint.portno != packet.remote_endpoint.portno ||
31 closed) {
32 return;
33 }
34 std::lock_guard<std::mutex> guard(packets_mutex);
35 received_packets.push(packet);
36}
37
38template <typename T>
39Errno ProxySocket::SetSockOpt(SOCKET _fd, int option, T value) {
40 socket_options[option] = reinterpret_cast<const char*>(&value);
41 return Errno::SUCCESS;
42}
43
44Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol) {
45 protocol = socket_protocol;
46 socket_options[0x1008] = reinterpret_cast<const char*>(&type);
47
48 return Errno::SUCCESS;
49}
50
51std::pair<ProxySocket::AcceptResult, Errno> ProxySocket::Accept() {
52 LOG_WARNING(Network, "(STUBBED) called");
53 return {AcceptResult{}, Errno::SUCCESS};
54}
55
56Errno ProxySocket::Connect(SockAddrIn addr_in) {
57 LOG_WARNING(Network, "(STUBBED) called");
58 return Errno::SUCCESS;
59}
60
61std::pair<SockAddrIn, Errno> ProxySocket::GetPeerName() {
62 LOG_WARNING(Network, "(STUBBED) called");
63 return {SockAddrIn{}, Errno::SUCCESS};
64}
65
66std::pair<SockAddrIn, Errno> ProxySocket::GetSockName() {
67 LOG_WARNING(Network, "(STUBBED) called");
68 return {SockAddrIn{}, Errno::SUCCESS};
69}
70
71Errno ProxySocket::Bind(SockAddrIn addr) {
72 if (is_bound) {
73 LOG_WARNING(Network, "Rebinding Socket is unimplemented!");
74 return Errno::SUCCESS;
75 }
76 local_endpoint = addr;
77 is_bound = true;
78
79 return Errno::SUCCESS;
80}
81
82Errno ProxySocket::Listen(s32 backlog) {
83 LOG_WARNING(Network, "(STUBBED) called");
84 return Errno::SUCCESS;
85}
86
87Errno ProxySocket::Shutdown(ShutdownHow how) {
88 LOG_WARNING(Network, "(STUBBED) called");
89 return Errno::SUCCESS;
90}
91
92std::pair<s32, Errno> ProxySocket::Recv(int flags, std::vector<u8>& message) {
93 LOG_WARNING(Network, "(STUBBED) called");
94 ASSERT(flags == 0);
95 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
96
97 return {static_cast<s32>(0), Errno::SUCCESS};
98}
99
100std::pair<s32, Errno> ProxySocket::RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) {
101 ASSERT(flags == 0);
102 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
103
104 {
105 std::lock_guard<std::mutex> guard(packets_mutex);
106 if (received_packets.size() > 0) {
107 return ReceivePacket(flags, message, addr, message.size());
108 }
109 }
110
111 if (blocking) {
112 if (receive_timeout > 0) {
113 std::this_thread::sleep_for(std::chrono::milliseconds(receive_timeout));
114 }
115 } else {
116 return {-1, Errno::AGAIN};
117 }
118
119 std::lock_guard<std::mutex> guard(packets_mutex);
120 if (received_packets.size() > 0) {
121 return ReceivePacket(flags, message, addr, message.size());
122 }
123
124 return {-1, Errno::TIMEDOUT};
125}
126
127std::pair<s32, Errno> ProxySocket::ReceivePacket(int flags, std::vector<u8>& message,
128 SockAddrIn* addr, std::size_t max_length) {
129 ProxyPacket& packet = received_packets.front();
130 if (addr) {
131 addr->family = Domain::INET;
132 addr->ip = packet.local_endpoint.ip; // The senders ip address
133 addr->portno = packet.local_endpoint.portno; // The senders port number
134 }
135
136 bool peek = (flags & FLAG_MSG_PEEK) != 0;
137 std::size_t read_bytes;
138 if (packet.data.size() > max_length) {
139 read_bytes = max_length;
140 message.clear();
141 std::copy(packet.data.begin(), packet.data.begin() + read_bytes,
142 std::back_inserter(message));
143 message.resize(max_length);
144
145 if (protocol == Protocol::UDP) {
146 if (!peek) {
147 received_packets.pop();
148 }
149 return {-1, Errno::MSGSIZE};
150 } else if (protocol == Protocol::TCP) {
151 std::vector<u8> numArray(packet.data.size() - max_length);
152 std::copy(packet.data.begin() + max_length, packet.data.end(),
153 std::back_inserter(numArray));
154 packet.data = numArray;
155 }
156 } else {
157 read_bytes = packet.data.size();
158 message.clear();
159 std::copy(packet.data.begin(), packet.data.end(), std::back_inserter(message));
160 message.resize(max_length);
161 if (!peek) {
162 received_packets.pop();
163 }
164 }
165
166 return {static_cast<u32>(read_bytes), Errno::SUCCESS};
167}
168
169std::pair<s32, Errno> ProxySocket::Send(const std::vector<u8>& message, int flags) {
170 LOG_WARNING(Network, "(STUBBED) called");
171 ASSERT(message.size() < static_cast<size_t>(std::numeric_limits<int>::max()));
172 ASSERT(flags == 0);
173
174 return {static_cast<s32>(0), Errno::SUCCESS};
175}
176
177void ProxySocket::SendPacket(ProxyPacket& packet) {
178 if (auto room_member = room_network.GetRoomMember().lock()) {
179 if (room_member->IsConnected()) {
180 room_member->SendProxyPacket(packet);
181 }
182 }
183}
184
185std::pair<s32, Errno> ProxySocket::SendTo(u32 flags, const std::vector<u8>& message,
186 const SockAddrIn* addr) {
187 ASSERT(flags == 0);
188
189 if (!is_bound) {
190 LOG_ERROR(Network, "ProxySocket is not bound!");
191 return {static_cast<s32>(message.size()), Errno::SUCCESS};
192 }
193
194 if (auto room_member = room_network.GetRoomMember().lock()) {
195 if (!room_member->IsConnected()) {
196 return {static_cast<s32>(message.size()), Errno::SUCCESS};
197 }
198 }
199
200 ProxyPacket packet;
201 packet.local_endpoint = local_endpoint;
202 packet.remote_endpoint = *addr;
203 packet.protocol = protocol;
204 packet.broadcast = broadcast;
205
206 auto& ip = local_endpoint.ip;
207 auto ipv4 = Network::GetHostIPv4Address();
208 // If the ip is all zeroes (INADDR_ANY) or if it matches the hosts ip address,
209 // replace it with a "fake" routing address
210 if (std::all_of(ip.begin(), ip.end(), [](u8 i) { return i == 0; }) || (ipv4 && ipv4 == ip)) {
211 if (auto room_member = room_network.GetRoomMember().lock()) {
212 packet.local_endpoint.ip = room_member->GetFakeIpAddress();
213 }
214 }
215
216 packet.data.clear();
217 std::copy(message.begin(), message.end(), std::back_inserter(packet.data));
218
219 SendPacket(packet);
220
221 return {static_cast<s32>(message.size()), Errno::SUCCESS};
222}
223
224Errno ProxySocket::Close() {
225 fd = INVALID_SOCKET;
226 closed = true;
227
228 return Errno::SUCCESS;
229}
230
231Errno ProxySocket::SetLinger(bool enable, u32 linger) {
232 struct Linger {
233 u16 linger_enable;
234 u16 linger_time;
235 } values;
236 values.linger_enable = enable ? 1 : 0;
237 values.linger_time = static_cast<u16>(linger);
238
239 return SetSockOpt(fd, SO_LINGER, values);
240}
241
242Errno ProxySocket::SetReuseAddr(bool enable) {
243 return SetSockOpt<u32>(fd, SO_REUSEADDR, enable ? 1 : 0);
244}
245
246Errno ProxySocket::SetBroadcast(bool enable) {
247 broadcast = enable;
248 return SetSockOpt<u32>(fd, SO_BROADCAST, enable ? 1 : 0);
249}
250
251Errno ProxySocket::SetSndBuf(u32 value) {
252 return SetSockOpt(fd, SO_SNDBUF, value);
253}
254
255Errno ProxySocket::SetKeepAlive(bool enable) {
256 return Errno::SUCCESS;
257}
258
259Errno ProxySocket::SetRcvBuf(u32 value) {
260 return SetSockOpt(fd, SO_RCVBUF, value);
261}
262
263Errno ProxySocket::SetSndTimeo(u32 value) {
264 send_timeout = value;
265 return SetSockOpt(fd, SO_SNDTIMEO, static_cast<int>(value));
266}
267
268Errno ProxySocket::SetRcvTimeo(u32 value) {
269 receive_timeout = value;
270 return SetSockOpt(fd, SO_RCVTIMEO, static_cast<int>(value));
271}
272
273Errno ProxySocket::SetNonBlock(bool enable) {
274 blocking = !enable;
275 return Errno::SUCCESS;
276}
277
278bool ProxySocket::IsOpened() const {
279 return fd != INVALID_SOCKET;
280}
281
282} // namespace Network
diff --git a/src/core/internal_network/socket_proxy.h b/src/core/internal_network/socket_proxy.h
new file mode 100644
index 000000000..ef7d5b554
--- /dev/null
+++ b/src/core/internal_network/socket_proxy.h
@@ -0,0 +1,102 @@
1// Copyright 2022 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <mutex>
8#include <vector>
9#include <queue>
10
11#include "core/internal_network/sockets.h"
12#include "network/network.h"
13
14namespace Network {
15
16class ProxySocket : public SocketBase {
17public:
18 ProxySocket(RoomNetwork& room_network_) noexcept;
19 ~ProxySocket() override;
20
21 ProxySocket(const ProxySocket&) = delete;
22 ProxySocket& operator=(const ProxySocket&) = delete;
23
24 ProxySocket(ProxySocket&& rhs) noexcept;
25
26 // Avoid closing sockets implicitly
27 ProxySocket& operator=(ProxySocket&&) noexcept = delete;
28
29 void HandleProxyPacket(const ProxyPacket& packet);
30
31 Errno Initialize(Domain domain, Type type, Protocol socket_protocol) override;
32
33 Errno Close() override;
34
35 std::pair<AcceptResult, Errno> Accept() override;
36
37 Errno Connect(SockAddrIn addr_in) override;
38
39 std::pair<SockAddrIn, Errno> GetPeerName() override;
40
41 std::pair<SockAddrIn, Errno> GetSockName() override;
42
43 Errno Bind(SockAddrIn addr) override;
44
45 Errno Listen(s32 backlog) override;
46
47 Errno Shutdown(ShutdownHow how) override;
48
49 std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message) override;
50
51 std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) override;
52
53 std::pair<s32, Errno> ReceivePacket(int flags, std::vector<u8>& message, SockAddrIn* addr,
54 std::size_t max_length);
55
56 std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags) override;
57
58 void SendPacket(ProxyPacket& packet);
59
60 std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message,
61 const SockAddrIn* addr) override;
62
63 Errno SetLinger(bool enable, u32 linger) override;
64
65 Errno SetReuseAddr(bool enable) override;
66
67 Errno SetBroadcast(bool enable) override;
68
69 Errno SetKeepAlive(bool enable) override;
70
71 Errno SetSndBuf(u32 value) override;
72
73 Errno SetRcvBuf(u32 value) override;
74
75 Errno SetSndTimeo(u32 value) override;
76
77 Errno SetRcvTimeo(u32 value) override;
78
79 Errno SetNonBlock(bool enable) override;
80
81 template <typename T>
82 Errno SetSockOpt(SOCKET fd, int option, T value);
83
84 bool IsOpened() const override;
85
86 bool broadcast = false;
87 bool closed = false;
88 u32 send_timeout = 0;
89 u32 receive_timeout = 0;
90 std::map<int, const char*> socket_options;
91 bool is_bound = false;
92 SockAddrIn local_endpoint{};
93 bool blocking = true;
94 std::queue<ProxyPacket> received_packets;
95 Protocol protocol;
96
97 std::mutex packets_mutex;
98
99 RoomNetwork& room_network;
100};
101
102} // namespace Network
diff --git a/src/core/internal_network/sockets.h b/src/core/internal_network/sockets.h
index 77e27e928..92dc49993 100644
--- a/src/core/internal_network/sockets.h
+++ b/src/core/internal_network/sockets.h
@@ -14,20 +14,92 @@
14 14
15#include "common/common_types.h" 15#include "common/common_types.h"
16#include "core/internal_network/network.h" 16#include "core/internal_network/network.h"
17#include "network/network.h"
17 18
18// TODO: C++20 Replace std::vector usages with std::span 19// TODO: C++20 Replace std::vector usages with std::span
19 20
20namespace Network { 21namespace Network {
21 22
22class Socket { 23class SocketBase {
23public: 24public:
25#ifdef YUZU_UNIX
26 using SOCKET = int;
27 static constexpr SOCKET INVALID_SOCKET = -1;
28 static constexpr SOCKET SOCKET_ERROR = -1;
29#endif
30
24 struct AcceptResult { 31 struct AcceptResult {
25 std::unique_ptr<Socket> socket; 32 std::unique_ptr<SocketBase> socket;
26 SockAddrIn sockaddr_in; 33 SockAddrIn sockaddr_in;
27 }; 34 };
35 virtual ~SocketBase() {}
36
37 virtual SocketBase& operator=(const SocketBase&) = delete;
38
39 // Avoid closing sockets implicitly
40 virtual SocketBase& operator=(SocketBase&&) noexcept = delete;
41
42 virtual Errno Initialize(Domain domain, Type type, Protocol protocol) = 0;
43
44 virtual Errno Close() = 0;
45
46 virtual std::pair<AcceptResult, Errno> Accept() = 0;
47
48 virtual Errno Connect(SockAddrIn addr_in) = 0;
49
50 virtual std::pair<SockAddrIn, Errno> GetPeerName() = 0;
51
52 virtual std::pair<SockAddrIn, Errno> GetSockName() = 0;
53
54 virtual Errno Bind(SockAddrIn addr) = 0;
55
56 virtual Errno Listen(s32 backlog) = 0;
57
58 virtual Errno Shutdown(ShutdownHow how) = 0;
59
60 virtual std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message) = 0;
61
62 virtual std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message,
63 SockAddrIn* addr) = 0;
64
65 virtual std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags) = 0;
66
67 virtual std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message,
68 const SockAddrIn* addr) = 0;
69
70 virtual Errno SetLinger(bool enable, u32 linger) = 0;
71
72 virtual Errno SetReuseAddr(bool enable) = 0;
73
74 virtual Errno SetKeepAlive(bool enable) = 0;
75
76 virtual Errno SetBroadcast(bool enable) = 0;
28 77
29 explicit Socket() = default; 78 virtual Errno SetSndBuf(u32 value) = 0;
30 ~Socket(); 79
80 virtual Errno SetRcvBuf(u32 value) = 0;
81
82 virtual Errno SetSndTimeo(u32 value) = 0;
83
84 virtual Errno SetRcvTimeo(u32 value) = 0;
85
86 virtual Errno SetNonBlock(bool enable) = 0;
87
88 virtual bool IsOpened() const = 0;
89
90 virtual void HandleProxyPacket(const ProxyPacket& packet) = 0;
91
92#if defined(_WIN32)
93 SOCKET fd = INVALID_SOCKET;
94#elif YUZU_UNIX
95 int fd = -1;
96#endif
97};
98
99class Socket : public SocketBase {
100public:
101 Socket() = default;
102 ~Socket() override;
31 103
32 Socket(const Socket&) = delete; 104 Socket(const Socket&) = delete;
33 Socket& operator=(const Socket&) = delete; 105 Socket& operator=(const Socket&) = delete;
@@ -37,57 +109,57 @@ public:
37 // Avoid closing sockets implicitly 109 // Avoid closing sockets implicitly
38 Socket& operator=(Socket&&) noexcept = delete; 110 Socket& operator=(Socket&&) noexcept = delete;
39 111
40 Errno Initialize(Domain domain, Type type, Protocol protocol); 112 Errno Initialize(Domain domain, Type type, Protocol protocol) override;
41 113
42 Errno Close(); 114 Errno Close() override;
43 115
44 std::pair<AcceptResult, Errno> Accept(); 116 std::pair<AcceptResult, Errno> Accept() override;
45 117
46 Errno Connect(SockAddrIn addr_in); 118 Errno Connect(SockAddrIn addr_in) override;
47 119
48 std::pair<SockAddrIn, Errno> GetPeerName(); 120 std::pair<SockAddrIn, Errno> GetPeerName() override;
49 121
50 std::pair<SockAddrIn, Errno> GetSockName(); 122 std::pair<SockAddrIn, Errno> GetSockName() override;
51 123
52 Errno Bind(SockAddrIn addr); 124 Errno Bind(SockAddrIn addr) override;
53 125
54 Errno Listen(s32 backlog); 126 Errno Listen(s32 backlog) override;
55 127
56 Errno Shutdown(ShutdownHow how); 128 Errno Shutdown(ShutdownHow how) override;
57 129
58 std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message); 130 std::pair<s32, Errno> Recv(int flags, std::vector<u8>& message) override;
59 131
60 std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr); 132 std::pair<s32, Errno> RecvFrom(int flags, std::vector<u8>& message, SockAddrIn* addr) override;
61 133
62 std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags); 134 std::pair<s32, Errno> Send(const std::vector<u8>& message, int flags) override;
63 135
64 std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message, const SockAddrIn* addr); 136 std::pair<s32, Errno> SendTo(u32 flags, const std::vector<u8>& message,
137 const SockAddrIn* addr) override;
65 138
66 Errno SetLinger(bool enable, u32 linger); 139 Errno SetLinger(bool enable, u32 linger) override;
67 140
68 Errno SetReuseAddr(bool enable); 141 Errno SetReuseAddr(bool enable) override;
69 142
70 Errno SetKeepAlive(bool enable); 143 Errno SetKeepAlive(bool enable) override;
71 144
72 Errno SetBroadcast(bool enable); 145 Errno SetBroadcast(bool enable) override;
73 146
74 Errno SetSndBuf(u32 value); 147 Errno SetSndBuf(u32 value) override;
75 148
76 Errno SetRcvBuf(u32 value); 149 Errno SetRcvBuf(u32 value) override;
77 150
78 Errno SetSndTimeo(u32 value); 151 Errno SetSndTimeo(u32 value) override;
79 152
80 Errno SetRcvTimeo(u32 value); 153 Errno SetRcvTimeo(u32 value) override;
81 154
82 Errno SetNonBlock(bool enable); 155 Errno SetNonBlock(bool enable) override;
83 156
84 bool IsOpened() const; 157 template <typename T>
158 Errno SetSockOpt(SOCKET fd, int option, T value);
85 159
86#if defined(_WIN32) 160 bool IsOpened() const override;
87 SOCKET fd = INVALID_SOCKET; 161
88#elif YUZU_UNIX 162 void HandleProxyPacket(const ProxyPacket& packet) override;
89 int fd = -1;
90#endif
91}; 163};
92 164
93std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout); 165std::pair<s32, Errno> Poll(std::vector<PollFD>& poll_fds, s32 timeout);