mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-08-15 13:16:43 +00:00
add tcp options
This commit is contained in:
@@ -20,10 +20,11 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <poll.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#endif
|
||||
|
||||
#include "common/assert.h"
|
||||
@@ -937,38 +938,57 @@ Socket::Socket(Socket&& rhs) noexcept {
|
||||
fd = std::exchange(rhs.fd, INVALID_SOCKET);
|
||||
}
|
||||
|
||||
static s32 TranslateOptNameToNative(Network::OptName optname) {
|
||||
switch (optname) {
|
||||
// managarm doesn't like these
|
||||
static s32 TranslateOptNameToNative(Network::SocketLevel level, Network::OptName optname) {
|
||||
switch (level) {
|
||||
case Network::SocketLevel::SOCKET:
|
||||
switch (optname) {
|
||||
// managarm doesn't like these
|
||||
#ifdef SO_DEBUG
|
||||
case Network::OptName::DEBUG: return SO_DEBUG;
|
||||
case Network::OptName::DEBUG: return SO_DEBUG;
|
||||
#endif
|
||||
#ifdef SO_ACCEPTCONN
|
||||
case Network::OptName::ACCEPTCONN: return SO_ACCEPTCONN;
|
||||
case Network::OptName::ACCEPTCONN: return SO_ACCEPTCONN;
|
||||
#endif
|
||||
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;
|
||||
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;
|
||||
case Network::OptName::REUSEPORT: return SO_REUSEPORT;
|
||||
#endif
|
||||
#ifdef SO_ACCEPTFILTER
|
||||
case Network::OptName::ACCEPTFILTER: return SO_ACCEPTFILTER;
|
||||
case Network::OptName::ACCEPTFILTER: return SO_ACCEPTFILTER;
|
||||
#endif
|
||||
#ifdef SO_TIMESTAMP
|
||||
case Network::OptName::TIMESTAMP: return SO_TIMESTAMP;
|
||||
case Network::OptName::TIMESTAMP: return SO_TIMESTAMP;
|
||||
#endif
|
||||
case Network::OptName::ERROR_: return SO_ERROR;
|
||||
case Network::OptName::ERROR_: return SO_ERROR;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case Network::SocketLevel::TCP:
|
||||
switch (Network::TcpOptName(optname)) {
|
||||
case Network::TcpOptName::NODELAY: return TCP_NODELAY;
|
||||
case Network::TcpOptName::MAXSEG: return TCP_MAXSEG;
|
||||
case Network::TcpOptName::NOPUSH: return TCP_NOPUSH;
|
||||
case Network::TcpOptName::NOOPT: return TCP_NOOPT;
|
||||
case Network::TcpOptName::MD5SIG: return TCP_MD5SIG;
|
||||
case Network::TcpOptName::INFO: return TCP_INFO;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED_MSG("Unimplemented optname={}", optname);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
UNIMPLEMENTED_MSG("Unimplemented level={},optname={}", level, optname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static s32 TranslateSocketLevelToNative(Network::SocketLevel level) {
|
||||
@@ -977,15 +997,23 @@ static s32 TranslateSocketLevelToNative(Network::SocketLevel level) {
|
||||
// FreeBSD doesn't define below but Linux does :-(
|
||||
#ifdef SOL_IP
|
||||
case Network::SocketLevel::IP: return SOL_IP;
|
||||
#else
|
||||
case Network::SocketLevel::IP: return IPPROTO_IP;
|
||||
#endif
|
||||
#ifdef SOL_ICMP
|
||||
case Network::SocketLevel::ICMP: return SOL_ICMP;
|
||||
#else
|
||||
case Network::SocketLevel::ICMP: return IPPROTO_ICMP;
|
||||
#endif
|
||||
#ifdef SOL_TCP
|
||||
case Network::SocketLevel::TCP: return SOL_TCP;
|
||||
#else
|
||||
case Network::SocketLevel::TCP: return IPPROTO_TCP;
|
||||
#endif
|
||||
#ifdef SOL_UDP
|
||||
case Network::SocketLevel::UDP: return SOL_UDP;
|
||||
#else
|
||||
case Network::SocketLevel::UDP: return IPPROTO_UDP;
|
||||
#endif
|
||||
#ifdef SOL_CONFIG
|
||||
case Network::SocketLevel::CONFIG: return SOL_CONFIG;
|
||||
@@ -999,7 +1027,7 @@ static s32 TranslateSocketLevelToNative(Network::SocketLevel level) {
|
||||
Errno Socket::GetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<u8> value) {
|
||||
socklen_t len = socklen_t(value.size());
|
||||
auto const native_level = TranslateSocketLevelToNative(level);
|
||||
auto const native_optname = TranslateOptNameToNative(optname);
|
||||
auto const native_optname = TranslateOptNameToNative(level, optname);
|
||||
const int result = getsockopt(fd, native_level, native_optname, reinterpret_cast<char*>(value.data()), &len);
|
||||
if (result != SOCKET_ERROR) {
|
||||
ASSERT(len == socklen_t(value.size()));
|
||||
@@ -1019,7 +1047,7 @@ Errno Socket::SetNonBlock(bool enable) {
|
||||
Errno Socket::SetSockOpt(Network::SocketLevel level, Network::OptName optname, std::span<const u8> optval) {
|
||||
LOG_DEBUG(Network, "level={},optname={},optval={}", level, optname, optval.size());
|
||||
auto const native_level = TranslateSocketLevelToNative(level);
|
||||
auto const native_optname = TranslateOptNameToNative(optname);
|
||||
auto const native_optname = TranslateOptNameToNative(level, optname);
|
||||
// TODO: is it >= or ==? for sizes
|
||||
if (optname == Network::OptName::LINGER) {
|
||||
if (optval.size() >= sizeof(Network::Linger)) {
|
||||
|
||||
@@ -281,6 +281,14 @@ enum class OptName : u32 {
|
||||
NO_OFFLOAD = 0x4000,
|
||||
NO_DDP = 0x8000,
|
||||
};
|
||||
enum class TcpOptName : u32 {
|
||||
NODELAY = 0x0001,
|
||||
MAXSEG = 0x0002,
|
||||
NOPUSH = 0x0004,
|
||||
NOOPT = 0x0008,
|
||||
MS5SIG = 0x0010,
|
||||
INFO = 0x0020
|
||||
};
|
||||
|
||||
enum class ShutdownHow : s32 {
|
||||
RD = 0,
|
||||
|
||||
Reference in New Issue
Block a user