1/*
2 * Copyright 2023, Trung Nguyen, trungnt282910@gmail.com.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef UNIX_ENDPOINT_H
6#define UNIX_ENDPOINT_H
7
8
9#include <net_protocol.h>
10#include <net_socket.h>
11#include <ProtocolUtilities.h>
12
13#include <lock.h>
14#include <vfs.h>
15
16#include "UnixAddress.h"
17
18
19class UnixEndpoint : public net_protocol, public ProtocolSocket {
20public:
21	virtual						~UnixEndpoint();
22
23	bool Lock()
24	{
25		return mutex_lock(&fLock) == B_OK;
26	}
27
28	void Unlock()
29	{
30		mutex_unlock(&fLock);
31	}
32
33	const UnixAddress& Address() const
34	{
35		return fAddress;
36	}
37
38	UnixEndpoint*& HashTableLink()
39	{
40		return fAddressHashLink;
41	}
42
43	virtual	status_t			Init() = 0;
44	virtual	void				Uninit() = 0;
45
46	virtual	status_t			Open() = 0;
47	virtual	status_t			Close() = 0;
48	virtual	status_t			Free() = 0;
49
50	virtual	status_t			Bind(const struct sockaddr* _address) = 0;
51	virtual	status_t			Unbind() = 0;
52	virtual	status_t			Listen(int backlog) = 0;
53	virtual	status_t			Connect(const struct sockaddr* address) = 0;
54	virtual	status_t			Accept(net_socket** _acceptedSocket) = 0;
55
56	virtual	ssize_t				Send(const iovec* vecs, size_t vecCount,
57									ancillary_data_container* ancillaryData,
58									const struct sockaddr* address,
59									socklen_t addressLength, int flags) = 0;
60	virtual	ssize_t				Receive(const iovec* vecs, size_t vecCount,
61									ancillary_data_container** _ancillaryData,
62									struct sockaddr* _address, socklen_t* _addressLength,
63									int flags) = 0;
64
65	virtual	ssize_t				Sendable() = 0;
66	virtual	ssize_t				Receivable() = 0;
67
68	virtual	status_t			SetReceiveBufferSize(size_t size) = 0;
69	virtual	status_t			GetPeerCredentials(ucred* credentials) = 0;
70
71	virtual	status_t			Shutdown(int direction) = 0;
72
73	static	status_t			Create(net_socket* socket, UnixEndpoint** _endpoint);
74
75protected:
76								UnixEndpoint(net_socket* socket);
77
78	// These functions perform no locking or checking on the endpoint.
79			status_t			_Bind(const struct sockaddr_un* address);
80			status_t			_Unbind();
81
82private:
83			status_t			_Bind(struct vnode* vnode);
84			status_t			_Bind(int32 internalID);
85
86protected:
87			UnixAddress			fAddress;
88
89private:
90			mutex				fLock;
91			UnixEndpoint*		fAddressHashLink;
92};
93
94
95static inline bigtime_t
96absolute_timeout(bigtime_t timeout)
97{
98	if (timeout == 0 || timeout == B_INFINITE_TIMEOUT)
99		return timeout;
100
101// TODO: Make overflow safe!
102	return timeout + system_time();
103}
104
105
106#endif	// UNIX_ENDPOINT_H
107