blob: bfda8a57ad6b0909cea1362e20fce18475dc5b69 [file] [log] [blame]
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +00001/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
2 *
3 * This is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This software is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
16 * USA.
17 */
18
19// -=- Socket.h - abstract base-class for any kind of network stream/socket
20
21#ifndef __NETWORK_SOCKET_H__
22#define __NETWORK_SOCKET_H__
23
Pierre Ossman574dc642016-10-05 13:39:11 +020024#include <list>
25
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000026#include <limits.h>
27#include <rdr/FdInStream.h>
28#include <rdr/FdOutStream.h>
29#include <rdr/Exception.h>
30
31namespace network {
32
Pierre Ossman559e8b82018-05-04 12:44:31 +020033 void initSockets();
34
35 bool isSocketListening(int sock);
36
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000037 class Socket {
38 public:
Pierre Ossman559e8b82018-05-04 12:44:31 +020039 Socket(int fd);
40 virtual ~Socket();
41
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000042 rdr::FdInStream &inStream() {return *instream;}
43 rdr::FdOutStream &outStream() {return *outstream;}
44 int getFd() {return outstream->getFd();}
45
Pierre Ossman559e8b82018-05-04 12:44:31 +020046 void shutdown();
47 bool isShutdown() const;
48
Peter Åstrand (astrand)01dc1a62017-10-10 12:56:04 +020049 virtual bool cork(bool enable) = 0;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000050
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000051 // information about the remote end of the socket
52 virtual char* getPeerAddress() = 0; // a string e.g. "192.168.0.1"
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000053 virtual char* getPeerEndpoint() = 0; // <address>::<port>
54
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000055 // Was there a "?" in the ConnectionFilter used to accept this Socket?
Pierre Ossman559e8b82018-05-04 12:44:31 +020056 void setRequiresQuery();
57 bool requiresQuery() const;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000058
59 protected:
Pierre Ossman559e8b82018-05-04 12:44:31 +020060 Socket();
61
62 void setFd(int fd);
63
64 private:
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000065 rdr::FdInStream* instream;
66 rdr::FdOutStream* outstream;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000067 bool isShutdown_;
68 bool queryConnection;
69 };
70
71 class ConnectionFilter {
72 public:
73 virtual bool verifyConnection(Socket* s) = 0;
Steve Kondika6424622017-07-08 01:49:14 -070074 virtual ~ConnectionFilter() {}
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000075 };
76
77 class SocketListener {
78 public:
Pierre Ossman559e8b82018-05-04 12:44:31 +020079 SocketListener(int fd);
80 virtual ~SocketListener();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000081
82 // shutdown() stops the socket from accepting further connections
Pierre Ossman559e8b82018-05-04 12:44:31 +020083 void shutdown();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000084
85 // accept() returns a new Socket object if there is a connection
86 // attempt in progress AND if the connection passes the filter
87 // if one is installed. Otherwise, returns 0.
Pierre Ossman559e8b82018-05-04 12:44:31 +020088 Socket* accept();
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000089
Pierre Ossmane3a2be62018-05-03 14:03:55 +020090 virtual int getMyPort() = 0;
91
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +000092 // setFilter() applies the specified filter to all new connections
93 void setFilter(ConnectionFilter* f) {filter = f;}
94 int getFd() {return fd;}
Pierre Ossman559e8b82018-05-04 12:44:31 +020095
96 protected:
97 SocketListener();
98
99 void listen(int fd);
100
101 // createSocket() should create a new socket of the correct class
102 // for the given file descriptor
103 virtual Socket* createSocket(int fd) = 0;
104
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000105 protected:
106 int fd;
107 ConnectionFilter* filter;
108 };
109
110 struct SocketException : public rdr::SystemException {
111 SocketException(const char* text, int err_) : rdr::SystemException(text, err_) {}
112 };
113
114 class SocketServer {
115 public:
116 virtual ~SocketServer() {}
117
118 // addSocket() tells the server to serve the Socket. The caller
119 // retains ownership of the Socket - the only way for the server
120 // to discard a Socket is by calling shutdown() on it.
121 // outgoing is set to true if the socket was created by connecting out
122 // to another host, or false if the socket was created by accept()ing
123 // an incoming connection.
124 virtual void addSocket(network::Socket* sock, bool outgoing=false) = 0;
125
126 // removeSocket() tells the server to stop serving the Socket. The
127 // caller retains ownership of the Socket - the server must NOT
128 // delete the Socket! This call is used mainly to cause per-Socket
129 // resources to be freed.
130 virtual void removeSocket(network::Socket* sock) = 0;
131
Pierre Ossman574dc642016-10-05 13:39:11 +0200132 // getSockets() gets a list of sockets. This can be used to generate an
133 // fd_set for calling select().
134 virtual void getSockets(std::list<network::Socket*>* sockets) = 0;
135
Pierre Ossmand408ca52016-04-29 14:26:05 +0200136 // processSocketReadEvent() tells the server there is a Socket read event.
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000137 // The implementation can indicate that the Socket is no longer active
138 // by calling shutdown() on it. The caller will then call removeSocket()
139 // soon after processSocketEvent returns, to allow any pre-Socket
140 // resources to be tidied up.
Pierre Ossmand408ca52016-04-29 14:26:05 +0200141 virtual void processSocketReadEvent(network::Socket* sock) = 0;
142
143 // processSocketReadEvent() tells the server there is a Socket write event.
144 // This is only necessary if the Socket has been put in non-blocking
145 // mode and needs this callback to flush the buffer.
146 virtual void processSocketWriteEvent(network::Socket* sock) = 0;
Constantin Kaplinskya2adc8d2006-05-25 05:01:55 +0000147
148 // checkTimeouts() allows the server to check socket timeouts, etc. The
149 // return value is the number of milliseconds to wait before
150 // checkTimeouts() should be called again. If this number is zero then
151 // there is no timeout and checkTimeouts() should be called the next time
152 // an event occurs.
153 virtual int checkTimeouts() = 0;
154
155 virtual bool getDisable() {return false;};
156 };
157
158}
159
160#endif // __NETWORK_SOCKET_H__