mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 21:19:47 +00:00
coalesce the various sockopt
This commit is contained in:
@@ -790,49 +790,8 @@ Network::Errno BSD::SetSockOptImpl(s32 fd, u32 level, Network::OptName optname,
|
||||
}
|
||||
|
||||
Network::SocketBase* const socket = file_descriptors[fd]->socket.get();
|
||||
|
||||
if (optname == Network::OptName::LINGER) {
|
||||
ASSERT(optval.size() == sizeof(Network::Linger));
|
||||
auto linger = GetValue<Network::Linger>(optval);
|
||||
ASSERT(linger.onoff == 0 || linger.onoff == 1);
|
||||
return (socket->SetLinger(linger.onoff != 0, linger.linger));
|
||||
} else if (optname == Network::OptName::TIMESTAMP) {
|
||||
ASSERT(optval.size() == 4);
|
||||
auto value = GetValue<u32>(optval);
|
||||
return socket->SetTimeStamp(value);
|
||||
}
|
||||
|
||||
ASSERT(optval.size() == sizeof(u32));
|
||||
auto value = GetValue<u32>(optval);
|
||||
switch (optname) {
|
||||
case Network::OptName::REUSEADDR:
|
||||
ASSERT(value == 0 || value == 1);
|
||||
return (socket->SetReuseAddr(value != 0));
|
||||
case Network::OptName::KEEPALIVE:
|
||||
ASSERT(value == 0 || value == 1);
|
||||
return (socket->SetKeepAlive(value != 0));
|
||||
case Network::OptName::BROADCAST:
|
||||
ASSERT(value == 0 || value == 1);
|
||||
return (socket->SetBroadcast(value != 0));
|
||||
case Network::OptName::SNDBUF:
|
||||
return socket->SetSndBuf(value);
|
||||
case Network::OptName::RCVBUF:
|
||||
return socket->SetRcvBuf(value);
|
||||
case Network::OptName::SNDTIMEO:
|
||||
return socket->SetSndTimeo(value);
|
||||
case Network::OptName::RCVTIMEO:
|
||||
return socket->SetRcvTimeo(value);
|
||||
case Network::OptName::NOSIGPIPE:
|
||||
LOG_WARNING(Service, "(STUBBED) setting NOSIGPIPE to {}", value);
|
||||
return Network::Errno::SUCCESS;
|
||||
case Network::OptName::REUSEPORT:
|
||||
return socket->SetReusePort(value);
|
||||
case Network::OptName::ACCEPTFILTER:
|
||||
return socket->SetAcceptFilter(value);
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented optname={}", optname);
|
||||
return Network::Errno::SUCCESS;
|
||||
}
|
||||
return socket->SetSockOpt(fd, optname, optval);
|
||||
}
|
||||
|
||||
Network::Errno BSD::ShutdownImpl(s32 fd, s32 how) {
|
||||
|
||||
@@ -944,17 +944,76 @@ std::pair<T, Errno> Socket::GetSockOpt(SOCKET fd_so, int option) {
|
||||
return {value, GetAndLogLastError()};
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Errno Socket::SetSockOpt(SOCKET fd_so, int option, T value) {
|
||||
const int result =
|
||||
setsockopt(fd_so, SOL_SOCKET, option, reinterpret_cast<const char*>(&value), sizeof(value));
|
||||
if (result != SOCKET_ERROR) {
|
||||
static s32 TranslateOptNameToNative(Network::OptName optname) {
|
||||
switch (optname) {
|
||||
case Network::OptName::LINGER:
|
||||
return SO_LINGER;
|
||||
case Network::OptName::REUSEADDR:
|
||||
return SO_REUSEADDR;
|
||||
case Network::OptName::KEEPALIVE:
|
||||
return SO_KEEPALIVE;
|
||||
case Network::OptName::BROADCAST:
|
||||
return SO_BROADCAST;
|
||||
case Network::OptName::SNDBUF:
|
||||
return SO_SNDBUF;
|
||||
case Network::OptName::RCVBUF:
|
||||
return SO_RCVBUF;
|
||||
case Network::OptName::SNDTIMEO:
|
||||
return SO_SNDTIMEO;
|
||||
case Network::OptName::RCVTIMEO:
|
||||
return SO_RCVTIMEO;
|
||||
case Network::OptName::NOSIGPIPE:
|
||||
return SO_NOSIGPIPE;
|
||||
#ifdef SO_REUSEPORT
|
||||
case Network::OptName::REUSEPORT:
|
||||
return SO_REUSEPORT;
|
||||
#endif
|
||||
#ifdef SO_ACCEPTFILTER
|
||||
case Network::OptName::ACCEPTFILTER:
|
||||
return SO_ACCEPTFILTER;
|
||||
#endif
|
||||
#ifdef SO_TIMESTAMP
|
||||
case Network::OptName::TIMESTAMP:
|
||||
return SO_TIMESTAMP;
|
||||
#endif
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented optname={}", optname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Errno Socket::SetNonBlock(bool enable) {
|
||||
if (EnableNonBlock(fd, enable)) {
|
||||
is_non_blocking = enable;
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
return GetAndLogLastError();
|
||||
}
|
||||
|
||||
Errno Socket::SetSockOpt(SOCKET fd_so, Network::OptName optname, std::span<const u8> optval) {
|
||||
// TODO: is it >= or ==? for sizes
|
||||
if (optname == Network::OptName::LINGER) {
|
||||
if (optval.size() >= sizeof(Network::Linger)) {
|
||||
Network::Linger linger{};
|
||||
std::memcpy(&linger, optval.data(), sizeof(linger));
|
||||
auto const linkger_optval = MakeLinger(bool(linger.onoff), linger.linger);
|
||||
return setsockopt(fd_so, SOL_SOCKET, TranslateOptNameToNative(optname), reinterpret_cast<const char*>(linkger_optval.data()), socklen_t(linkger_optval.size())) != SOCKET_ERROR
|
||||
? Errno::SUCCESS
|
||||
: GetAndLogLastError();
|
||||
}
|
||||
return Errno::INVAL;
|
||||
}
|
||||
return setsockopt(fd_so, SOL_SOCKET, TranslateOptNameToNative(optname), reinterpret_cast<const char*>(optval.data()), socklen_t(optval.size())) != SOCKET_ERROR
|
||||
? Errno::SUCCESS
|
||||
: GetAndLogLastError();
|
||||
}
|
||||
|
||||
Errno Socket::Initialize(Domain domain, Type type, Protocol protocol) {
|
||||
if (type == Type::STREAM && protocol == Protocol::UDP) {
|
||||
LOG_WARNING(Network, "UDP used with STREAM");
|
||||
type = Type::DGRAM;
|
||||
}
|
||||
fd = socket(TranslateDomainToNative(domain), TranslateTypeToNative(type), TranslateProtocolToNative(protocol));
|
||||
if (fd != INVALID_SOCKET)
|
||||
return Errno::SUCCESS;
|
||||
@@ -1071,31 +1130,31 @@ Errno Socket::Shutdown(ShutdownHow how) {
|
||||
static s32 TranslateMsgOptToNative(s32 flags) {
|
||||
s32 r = 0;
|
||||
#ifdef MSG_OOB
|
||||
if (flags & s32(MsgOpt::OOB)) r |= MSG_OOB;
|
||||
if (0 != (flags & s32(MsgOpt::OOB))) r |= MSG_OOB;
|
||||
#endif
|
||||
#ifdef MSG_PEEK
|
||||
if (flags & s32(MsgOpt::PEEK)) r |= MSG_PEEK;
|
||||
if (0 != (flags & s32(MsgOpt::PEEK))) r |= MSG_PEEK;
|
||||
#endif
|
||||
#ifdef MSG_DONTROUTE
|
||||
if (flags & s32(MsgOpt::DONTROUTE)) r |= MSG_DONTROUTE;
|
||||
if (0 != (flags & s32(MsgOpt::DONTROUTE))) r |= MSG_DONTROUTE;
|
||||
#endif
|
||||
#ifdef MSG_EOR
|
||||
if (flags & s32(MsgOpt::EOR_)) r |= MSG_EOR;
|
||||
if (0 != (flags & s32(MsgOpt::EOR_))) r |= MSG_EOR;
|
||||
#endif
|
||||
#ifdef MSG_TRUNC
|
||||
if (flags & s32(MsgOpt::TRUNC)) r |= MSG_TRUNC;
|
||||
if (0 != (flags & s32(MsgOpt::TRUNC))) r |= MSG_TRUNC;
|
||||
#endif
|
||||
#ifdef MSG_CTRUNC
|
||||
if (flags & s32(MsgOpt::CTRUNC)) r |= MSG_CTRUNC;
|
||||
if (0 != (flags & s32(MsgOpt::CTRUNC))) r |= MSG_CTRUNC;
|
||||
#endif
|
||||
#ifdef MSG_WAITALL
|
||||
if (flags & s32(MsgOpt::WAITALL)) r |= MSG_WAITALL;
|
||||
if (0 != (flags & s32(MsgOpt::WAITALL))) r |= MSG_WAITALL;
|
||||
#endif
|
||||
#ifdef MSG_DONTWAIT
|
||||
if (flags & s32(MsgOpt::DONTWAIT)) r |= MSG_DONTWAIT;
|
||||
if (0 != (flags & s32(MsgOpt::DONTWAIT))) r |= MSG_DONTWAIT;
|
||||
#endif
|
||||
#ifdef MSG_EOF
|
||||
if (flags & s32(MsgOpt::EOF_)) r |= MSG_EOF;
|
||||
if (0 != (flags & s32(MsgOpt::EOF_))) r |= MSG_EOF;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
@@ -1186,73 +1245,6 @@ std::pair<Errno, Errno> Socket::GetPendingError() {
|
||||
return {TranslateNativeError(pending_err), getsockopt_err};
|
||||
}
|
||||
|
||||
Errno Socket::SetLinger(bool enable, u32 linger) {
|
||||
return SetSockOpt(fd, SO_LINGER, MakeLinger(enable, linger));
|
||||
}
|
||||
|
||||
Errno Socket::SetReuseAddr(bool enable) {
|
||||
return SetSockOpt<u32>(fd, SO_REUSEADDR, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
Errno Socket::SetKeepAlive(bool enable) {
|
||||
return SetSockOpt<u32>(fd, SO_KEEPALIVE, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
Errno Socket::SetBroadcast(bool enable) {
|
||||
return SetSockOpt<u32>(fd, SO_BROADCAST, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
Errno Socket::SetSndBuf(u32 value) {
|
||||
return SetSockOpt(fd, SO_SNDBUF, value);
|
||||
}
|
||||
|
||||
Errno Socket::SetRcvBuf(u32 value) {
|
||||
return SetSockOpt(fd, SO_RCVBUF, value);
|
||||
}
|
||||
|
||||
Errno Socket::SetSndTimeo(u32 value) {
|
||||
return SetSockOpt(fd, SO_SNDTIMEO, value);
|
||||
}
|
||||
|
||||
Errno Socket::SetRcvTimeo(u32 value) {
|
||||
return SetSockOpt(fd, SO_RCVTIMEO, value);
|
||||
}
|
||||
|
||||
Errno Socket::SetReusePort(u32 value) {
|
||||
#ifdef SO_REUSEPORT
|
||||
return SetSockOpt(fd, SO_REUSEPORT, value);
|
||||
#else
|
||||
LOG_WARNING(Network, "(stubbed)");
|
||||
return Errno::SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
Errno Socket::SetTimeStamp(u32 value) {
|
||||
#ifdef SO_TIMESTAMP
|
||||
return SetSockOpt(fd, SO_TIMESTAMP, value);
|
||||
#else
|
||||
LOG_WARNING(Network, "(stubbed)");
|
||||
return Errno::SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
Errno Socket::SetAcceptFilter(u32 value) {
|
||||
#ifdef SO_ACCEPTFILTER
|
||||
return SetSockOpt(fd, SO_ACCEPTFILTER, value);
|
||||
#else
|
||||
LOG_WARNING(Network, "(stubbed)");
|
||||
return Errno::SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
Errno Socket::SetNonBlock(bool enable) {
|
||||
if (EnableNonBlock(fd, enable)) {
|
||||
is_non_blocking = enable;
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
return GetAndLogLastError();
|
||||
}
|
||||
|
||||
bool Socket::IsOpened() const {
|
||||
return fd != INVALID_SOCKET;
|
||||
}
|
||||
|
||||
@@ -47,16 +47,29 @@ void ProxySocket::HandleProxyPacket(const ProxyPacket& packet) {
|
||||
received_packets.push(decompressed);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Errno ProxySocket::SetSockOpt(SOCKET fd_, int option, T value) {
|
||||
LOG_DEBUG(Network, "(STUBBED) called");
|
||||
Errno ProxySocket::SetNonBlock(bool enable) {
|
||||
blocking = !enable;
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetSockOpt(SOCKET fd_, Network::OptName option, std::span<const u8> optval) {
|
||||
LOG_DEBUG(Network, "(stubbed) called");
|
||||
// numeric values?
|
||||
if (optval.size() >= sizeof(u32)) {
|
||||
u32 value;
|
||||
std::memcpy(&value, optval.data(), sizeof(value));
|
||||
if (option == Network::OptName::BROADCAST)
|
||||
broadcast = bool(value);
|
||||
if (option == Network::OptName::SNDTIMEO)
|
||||
send_timeout = value;
|
||||
if (option == Network::OptName::RCVTIMEO)
|
||||
receive_timeout = value;
|
||||
}
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
Errno ProxySocket::Initialize(Domain domain, Type type, Protocol socket_protocol) {
|
||||
protocol = socket_protocol;
|
||||
SetSockOpt(fd, SO_TYPE, type);
|
||||
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
@@ -246,79 +259,6 @@ Errno ProxySocket::Close() {
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetLinger(bool enable, u32 linger) {
|
||||
struct {
|
||||
u16 linger_enable;
|
||||
u16 linger_time;
|
||||
} values;
|
||||
values.linger_enable = enable ? 1 : 0;
|
||||
values.linger_time = u16(linger);
|
||||
return SetSockOpt(fd, SO_LINGER, values);
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetReuseAddr(bool enable) {
|
||||
return SetSockOpt<u32>(fd, SO_REUSEADDR, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetBroadcast(bool enable) {
|
||||
broadcast = enable;
|
||||
return SetSockOpt<u32>(fd, SO_BROADCAST, enable ? 1 : 0);
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetSndBuf(u32 value) {
|
||||
return SetSockOpt(fd, SO_SNDBUF, value);
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetKeepAlive(bool enable) {
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetRcvBuf(u32 value) {
|
||||
return SetSockOpt(fd, SO_RCVBUF, value);
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetSndTimeo(u32 value) {
|
||||
send_timeout = value;
|
||||
return SetSockOpt(fd, SO_SNDTIMEO, static_cast<int>(value));
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetRcvTimeo(u32 value) {
|
||||
receive_timeout = value;
|
||||
return SetSockOpt(fd, SO_RCVTIMEO, static_cast<int>(value));
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetReusePort(u32 value) {
|
||||
#ifdef SO_REUSEPORT
|
||||
return SetSockOpt(fd, SO_REUSEPORT, value);
|
||||
#else
|
||||
LOG_WARNING(Network, "(stubbed)");
|
||||
return Errno::SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetTimeStamp(u32 value) {
|
||||
#ifdef SO_TIMESTAMP
|
||||
return SetSockOpt(fd, SO_TIMESTAMP, value);
|
||||
#else
|
||||
LOG_WARNING(Network, "(stubbed)");
|
||||
return Errno::SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetAcceptFilter(u32 value) {
|
||||
#ifdef SO_ACCEPTFILTER
|
||||
return SetSockOpt(fd, SO_ACCEPTFILTER, value);
|
||||
#else
|
||||
LOG_WARNING(Network, "(stubbed)");
|
||||
return Errno::SUCCESS;
|
||||
#endif
|
||||
}
|
||||
|
||||
Errno ProxySocket::SetNonBlock(bool enable) {
|
||||
blocking = !enable;
|
||||
return Errno::SUCCESS;
|
||||
}
|
||||
|
||||
std::pair<Errno, Errno> ProxySocket::GetPendingError() {
|
||||
LOG_DEBUG(Network, "(STUBBED) called");
|
||||
return {Errno::SUCCESS, Errno::SUCCESS};
|
||||
|
||||
@@ -55,21 +55,9 @@ public:
|
||||
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
|
||||
const Network::SockAddrIn* addr) override;
|
||||
|
||||
Errno SetLinger(bool enable, u32 linger) override;
|
||||
Errno SetReuseAddr(bool enable) override;
|
||||
Errno SetBroadcast(bool enable) override;
|
||||
Errno SetKeepAlive(bool enable) override;
|
||||
Errno SetSndBuf(u32 value) override;
|
||||
Errno SetRcvBuf(u32 value) override;
|
||||
Errno SetSndTimeo(u32 value) override;
|
||||
Errno SetRcvTimeo(u32 value) override;
|
||||
Errno SetReusePort(u32 value) override;
|
||||
Errno SetTimeStamp(u32 value) override;
|
||||
Errno SetAcceptFilter(u32 value) override;
|
||||
Errno SetNonBlock(bool enable) override;
|
||||
|
||||
template <typename T>
|
||||
Errno SetSockOpt(SOCKET fd, int option, T value);
|
||||
Errno SetSockOpt(SOCKET fd, Network::OptName option, std::span<const u8> value) override;
|
||||
|
||||
std::pair<Errno, Errno> GetPendingError() override;
|
||||
|
||||
|
||||
@@ -252,6 +252,8 @@ enum class MsgOpt : u32 {
|
||||
};
|
||||
|
||||
enum class OptName : u32 {
|
||||
DEBUG = 0x0001,
|
||||
ACCEPTCONN = 0x0002,
|
||||
REUSEADDR = 0x0004,
|
||||
KEEPALIVE = 0x0008,
|
||||
DONTROUTE = 0x0010,
|
||||
|
||||
@@ -64,22 +64,12 @@ public:
|
||||
|
||||
virtual std::pair<s32, Errno> Send(std::span<const u8> message, int flags) = 0;
|
||||
|
||||
virtual std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
|
||||
const Network::SockAddrIn* addr) = 0;
|
||||
virtual std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) = 0;
|
||||
|
||||
virtual Errno SetLinger(bool enable, u32 linger) = 0;
|
||||
virtual Errno SetReuseAddr(bool enable) = 0;
|
||||
virtual Errno SetKeepAlive(bool enable) = 0;
|
||||
virtual Errno SetBroadcast(bool enable) = 0;
|
||||
virtual Errno SetSndBuf(u32 value) = 0;
|
||||
virtual Errno SetRcvBuf(u32 value) = 0;
|
||||
virtual Errno SetSndTimeo(u32 value) = 0;
|
||||
virtual Errno SetRcvTimeo(u32 value) = 0;
|
||||
virtual Errno SetReusePort(u32 value) = 0;
|
||||
virtual Errno SetTimeStamp(u32 value) = 0;
|
||||
virtual Errno SetAcceptFilter(u32 value) = 0;
|
||||
virtual Errno SetNonBlock(bool enable) = 0;
|
||||
|
||||
virtual Errno SetSockOpt(SOCKET fd, Network::OptName option, std::span<const u8> value) = 0;
|
||||
|
||||
virtual std::pair<Errno, Errno> GetPendingError() = 0;
|
||||
|
||||
virtual bool IsOpened() const = 0;
|
||||
@@ -126,24 +116,11 @@ public:
|
||||
|
||||
std::pair<s32, Errno> Send(std::span<const u8> message, int flags) override;
|
||||
|
||||
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message,
|
||||
const Network::SockAddrIn* addr) override;
|
||||
std::pair<s32, Errno> SendTo(u32 flags, std::span<const u8> message, const Network::SockAddrIn* addr) override;
|
||||
|
||||
Errno SetLinger(bool enable, u32 linger) override;
|
||||
Errno SetReuseAddr(bool enable) override;
|
||||
Errno SetKeepAlive(bool enable) override;
|
||||
Errno SetBroadcast(bool enable) override;
|
||||
Errno SetSndBuf(u32 value) override;
|
||||
Errno SetRcvBuf(u32 value) override;
|
||||
Errno SetSndTimeo(u32 value) override;
|
||||
Errno SetRcvTimeo(u32 value) override;
|
||||
Errno SetReusePort(u32 value) override;
|
||||
Errno SetTimeStamp(u32 value) override;
|
||||
Errno SetAcceptFilter(u32 value) override;
|
||||
Errno SetNonBlock(bool enable) override;
|
||||
|
||||
template <typename T>
|
||||
Errno SetSockOpt(SOCKET fd, int option, T value);
|
||||
Errno SetSockOpt(SOCKET fd, Network::OptName option, std::span<const u8> value) override;
|
||||
|
||||
std::pair<Errno, Errno> GetPendingError() override;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user