1/*
2 * Copyright 2012-2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 *		Paweł Dziepak, pdziepak@quarnos.org
7 */
8#ifndef CONNECTION_H
9#define CONNECTION_H
10
11
12#include <netinet/in.h>
13
14#include <lock.h>
15#include <SupportDefs.h>
16
17
18struct PeerAddress {
19			sockaddr_storage	fAddress;
20			int					fProtocol;
21
22			bool				operator==(const PeerAddress& address);
23			bool				operator<(const PeerAddress& address);
24
25			PeerAddress&		operator=(const PeerAddress& address);
26
27								PeerAddress();
28								PeerAddress(int networkFamily);
29
30	inline	int					Family() const;
31
32			const char*			ProtocolString() const;
33			void				SetProtocol(const char* protocol);
34
35			char*				UniversalAddress() const;
36
37			socklen_t			AddressSize() const;
38
39			void				SetPort(uint16 port);
40			uint16				Port() const;
41
42			const void*			InAddr() const;
43			size_t				InAddrSize() const;
44};
45
46
47inline int
48PeerAddress::Family() const
49{
50	return fAddress.ss_family;
51}
52
53
54struct addrinfo;
55
56class AddressResolver {
57public:
58								AddressResolver(const char* name);
59								~AddressResolver();
60
61			status_t			GetNextAddress(PeerAddress* address);
62
63			void				ForceProtocol(const char* protocol);
64			void				ForcePort(uint16 port);
65
66protected:
67			status_t			ResolveAddress(const char* name);
68
69private:
70			addrinfo*			fHead;
71			addrinfo*			fCurrent;
72
73			PeerAddress			fAddress;
74
75			uint16				fForcedPort;
76			int					fForcedProtocol;
77
78			status_t			fStatus;
79};
80
81class ConnectionBase {
82public:
83								ConnectionBase(const PeerAddress& address);
84	virtual						~ConnectionBase();
85
86			status_t			GetLocalAddress(PeerAddress* address);
87
88			void				Disconnect();
89
90protected:
91			sem_id				fWaitCancel;
92			int					fSocket;
93			mutex				fSocketLock;
94
95			const PeerAddress	fPeerAddress;
96};
97
98class Connection : public ConnectionBase {
99public:
100	static	status_t			Connect(Connection **connection,
101									const PeerAddress& address);
102	static	status_t			SetTo(Connection **connection, int socket,
103									const PeerAddress& address);
104
105	virtual	status_t			Send(const void* buffer, uint32 size) = 0;
106	virtual	status_t			Receive(void** buffer, uint32* size) = 0;
107
108			status_t			Reconnect();
109
110protected:
111	static	Connection*			CreateObject(const PeerAddress& address);
112
113								Connection(const PeerAddress& address);
114			status_t			Connect();
115
116};
117
118class ConnectionStream : public Connection {
119public:
120								ConnectionStream(const PeerAddress& address);
121
122	virtual	status_t			Send(const void* buffer, uint32 size);
123	virtual	status_t			Receive(void** buffer, uint32* size);
124};
125
126class ConnectionPacket : public Connection {
127public:
128								ConnectionPacket(const PeerAddress& address);
129
130	virtual	status_t			Send(const void* buffer, uint32 size);
131	virtual	status_t			Receive(void** buffer, uint32* size);
132};
133
134class ConnectionListener : public ConnectionBase {
135public:
136	static	status_t	Listen(ConnectionListener** listener, int networkFamily,
137							uint16 port = 0);
138
139			status_t	AcceptConnection(Connection** connection);
140
141protected:
142						ConnectionListener(const PeerAddress& address);
143};
144
145#endif	// CONNECTION_H
146
147