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"
62bool finishInterruptibleSocketCall(
Thread* thread, ssize_t result);
63bool finishInterruptibleSocketCall(
Thread* thread,
bool result) =
delete;
65#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
66using UnixEndpointMutationLockHook = void (*)();
67using UnixEndpointReadinessLeaseHook = void (*)();
68void setUnixEndpointMutationLockHookForTest(UnixEndpointMutationLockHook hook);
69void setUnixEndpointReadinessLeaseHookForTest(UnixEndpointReadinessLeaseHook hook);
72ssize_t posix_send_descriptor(
const DescriptorLease& descriptor,
const void* buffer,
73 size_t bufferLength,
int flags,
bool kernelBuffer =
false);
74ssize_t posix_recv_descriptor(
const DescriptorLease& descriptor,
void* buffer,
size_t bufferLength,
76ssize_t posix_sendmsg_descriptor(
79 bool kernelBuffer =
false);
91 virtual int connect(
const struct sockaddr_storage* address, socklen_t addrlen) = 0;
93 virtual ssize_t sendto_msg(
const struct msghdr* msghdr,
97 virtual ssize_t sendto(
const void* buffer,
size_t bufferlen,
int flags,
98 const struct sockaddr_storage* address, socklen_t addrlen);
99 virtual ssize_t recvfrom(
void* buffer,
size_t bufferlen,
int flags,
100 struct sockaddr_storage* address, socklen_t* addrlen);
102 virtual int listen(
int backlog) = 0;
103 virtual int bind(
const struct sockaddr_storage* address, socklen_t addrlen) = 0;
104 virtual int accept(
struct sockaddr_storage* address, socklen_t* addrlen,
int flags,
107 virtual int shutdown(
int how);
109 virtual int getpeername(
struct sockaddr_storage* address, socklen_t* address_len) = 0;
110 virtual int getsockname(
struct sockaddr_storage* address, socklen_t* address_len) = 0;
112 virtual int setsockopt(
int level,
int optname,
const void* optvalue, socklen_t optlen) = 0;
113 virtual int getsockopt(
int level,
int optname,
void* optvalue, socklen_t* optlen) = 0;
115 virtual bool canPoll()
const;
116 virtual bool poll(
bool& read,
bool& write,
bool& error,
Semaphore*
waiter);
120 virtual ReadyMask
queryReady(
bool reading,
bool writing);
125 void removeDescriptorOwner();
138 virtual bool monitor(
Thread* pThread,
Event* pEvent);
139 virtual bool unmonitor(
Event* pEvent);
143 int getDomain()
const {
147 int getType()
const {
151 int getProtocol()
const {
155 bool isBlocking()
const;
157 virtual void setBlocking(
bool blocking);
159 int takeReceiveError();
160 void deferReceiveError(
int error);
163 ReadyMask pendingReceiveReadiness()
const;
169 bool hasLastDescriptorClosed()
const;
179 mutable Mutex m_ReceiveErrorLock;
180 int m_ReceiveError = 0;
181 uint64_t m_ReceiveErrorGeneration = 0;
187 mutable Mutex m_LifecycleLock;
188 size_t m_DescriptorOwners;
189 bool m_DescriptorAdmissionOpen;
190 bool m_LastDescriptorClosed;
201 virtual int connect(
const struct sockaddr_storage* address, socklen_t addrlen);
203 virtual ssize_t sendto_msg(
const struct msghdr* msghdr,
207 virtual int listen(
int backlog);
208 virtual int bind(
const struct sockaddr_storage* address, socklen_t addrlen);
209 virtual int accept(
struct sockaddr_storage* address, socklen_t* addrlen,
int flags,
212 virtual int shutdown(
int how);
214 virtual int getpeername(
struct sockaddr_storage* address, socklen_t* address_len);
215 virtual int getsockname(
struct sockaddr_storage* address, socklen_t* address_len);
217 virtual int setsockopt(
int level,
int optname,
const void* optvalue, socklen_t optlen);
218 virtual int getsockopt(
int level,
int optname,
void* optvalue, socklen_t* optlen);
220 virtual bool canPoll()
const;
223 virtual ReadyMask
queryReady(
bool reading,
bool writing);
227 virtual void setBlocking(
bool blocking);
231 static Mutex m_SyscallObjectsLock;
233 static void netconnCallback(
struct netconn* conn,
enum netconn_evt evt, uint16_t len);
234 static void lwipToSyscallError(
err_t err);
235 void registerSocket();
236 ReadyMask readinessLevelLocked()
const;
237 void recordReadinessRisesLocked(ReadyMask previous);
239 struct netconn* m_Socket;
253 bool receivingQueuedData;
272 virtual int connect(
const struct sockaddr_storage* address, socklen_t addrlen);
274 virtual ssize_t sendto_msg(
const struct msghdr* msghdr,
278 virtual int listen(
int backlog);
279 virtual int bind(
const struct sockaddr_storage* address, socklen_t addrlen);
280 virtual int accept(
struct sockaddr_storage* address, socklen_t* addrlen,
int flags,
283 virtual int shutdown(
int how);
285 virtual int getpeername(
struct sockaddr_storage* address, socklen_t* address_len);
286 virtual int getsockname(
struct sockaddr_storage* address, socklen_t* address_len);
288 virtual int setsockopt(
int level,
int optname,
const void* optvalue, socklen_t optlen);
289 virtual int getsockopt(
int level,
int optname,
void* optvalue, socklen_t* optlen);
291 virtual bool canPoll()
const;
292 virtual bool poll(
bool& read,
bool& write,
bool& error,
Semaphore*
waiter);
294 virtual ReadyMask
queryReady(
bool reading,
bool writing);
298 virtual bool monitor(
Thread* pThread,
Event* pEvent);
299 virtual bool unmonitor(
Event* pEvent);
307 friend bool runHostedUnixEndpointLifetimeRegression(
Process* process);
315 static Mutex m_SyscallObjectsLock;
346 explicit operator bool()
const {
361 void notifyPeer(
UnixSocket* socket, ReadyMask mask);
362 static void notifySocket(
UnixSocket* socket, ReadyMask mask);
363 static bool publishAbstractSocket(
const String& address,
366 static void removeAbstractSocket(
const String& address,
UnixSocket* socket);
369 void replaceLocalEndpoint(
UnixSocket* socket,
bool tracked,
const String* localPath =
nullptr);
371 const String* localPath,
bool ownsAbstractName);
372 void tryCompleteEndpointClose();
374 UnixSocket::SocketType getSocketType()
const;
391 bool m_OwnsAbstractName;
395struct netconnMetadata* getNetconnMetadata(
struct netconn* conn);
397int posix_socket(
int domain,
int type,
int protocol);
398int posix_socketpair(
int domain,
int type,
int protocol,
int sv[2]);
399int posix_connect(
int sock,
const struct sockaddr_storage* address, socklen_t addrlen);
401ssize_t posix_send(
int sock,
const void* buff,
size_t bufflen,
int flags);
402ssize_t posix_sendto(
int sock,
const void* buff,
size_t bufflen,
int flags,
403 struct sockaddr_storage* address, socklen_t addrlen);
404ssize_t posix_recv(
int sock,
void* buff,
size_t bufflen,
int flags);
405ssize_t posix_recvfrom(
int sock,
void* buff,
size_t bufflen,
int flags,
406 struct sockaddr_storage* address, socklen_t* addrlen);
408int posix_listen(
int sock,
int backlog);
409int posix_bind(
int sock,
const struct sockaddr_storage* address, socklen_t addrlen);
410int posix_accept(
int sock,
struct sockaddr_storage* address, socklen_t* addrlen);
411int posix_accept4(
int sock,
struct sockaddr_storage* address, socklen_t* addrlen,
int flags);
413int posix_shutdown(
int socket,
int how);
415int posix_getpeername(
int socket,
struct sockaddr_storage* address, socklen_t* address_len);
416int posix_getsockname(
int socket,
struct sockaddr_storage* address, socklen_t* address_len);
418int posix_setsockopt(
int sock,
int level,
int optname,
const void* optvalue, socklen_t optlen);
419int posix_getsockopt(
int sock,
int level,
int optname,
void* optvalue, socklen_t* optlen);
421int posix_sethostname(
const char* name,
size_t len);
423ssize_t posix_sendmsg(
int sockfd,
const struct msghdr* msg,
int flags);
424ssize_t posix_recvmsg(
int sockfd,
struct msghdr* msg,
int flags);
426#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
427bool 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 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