diff --git a/kernel/include/kernel/Networking/TCPSocket.h b/kernel/include/kernel/Networking/TCPSocket.h index fe21d1e6..3f6f41aa 100644 --- a/kernel/include/kernel/Networking/TCPSocket.h +++ b/kernel/include/kernel/Networking/TCPSocket.h @@ -64,6 +64,7 @@ namespace Kernel virtual BAN::ErrorOr sendmsg_impl(const msghdr& message, int flags) override; virtual BAN::ErrorOr getpeername_impl(sockaddr*, socklen_t*) override; virtual BAN::ErrorOr getsockopt_impl(int, int, void*, socklen_t*) override; + virtual BAN::ErrorOr setsockopt_impl(int, int, const void*, socklen_t) override; virtual BAN::ErrorOr ioctl_impl(int, void*) override; @@ -168,6 +169,10 @@ namespace Kernel Thread* m_thread { nullptr }; + // TODO: actually support these + bool m_keep_alive { false }; + bool m_no_delay { false }; + uint64_t m_time_wait_start_ms { 0 }; ThreadBlocker m_thread_blocker; diff --git a/kernel/include/kernel/Networking/UDPSocket.h b/kernel/include/kernel/Networking/UDPSocket.h index bb3226d4..81ff5bb2 100644 --- a/kernel/include/kernel/Networking/UDPSocket.h +++ b/kernel/include/kernel/Networking/UDPSocket.h @@ -39,6 +39,7 @@ namespace Kernel virtual BAN::ErrorOr sendmsg_impl(const msghdr& message, int flags) override; virtual BAN::ErrorOr getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); } virtual BAN::ErrorOr getsockopt_impl(int, int, void*, socklen_t*) override; + virtual BAN::ErrorOr setsockopt_impl(int, int, const void*, socklen_t) override; virtual BAN::ErrorOr ioctl_impl(int, void*) override; diff --git a/kernel/kernel/Networking/TCPSocket.cpp b/kernel/kernel/Networking/TCPSocket.cpp index 70b228b9..eb20955d 100644 --- a/kernel/kernel/Networking/TCPSocket.cpp +++ b/kernel/kernel/Networking/TCPSocket.cpp @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -298,23 +299,44 @@ namespace Kernel BAN::ErrorOr TCPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len) { - if (level != SOL_SOCKET) - return BAN::Error::from_errno(EINVAL); - int result; - switch (option) + + switch (level) { - case SO_ERROR: - result = 0; + case SOL_SOCKET: + switch (option) + { + case SO_KEEPALIVE: + result = m_keep_alive; + break; + case SO_ERROR: + result = 0; + break; + case SO_SNDBUF: + result = m_send_window.scaled_size(); + break; + case SO_RCVBUF: + result = m_recv_window.buffer->size(); + break; + default: + dwarnln("getsockopt(SOL_SOCKET, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); + } break; - case SO_SNDBUF: - result = m_send_window.scaled_size(); - break; - case SO_RCVBUF: - result = m_recv_window.buffer->size(); + case IPPROTO_TCP: + switch (option) + { + case TCP_NODELAY: + result = m_no_delay; + break; + default: + dwarnln("getsockopt(IPPROTO_TCP, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); + } break; default: - return BAN::Error::from_errno(ENOTSUP); + dwarnln("getsockopt({}, {})", level, option); + return BAN::Error::from_errno(EINVAL); } const size_t len = BAN::Math::min(sizeof(result), *value_len); @@ -324,6 +346,44 @@ namespace Kernel return {}; } + BAN::ErrorOr TCPSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len) + { + switch (level) + { + case SOL_SOCKET: + switch (option) + { + case SO_KEEPALIVE: + if (value_len != sizeof(int)) + return BAN::Error::from_errno(EINVAL); + m_keep_alive = *static_cast(value); + break; + default: + dwarnln("setsockopt(SOL_SOCKET, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); + } + break; + case IPPROTO_TCP: + switch (option) + { + case TCP_NODELAY: + if (value_len != sizeof(int)) + return BAN::Error::from_errno(EINVAL); + m_no_delay = *static_cast(value); + break; + default: + dwarnln("setsockopt(IPPROTO_TCP, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); + } + break; + default: + dwarnln("setsockopt({}, {})", level, option); + return BAN::Error::from_errno(EINVAL); + } + + return {}; + } + BAN::ErrorOr TCPSocket::ioctl_impl(int request, void* argument) { switch (request) diff --git a/kernel/kernel/Networking/UDPSocket.cpp b/kernel/kernel/Networking/UDPSocket.cpp index 257a27ef..3454e070 100644 --- a/kernel/kernel/Networking/UDPSocket.cpp +++ b/kernel/kernel/Networking/UDPSocket.cpp @@ -212,23 +212,33 @@ namespace Kernel BAN::ErrorOr UDPSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len) { - if (level != SOL_SOCKET) - return BAN::Error::from_errno(EINVAL); - int result; - switch (option) + + switch (level) { - case SO_ERROR: - result = 0; - break; - case SO_SNDBUF: - result = m_packet_buffer->size(); - break; - case SO_RCVBUF: - result = m_packet_buffer->size(); + case SOL_SOCKET: + switch (option) + { + case SO_ERROR: + result = 0; + break; + case SO_SNDBUF: + result = m_packet_buffer->size(); + break; + case SO_RCVBUF: + result = m_packet_buffer->size(); + break; + default: + dwarnln("getsockopt(SOLSOCKET, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); + } break; + case IPPROTO_UDP: + dwarnln("getsockopt(IPPROTO_UDP, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); default: - return BAN::Error::from_errno(ENOTSUP); + dwarnln("getsockopt({}, {})", level, option); + return BAN::Error::from_errno(EINVAL); } const size_t len = BAN::Math::min(sizeof(result), *value_len); @@ -238,6 +248,27 @@ namespace Kernel return {}; } + BAN::ErrorOr UDPSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len) + { + (void)value; + (void)value_len; + + switch (level) + { + case SOL_SOCKET: + dwarnln("setsockopt(SOL_SOCKET, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); + case IPPROTO_UDP: + dwarnln("setsockopt(IPPROTO_UDP, {})", option); + return BAN::Error::from_errno(ENOPROTOOPT); + default: + dwarnln("setsockopt({}, {})", level, option); + return BAN::Error::from_errno(EINVAL); + } + + return {}; + } + BAN::ErrorOr UDPSocket::ioctl_impl(int request, void* argument) { switch (request) diff --git a/kernel/kernel/Networking/UNIX/Socket.cpp b/kernel/kernel/Networking/UNIX/Socket.cpp index eb372859..62cabfbd 100644 --- a/kernel/kernel/Networking/UNIX/Socket.cpp +++ b/kernel/kernel/Networking/UNIX/Socket.cpp @@ -707,7 +707,10 @@ namespace Kernel BAN::ErrorOr UnixDomainSocket::getsockopt_impl(int level, int option, void* value, socklen_t* value_len) { if (level != SOL_SOCKET) + { + dwarnln("getsockopt({}, {})", level, option); return BAN::Error::from_errno(EINVAL); + } int result; switch (option) @@ -736,7 +739,10 @@ namespace Kernel BAN::ErrorOr UnixDomainSocket::setsockopt_impl(int level, int option, const void* value, socklen_t value_len) { if (level != SOL_SOCKET) + { + dwarnln("setsockopt({}, {})", level, option); return BAN::Error::from_errno(EINVAL); + } switch (option) {