23#include "pedigree/kernel/Atomic.h"
24#include "pedigree/kernel/LockGuard.h"
25#include "pedigree/kernel/process/Mutex.h"
26#include "pedigree/kernel/process/OperationBarrier.h"
27#include "pedigree/kernel/process/Readiness.h"
28#include "pedigree/kernel/utilities/List.h"
29#include "pedigree/kernel/utilities/String.h"
30#include "pedigree/kernel/utilities/Tree.h"
33#include "modules/subsys/posix/UnixFilesystem.h"
34#include "network-namespace.h"
64bool finishInterruptibleSocketCall(
Thread* thread, ssize_t result);
65bool finishInterruptibleSocketCall(
Thread* thread,
bool result) =
delete;
67#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
68using UnixEndpointMutationLockHook = void (*)();
69using UnixEndpointReadinessLeaseHook = void (*)();
70void setUnixEndpointMutationLockHookForTest(UnixEndpointMutationLockHook hook);
71void setUnixEndpointReadinessLeaseHookForTest(UnixEndpointReadinessLeaseHook hook);
74ssize_t posix_send_descriptor(
const DescriptorLease& descriptor,
const void* buffer,
75 size_t bufferLength,
int flags,
bool kernelBuffer =
false);
76ssize_t posix_recv_descriptor(
const DescriptorLease& descriptor,
void* buffer,
size_t bufferLength,
78ssize_t posix_sendmsg_descriptor(
81 bool kernelBuffer =
false);
95 virtual bool create();
96 virtual int connect(
const struct sockaddr_storage* address, socklen_t addrlen) = 0;
98 virtual ssize_t sendto_msg(
const struct msghdr* msghdr,
102 virtual ssize_t sendto(
const void* buffer,
size_t bufferlen,
int flags,
103 const struct sockaddr_storage* address, socklen_t addrlen);
104 virtual ssize_t recvfrom(
void* buffer,
size_t bufferlen,
int flags,
105 struct sockaddr_storage* address, socklen_t* addrlen);
107 virtual int listen(
int backlog) = 0;
108 virtual int bind(
const struct sockaddr_storage* address, socklen_t addrlen) = 0;
109 virtual int accept(
struct sockaddr_storage* address, socklen_t* addrlen,
int flags,
112 virtual int shutdown(
int how);
114 virtual int getpeername(
struct sockaddr_storage* address, socklen_t* address_len) = 0;
115 virtual int getsockname(
struct sockaddr_storage* address, socklen_t* address_len) = 0;
117 virtual int setsockopt(
int level,
int optname,
const void* optvalue, socklen_t optlen) = 0;
118 virtual int getsockopt(
int level,
int optname,
void* optvalue, socklen_t* optlen) = 0;
120 virtual bool canPoll()
const;
121 virtual bool poll(
bool& read,
bool& write,
bool& error,
Semaphore*
waiter);
125 virtual ReadyMask
queryReady(
bool reading,
bool writing);
130 void removeDescriptorOwner();
143 virtual bool monitor(
Thread* pThread,
Event* pEvent);
144 virtual bool unmonitor(
Event* pEvent);
148 int getDomain()
const {
152 int getType()
const {
156 int getProtocol()
const {
161 return m_NetworkNamespace;
164 bool isBlocking()
const;
166 virtual void setBlocking(
bool blocking);
168 int takeReceiveError();
169 void deferReceiveError(
int error);
172 virtual bool usesLocalEndpointLifetime()
const {
175 ReadyMask pendingReceiveReadiness()
const;
181 bool hasLastDescriptorClosed()
const;
192 mutable Mutex m_ReceiveErrorLock;
193 int m_ReceiveError = 0;
194 uint64_t m_ReceiveErrorGeneration = 0;
200 mutable Mutex m_LifecycleLock;
201 size_t m_DescriptorOwners;
202 bool m_DescriptorAdmissionOpen;
203 bool m_LastDescriptorClosed;
214 virtual int connect(
const struct sockaddr_storage* address, socklen_t addrlen);
216 virtual ssize_t sendto_msg(
const struct msghdr* msghdr,
220 virtual int listen(
int backlog);
221 virtual int bind(
const struct sockaddr_storage* address, socklen_t addrlen);
222 virtual int accept(
struct sockaddr_storage* address, socklen_t* addrlen,
int flags,
225 virtual int shutdown(
int how);
227 virtual int getpeername(
struct sockaddr_storage* address, socklen_t* address_len);
228 virtual int getsockname(
struct sockaddr_storage* address, socklen_t* address_len);
230 virtual int setsockopt(
int level,
int optname,
const void* optvalue, socklen_t optlen);
231 virtual int getsockopt(
int level,
int optname,
void* optvalue, socklen_t* optlen);
233 virtual bool canPoll()
const;
236 virtual ReadyMask
queryReady(
bool reading,
bool writing);
240 virtual void setBlocking(
bool blocking);
244 static Mutex m_SyscallObjectsLock;
246 static void netconnCallback(
struct netconn* conn,
enum netconn_evt evt, uint16_t len);
247 static void lwipToSyscallError(
err_t err);
248 void registerSocket();
249 ReadyMask readinessLevelLocked()
const;
250 void recordReadinessRisesLocked(ReadyMask previous);
252 struct netconn* m_Socket;
266 bool receivingQueuedData;
285 virtual int connect(
const struct sockaddr_storage* address, socklen_t addrlen);
287 virtual ssize_t sendto_msg(
const struct msghdr* msghdr,
291 virtual int listen(
int backlog);
292 virtual int bind(
const struct sockaddr_storage* address, socklen_t addrlen);
293 virtual int accept(
struct sockaddr_storage* address, socklen_t* addrlen,
int flags,
296 virtual int shutdown(
int how);
298 virtual int getpeername(
struct sockaddr_storage* address, socklen_t* address_len);
299 virtual int getsockname(
struct sockaddr_storage* address, socklen_t* address_len);
301 virtual int setsockopt(
int level,
int optname,
const void* optvalue, socklen_t optlen);
302 virtual int getsockopt(
int level,
int optname,
void* optvalue, socklen_t* optlen);
304 virtual bool canPoll()
const;
305 virtual bool poll(
bool& read,
bool& write,
bool& error,
Semaphore*
waiter);
307 virtual ReadyMask
queryReady(
bool reading,
bool writing);
311 virtual bool monitor(
Thread* pThread,
Event* pEvent);
312 virtual bool unmonitor(
Event* pEvent);
319 bool usesLocalEndpointLifetime()
const override {
326 friend bool runHostedUnixEndpointLifetimeRegression(
Process* process);
334 static Mutex m_SyscallObjectsLock;
365 explicit operator bool()
const {
380 void notifyPeer(
UnixSocket* socket, ReadyMask mask);
381 static void notifySocket(
UnixSocket* socket, ReadyMask mask);
383 bool publishAbstractSocket(
const String& address,
389 void replaceLocalEndpoint(
UnixSocket* socket,
bool tracked,
const String* localPath =
nullptr);
391 const String* localPath,
bool ownsAbstractName);
392 void tryCompleteEndpointClose();
394 UnixSocket::SocketType getSocketType()
const;
411 bool m_OwnsAbstractName;
415struct netconnMetadata* getNetconnMetadata(
struct netconn* conn);
417int posix_socket(
int domain,
int type,
int protocol);
418int posix_socketpair(
int domain,
int type,
int protocol,
int sv[2]);
419int posix_connect(
int sock,
const struct sockaddr_storage* address, socklen_t addrlen);
421ssize_t posix_send(
int sock,
const void* buff,
size_t bufflen,
int flags);
422ssize_t posix_sendto(
int sock,
const void* buff,
size_t bufflen,
int flags,
423 struct sockaddr_storage* address, socklen_t addrlen);
424ssize_t posix_recv(
int sock,
void* buff,
size_t bufflen,
int flags);
425ssize_t posix_recvfrom(
int sock,
void* buff,
size_t bufflen,
int flags,
426 struct sockaddr_storage* address, socklen_t* addrlen);
428int posix_listen(
int sock,
int backlog);
429int posix_bind(
int sock,
const struct sockaddr_storage* address, socklen_t addrlen);
430int posix_accept(
int sock,
struct sockaddr_storage* address, socklen_t* addrlen);
431int posix_accept4(
int sock,
struct sockaddr_storage* address, socklen_t* addrlen,
int flags);
433int posix_shutdown(
int socket,
int how);
435int posix_getpeername(
int socket,
struct sockaddr_storage* address, socklen_t* address_len);
436int posix_getsockname(
int socket,
struct sockaddr_storage* address, socklen_t* address_len);
438int posix_setsockopt(
int sock,
int level,
int optname,
const void* optvalue, socklen_t optlen);
439int posix_getsockopt(
int sock,
int level,
int optname,
void* optvalue, socklen_t* optlen);
441int posix_sethostname(
const char* name,
size_t len);
443ssize_t posix_sendmsg(
int sockfd,
const struct msghdr* msg,
int flags);
444ssize_t posix_recvmsg(
int sockfd,
struct msghdr* msg,
int flags);
446#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
447bool runHostedUnixEndpointLifetimeRegression(
Process* process);
static void netconnCallback(struct netconn *conn, enum netconn_evt evt, uint16_t len)
ReadinessGenerations readinessGenerations() override
virtual int connect(const struct sockaddr_storage *address, socklen_t addrlen)
virtual void lastDescriptorClosed()
virtual int getpeername(struct sockaddr_storage *address, socklen_t *address_len)
virtual int accept(struct sockaddr_storage *address, socklen_t *addrlen, int flags, DescriptorLease *accepted=nullptr)
virtual ReadyMask queryReady(bool reading, bool writing)
virtual bool poll(bool &read, bool &write, bool &error, Semaphore *waiter)
virtual bool create()
Implementation-specific final socket creation logic.
virtual int getsockname(struct sockaddr_storage *address, socklen_t *address_len)
bool beginDescriptorClose()
virtual MqueueNetlinkSocket * asMqueueNetlink()
virtual ReadyMask queryReady(bool reading, bool writing)
MUST_USE_RESULT bool addDescriptorOwner()
virtual void lastDescriptorClosed()
OperationBarrier m_ReadinessNotifications
ReadinessGenerations readinessGenerations() override
void retainDescriptorLifetime(const SharedPointer< NetworkSyscalls > &lifetime)
virtual int listen(int backlog)
virtual void lastDescriptorClosed()
ReadinessGenerations readinessGenerations() override
bool pairWith(UnixSocketSyscalls *other)
virtual int bind(const struct sockaddr_storage *address, socklen_t addrlen)
virtual bool create()
Implementation-specific final socket creation logic.
Mutex m_EndpointMutationLock
virtual ReadyMask queryReady(bool reading, bool writing)
Mutex m_EndpointStateLock