Kernel: Move {set,get}sockopt to sockets
Sockets can now actually implement socket options :D
This commit is contained in:
parent
9809f87010
commit
a51a81b6cd
|
|
@ -113,6 +113,8 @@ namespace Kernel
|
||||||
BAN::ErrorOr<size_t> recvmsg(msghdr& message, int flags);
|
BAN::ErrorOr<size_t> recvmsg(msghdr& message, int flags);
|
||||||
BAN::ErrorOr<void> getsockname(sockaddr* address, socklen_t* address_len);
|
BAN::ErrorOr<void> getsockname(sockaddr* address, socklen_t* address_len);
|
||||||
BAN::ErrorOr<void> getpeername(sockaddr* address, socklen_t* address_len);
|
BAN::ErrorOr<void> getpeername(sockaddr* address, socklen_t* address_len);
|
||||||
|
BAN::ErrorOr<void> getsockopt(int level, int option, void* value, socklen_t* value_len);
|
||||||
|
BAN::ErrorOr<void> setsockopt(int level, int option, const void* value, socklen_t value_len);
|
||||||
|
|
||||||
// General API
|
// General API
|
||||||
BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
|
BAN::ErrorOr<size_t> read(off_t, BAN::ByteSpan buffer);
|
||||||
|
|
@ -161,6 +163,8 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); }
|
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr&, int) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
|
virtual BAN::ErrorOr<void> getsockname_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
|
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
|
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
|
virtual BAN::ErrorOr<void> setsockopt_impl(int, int, const void*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
|
|
||||||
// General API
|
// General API
|
||||||
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); }
|
virtual BAN::ErrorOr<size_t> read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); }
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
||||||
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
||||||
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
|
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
|
||||||
|
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
|
||||||
|
|
||||||
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
||||||
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
||||||
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
|
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override { return BAN::Error::from_errno(ENOTCONN); }
|
||||||
|
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
|
||||||
|
|
||||||
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
virtual BAN::ErrorOr<long> ioctl_impl(int, void*) override;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,8 @@ namespace Kernel
|
||||||
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> recvmsg_impl(msghdr& message, int flags) override;
|
||||||
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
virtual BAN::ErrorOr<size_t> sendmsg_impl(const msghdr& message, int flags) override;
|
||||||
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
|
virtual BAN::ErrorOr<void> getpeername_impl(sockaddr*, socklen_t*) override;
|
||||||
|
virtual BAN::ErrorOr<void> getsockopt_impl(int, int, void*, socklen_t*) override;
|
||||||
|
virtual BAN::ErrorOr<void> setsockopt_impl(int, int, const void*, socklen_t) override;
|
||||||
|
|
||||||
virtual bool can_read_impl() const override;
|
virtual bool can_read_impl() const override;
|
||||||
virtual bool can_write_impl() const override;
|
virtual bool can_write_impl() const override;
|
||||||
|
|
|
||||||
|
|
@ -222,6 +222,22 @@ namespace Kernel
|
||||||
return getpeername_impl(address, address_len);
|
return getpeername_impl(address, address_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> Inode::getsockopt(int level, int option, void* value, socklen_t* value_len)
|
||||||
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
if (!mode().ifsock())
|
||||||
|
return BAN::Error::from_errno(ENOTSOCK);
|
||||||
|
return getsockopt_impl(level, option, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> Inode::setsockopt(int level, int option, const void* value, socklen_t value_len)
|
||||||
|
{
|
||||||
|
LockGuard _(m_mutex);
|
||||||
|
if (!mode().ifsock())
|
||||||
|
return BAN::Error::from_errno(ENOTSOCK);
|
||||||
|
return setsockopt_impl(level, option, value, value_len);
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<size_t> Inode::read(off_t offset, BAN::ByteSpan buffer)
|
BAN::ErrorOr<size_t> Inode::read(off_t offset, BAN::ByteSpan buffer)
|
||||||
{
|
{
|
||||||
LockGuard _(m_mutex);
|
LockGuard _(m_mutex);
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,34 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> 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)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
|
||||||
|
memcpy(value, &result, len);
|
||||||
|
*value_len = sizeof(int);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> TCPSocket::ioctl_impl(int request, void* argument)
|
BAN::ErrorOr<long> TCPSocket::ioctl_impl(int request, void* argument)
|
||||||
{
|
{
|
||||||
switch (request)
|
switch (request)
|
||||||
|
|
|
||||||
|
|
@ -213,6 +213,34 @@ namespace Kernel
|
||||||
return TRY(m_network_layer.sendto(*this, buffer.span(), address, address_len));
|
return TRY(m_network_layer.sendto(*this, buffer.span(), address, address_len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> 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)
|
||||||
|
{
|
||||||
|
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:
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
|
||||||
|
memcpy(value, &result, len);
|
||||||
|
*value_len = sizeof(int);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument)
|
BAN::ErrorOr<long> UDPSocket::ioctl_impl(int request, void* argument)
|
||||||
{
|
{
|
||||||
switch (request)
|
switch (request)
|
||||||
|
|
|
||||||
|
|
@ -678,4 +678,33 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> UnixDomainSocket::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)
|
||||||
|
{
|
||||||
|
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(SOL_SOCKET, {})", option);
|
||||||
|
return BAN::Error::from_errno(ENOTSUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
const size_t len = BAN::Math::min<size_t>(sizeof(result), *value_len);
|
||||||
|
memcpy(value, &result, len);
|
||||||
|
*value_len = sizeof(int);
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1674,20 +1674,13 @@ namespace Kernel
|
||||||
if (!inode->mode().ifsock())
|
if (!inode->mode().ifsock())
|
||||||
return BAN::Error::from_errno(ENOTSOCK);
|
return BAN::Error::from_errno(ENOTSOCK);
|
||||||
|
|
||||||
switch (option_name)
|
auto* buffer = TRY(validate_and_pin_pointer_access(user_option_value, option_len, true));
|
||||||
{
|
BAN::ScopeGuard _([buffer] { buffer->unpin(); });
|
||||||
case SO_ERROR:
|
|
||||||
{
|
|
||||||
option_len = BAN::Math::min<socklen_t>(option_len, sizeof(int));
|
|
||||||
const int zero { 0 };
|
|
||||||
TRY(write_to_user(user_option_value, &zero, option_len));
|
|
||||||
TRY(write_to_user(user_option_len, &option_len, sizeof(socklen_t)));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dwarnln("getsockopt(SOL_SOCKET, {})", option_name);
|
TRY(inode->getsockopt(level, option_name, user_option_value, &option_len));
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
TRY(write_to_user(user_option_len, &option_len, sizeof(socklen_t)));
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_setsockopt(int socket, int level, int option_name, const void* user_option_value, socklen_t option_len)
|
BAN::ErrorOr<long> Process::sys_setsockopt(int socket, int level, int option_name, const void* user_option_value, socklen_t option_len)
|
||||||
|
|
@ -1705,10 +1698,12 @@ namespace Kernel
|
||||||
if (!inode->mode().ifsock())
|
if (!inode->mode().ifsock())
|
||||||
return BAN::Error::from_errno(ENOTSOCK);
|
return BAN::Error::from_errno(ENOTSOCK);
|
||||||
|
|
||||||
(void)user_option_value;
|
auto* buffer = TRY(validate_and_pin_pointer_access(user_option_value, option_len, false));
|
||||||
|
BAN::ScopeGuard _([buffer] { buffer->unpin(); });
|
||||||
|
|
||||||
dwarnln("setsockopt(SOL_SOCKET, {})", option_name);
|
TRY(inode->setsockopt(level, option_name, user_option_value, option_len));
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<long> Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len, int flags)
|
BAN::ErrorOr<long> Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len, int flags)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue