diff --git a/kernel/include/kernel/FS/Inode.h b/kernel/include/kernel/FS/Inode.h index e7be1c3328..3142175ff3 100644 --- a/kernel/include/kernel/FS/Inode.h +++ b/kernel/include/kernel/FS/Inode.h @@ -100,9 +100,12 @@ namespace Kernel BAN::ErrorOr link_target(); // Socket API + BAN::ErrorOr accept(sockaddr* address, socklen_t* address_len); BAN::ErrorOr bind(const sockaddr* address, socklen_t address_len); - BAN::ErrorOr sendto(const sys_sendto_t*); - BAN::ErrorOr recvfrom(sys_recvfrom_t*); + BAN::ErrorOr connect(const sockaddr* address, socklen_t address_len); + BAN::ErrorOr listen(int backlog); + BAN::ErrorOr sendto(const sys_sendto_t*); + BAN::ErrorOr recvfrom(sys_recvfrom_t*); // General API BAN::ErrorOr read(off_t, BAN::ByteSpan buffer); @@ -128,9 +131,12 @@ namespace Kernel virtual BAN::ErrorOr link_target_impl() { return BAN::Error::from_errno(ENOTSUP); } // Socket API + virtual BAN::ErrorOr accept_impl(sockaddr*, socklen_t*) { return BAN::Error::from_errno(ENOTSUP); } + virtual BAN::ErrorOr connect_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } + virtual BAN::ErrorOr listen_impl(int) { return BAN::Error::from_errno(ENOTSUP); } virtual BAN::ErrorOr bind_impl(const sockaddr*, socklen_t) { return BAN::Error::from_errno(ENOTSUP); } - virtual BAN::ErrorOr sendto_impl(const sys_sendto_t*) { return BAN::Error::from_errno(ENOTSUP); } - virtual BAN::ErrorOr recvfrom_impl(sys_recvfrom_t*) { return BAN::Error::from_errno(ENOTSUP); } + virtual BAN::ErrorOr sendto_impl(const sys_sendto_t*) { return BAN::Error::from_errno(ENOTSUP); } + virtual BAN::ErrorOr recvfrom_impl(sys_recvfrom_t*) { return BAN::Error::from_errno(ENOTSUP); } // General API virtual BAN::ErrorOr read_impl(off_t, BAN::ByteSpan) { return BAN::Error::from_errno(ENOTSUP); } diff --git a/kernel/include/kernel/Networking/NetworkSocket.h b/kernel/include/kernel/Networking/NetworkSocket.h index adf8c5ad5f..71ee94ac70 100644 --- a/kernel/include/kernel/Networking/NetworkSocket.h +++ b/kernel/include/kernel/Networking/NetworkSocket.h @@ -58,8 +58,8 @@ namespace Kernel virtual void on_close_impl() override; virtual BAN::ErrorOr bind_impl(const sockaddr* address, socklen_t address_len) override; - virtual BAN::ErrorOr sendto_impl(const sys_sendto_t*) override; - virtual BAN::ErrorOr recvfrom_impl(sys_recvfrom_t*) override; + virtual BAN::ErrorOr sendto_impl(const sys_sendto_t*) override; + virtual BAN::ErrorOr recvfrom_impl(sys_recvfrom_t*) override; virtual BAN::ErrorOr ioctl_impl(int request, void* arg) override; diff --git a/kernel/include/kernel/Process.h b/kernel/include/kernel/Process.h index 19d371da78..18733d2bdf 100644 --- a/kernel/include/kernel/Process.h +++ b/kernel/include/kernel/Process.h @@ -115,7 +115,10 @@ namespace Kernel BAN::ErrorOr sys_chown(const char*, uid_t, gid_t); BAN::ErrorOr sys_socket(int domain, int type, int protocol); + BAN::ErrorOr sys_accept(int socket, sockaddr* address, socklen_t* address_len); BAN::ErrorOr sys_bind(int socket, const sockaddr* address, socklen_t address_len); + BAN::ErrorOr sys_connect(int socket, const sockaddr* address, socklen_t address_len); + BAN::ErrorOr sys_listen(int socket, int backlog); BAN::ErrorOr sys_sendto(const sys_sendto_t*); BAN::ErrorOr sys_recvfrom(sys_recvfrom_t*); diff --git a/kernel/kernel/FS/Inode.cpp b/kernel/kernel/FS/Inode.cpp index c3cbaea640..0f775c3c45 100644 --- a/kernel/kernel/FS/Inode.cpp +++ b/kernel/kernel/FS/Inode.cpp @@ -116,6 +116,14 @@ namespace Kernel return link_target_impl(); } + BAN::ErrorOr Inode::accept(sockaddr* address, socklen_t* address_len) + { + LockGuard _(m_lock); + if (!mode().ifsock()) + return BAN::Error::from_errno(ENOTSOCK); + return accept_impl(address, address_len); + } + BAN::ErrorOr Inode::bind(const sockaddr* address, socklen_t address_len) { LockGuard _(m_lock); @@ -124,7 +132,23 @@ namespace Kernel return bind_impl(address, address_len); } - BAN::ErrorOr Inode::sendto(const sys_sendto_t* arguments) + BAN::ErrorOr Inode::connect(const sockaddr* address, socklen_t address_len) + { + LockGuard _(m_lock); + if (!mode().ifsock()) + return BAN::Error::from_errno(ENOTSOCK); + return connect_impl(address, address_len); + } + + BAN::ErrorOr Inode::listen(int backlog) + { + LockGuard _(m_lock); + if (!mode().ifsock()) + return BAN::Error::from_errno(ENOTSOCK); + return listen_impl(backlog); + } + + BAN::ErrorOr Inode::sendto(const sys_sendto_t* arguments) { LockGuard _(m_lock); if (!mode().ifsock()) @@ -132,7 +156,7 @@ namespace Kernel return sendto_impl(arguments); }; - BAN::ErrorOr Inode::recvfrom(sys_recvfrom_t* arguments) + BAN::ErrorOr Inode::recvfrom(sys_recvfrom_t* arguments) { LockGuard _(m_lock); if (!mode().ifsock()) diff --git a/kernel/kernel/Networking/NetworkSocket.cpp b/kernel/kernel/Networking/NetworkSocket.cpp index 2c34f56ed2..53eb745e30 100644 --- a/kernel/kernel/Networking/NetworkSocket.cpp +++ b/kernel/kernel/Networking/NetworkSocket.cpp @@ -38,7 +38,7 @@ namespace Kernel return m_network_layer.bind_socket(dst_port, this); } - BAN::ErrorOr NetworkSocket::sendto_impl(const sys_sendto_t* arguments) + BAN::ErrorOr NetworkSocket::sendto_impl(const sys_sendto_t* arguments) { if (arguments->flags) { @@ -52,7 +52,7 @@ namespace Kernel return TRY(m_network_layer.sendto(*this, arguments)); } - BAN::ErrorOr NetworkSocket::recvfrom_impl(sys_recvfrom_t* arguments) + BAN::ErrorOr NetworkSocket::recvfrom_impl(sys_recvfrom_t* arguments) { sockaddr_in* sender_addr = nullptr; if (arguments->address) diff --git a/kernel/kernel/Process.cpp b/kernel/kernel/Process.cpp index 6ba65d9edb..2cbb1d8729 100644 --- a/kernel/kernel/Process.cpp +++ b/kernel/kernel/Process.cpp @@ -901,6 +901,27 @@ namespace Kernel return TRY(m_open_file_descriptors.socket(domain, type, protocol)); } + BAN::ErrorOr Process::sys_accept(int socket, sockaddr* address, socklen_t* address_len) + { + if (address && !address_len) + return BAN::Error::from_errno(EINVAL); + if (!address && address_len) + return BAN::Error::from_errno(EINVAL); + + LockGuard _(m_lock); + if (address) + { + TRY(validate_pointer_access(address_len, sizeof(*address_len))); + TRY(validate_pointer_access(address, *address_len)); + } + + auto inode = TRY(m_open_file_descriptors.inode_of(socket)); + if (!inode->mode().ifsock()) + return BAN::Error::from_errno(ENOTSOCK); + + TRY(inode->accept(address, address_len)); + return 0; + } BAN::ErrorOr Process::sys_bind(int socket, const sockaddr* address, socklen_t address_len) { @@ -915,6 +936,31 @@ namespace Kernel return 0; } + BAN::ErrorOr Process::sys_connect(int socket, const sockaddr* address, socklen_t address_len) + { + LockGuard _(m_lock); + TRY(validate_pointer_access(address, address_len)); + + auto inode = TRY(m_open_file_descriptors.inode_of(socket)); + if (!inode->mode().ifsock()) + return BAN::Error::from_errno(ENOTSOCK); + + TRY(inode->connect(address, address_len)); + return 0; + } + + BAN::ErrorOr Process::sys_listen(int socket, int backlog) + { + LockGuard _(m_lock); + + auto inode = TRY(m_open_file_descriptors.inode_of(socket)); + if (!inode->mode().ifsock()) + return BAN::Error::from_errno(ENOTSOCK); + + TRY(inode->listen(backlog)); + return 0; + } + BAN::ErrorOr Process::sys_sendto(const sys_sendto_t* arguments) { LockGuard _(m_lock); diff --git a/kernel/kernel/Syscall.cpp b/kernel/kernel/Syscall.cpp index fba4152391..383bc9b729 100644 --- a/kernel/kernel/Syscall.cpp +++ b/kernel/kernel/Syscall.cpp @@ -228,6 +228,15 @@ namespace Kernel case SYS_IOCTL: ret = Process::current().sys_ioctl((int)arg1, (int)arg2, (void*)arg3); break; + case SYS_ACCEPT: + ret = Process::current().sys_accept((int)arg1, (sockaddr*)arg2, (socklen_t*)arg3); + break; + case SYS_CONNECT: + ret = Process::current().sys_connect((int)arg1, (const sockaddr*)arg2, (socklen_t)arg3); + break; + case SYS_LISTEN: + ret = Process::current().sys_listen((int)arg1, (int)arg2); + break; default: dwarnln("Unknown syscall {}", syscall); break; diff --git a/libc/include/sys/syscall.h b/libc/include/sys/syscall.h index 10a7e26a87..780103d88f 100644 --- a/libc/include/sys/syscall.h +++ b/libc/include/sys/syscall.h @@ -68,6 +68,9 @@ __BEGIN_DECLS #define SYS_SENDTO 67 #define SYS_RECVFROM 68 #define SYS_IOCTL 69 +#define SYS_ACCEPT 70 +#define SYS_CONNECT 71 +#define SYS_LISTEN 72 __END_DECLS diff --git a/libc/sys/socket.cpp b/libc/sys/socket.cpp index 241a1c4bba..82b778a376 100644 --- a/libc/sys/socket.cpp +++ b/libc/sys/socket.cpp @@ -2,11 +2,31 @@ #include #include +int accept(int socket, struct sockaddr* __restrict address, socklen_t* __restrict address_len) +{ + return syscall(SYS_ACCEPT, socket, address, address_len); +} + int bind(int socket, const struct sockaddr* address, socklen_t address_len) { return syscall(SYS_BIND, socket, address, address_len); } +int connect(int socket, const struct sockaddr* address, socklen_t address_len) +{ + return syscall(SYS_CONNECT, socket, address, address_len); +} + +int listen(int socket, int backlog) +{ + return syscall(SYS_LISTEN, socket, backlog); +} + +ssize_t revc(int socket, void* __restrict buffer, size_t length, int flags) +{ + return recvfrom(socket, buffer, length, flags, nullptr, nullptr); +} + ssize_t recvfrom(int socket, void* __restrict buffer, size_t length, int flags, struct sockaddr* __restrict address, socklen_t* __restrict address_len) { sys_recvfrom_t arguments { @@ -20,6 +40,10 @@ ssize_t recvfrom(int socket, void* __restrict buffer, size_t length, int flags, return syscall(SYS_RECVFROM, &arguments); } +ssize_t send(int socket, const void* message, size_t length, int flags) +{ + return sendto(socket, message, length, flags, nullptr, 0); +} ssize_t sendto(int socket, const void* message, size_t length, int flags, const struct sockaddr* dest_addr, socklen_t dest_len) {