1/*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef UNIX_ENDPOINT_H
6#define UNIX_ENDPOINT_H
7
8#include <sys/stat.h>
9
10#include <Referenceable.h>
11
12#include <lock.h>
13#include <util/DoublyLinkedList.h>
14#include <util/OpenHashTable.h>
15#include <vfs.h>
16
17#include <net_protocol.h>
18#include <net_socket.h>
19#include <ProtocolUtilities.h>
20
21#include "unix.h"
22#include "UnixAddress.h"
23
24
25class UnixEndpoint;
26class UnixFifo;
27
28
29enum unix_endpoint_state {
30	UNIX_ENDPOINT_NOT_CONNECTED,
31	UNIX_ENDPOINT_LISTENING,
32	UNIX_ENDPOINT_CONNECTED,
33	UNIX_ENDPOINT_CLOSED
34};
35
36
37typedef AutoLocker<UnixEndpoint> UnixEndpointLocker;
38
39
40class UnixEndpoint : public net_protocol, public ProtocolSocket,
41	public BReferenceable {
42public:
43	UnixEndpoint(net_socket* socket);
44	virtual ~UnixEndpoint();
45
46	status_t Init();
47	void Uninit();
48
49	status_t Open();
50	status_t Close();
51	status_t Free();
52
53	bool Lock()
54	{
55		return mutex_lock(&fLock) == B_OK;
56	}
57
58	void Unlock()
59	{
60		mutex_unlock(&fLock);
61	}
62
63	status_t Bind(const struct sockaddr *_address);
64	status_t Unbind();
65	status_t Listen(int backlog);
66	status_t Connect(const struct sockaddr *address);
67	status_t Accept(net_socket **_acceptedSocket);
68
69	ssize_t Send(const iovec *vecs, size_t vecCount,
70		ancillary_data_container *ancillaryData);
71	ssize_t Receive(const iovec *vecs, size_t vecCount,
72		ancillary_data_container **_ancillaryData, struct sockaddr *_address,
73		socklen_t *_addressLength);
74
75	ssize_t Sendable();
76	ssize_t Receivable();
77
78	status_t SetReceiveBufferSize(size_t size);
79	status_t GetPeerCredentials(ucred* credentials);
80
81	status_t Shutdown(int direction);
82
83	bool IsBound() const
84	{
85		return !fIsChild && fAddress.IsValid();
86	}
87
88	const UnixAddress& Address() const
89	{
90		return fAddress;
91	}
92
93	UnixEndpoint*& HashTableLink()
94	{
95		return fAddressHashLink;
96	}
97
98private:
99	void _Spawn(UnixEndpoint* connectingEndpoint,
100		UnixEndpoint* listeningEndpoint, UnixFifo* fifo);
101	void _Disconnect();
102	status_t _LockConnectedEndpoints(UnixEndpointLocker& locker,
103		UnixEndpointLocker& peerLocker);
104
105	status_t _Bind(struct vnode* vnode);
106	status_t _Bind(int32 internalID);
107	status_t _Unbind();
108
109	void _UnsetReceiveFifo();
110	void _StopListening();
111
112private:
113	mutex							fLock;
114	UnixAddress						fAddress;
115	UnixEndpoint*					fAddressHashLink;
116	UnixEndpoint*					fPeerEndpoint;
117	UnixFifo*						fReceiveFifo;
118	unix_endpoint_state				fState;
119	sem_id							fAcceptSemaphore;
120	ucred							fCredentials;
121	bool							fIsChild;
122};
123
124#endif	// UNIX_ENDPOINT_H
125