1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
|
/* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this software; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*/
// -=- Socket.h - abstract base-class for any kind of network stream/socket
#ifndef __NETWORK_SOCKET_H__
#define __NETWORK_SOCKET_H__
#include <limits.h>
#include <rdr/FdInStream.h>
#include <rdr/FdOutStream.h>
#include <rdr/Exception.h>
namespace network {
class Socket {
public:
Socket(int fd)
: instream(new rdr::FdInStream(fd)),
outstream(new rdr::FdOutStream(fd)),
ownStreams(true), isShutdown_(false),
queryConnection(false) {}
virtual ~Socket() {
if (ownStreams) {
delete instream;
delete outstream;
}
}
rdr::FdInStream &inStream() {return *instream;}
rdr::FdOutStream &outStream() {return *outstream;}
int getFd() {return outstream->getFd();}
// if shutdown() is overridden then the override MUST call on to here
virtual void shutdown() {isShutdown_ = true;}
bool isShutdown() const {return isShutdown_;}
// information about this end of the socket
virtual int getMyPort() = 0;
// information about the remote end of the socket
virtual char* getPeerAddress() = 0; // a string e.g. "192.168.0.1"
virtual int getPeerPort() = 0;
virtual char* getPeerEndpoint() = 0; // <address>::<port>
// Is the remote end on the same machine?
virtual bool sameMachine() = 0;
// Was there a "?" in the ConnectionFilter used to accept this Socket?
void setRequiresQuery() {queryConnection = true;}
bool requiresQuery() const {return queryConnection;}
protected:
Socket() : instream(0), outstream(0), ownStreams(false),
isShutdown_(false), queryConnection(false) {}
Socket(rdr::FdInStream* i, rdr::FdOutStream* o, bool own)
: instream(i), outstream(o), ownStreams(own),
isShutdown_(false), queryConnection(false) {}
rdr::FdInStream* instream;
rdr::FdOutStream* outstream;
bool ownStreams;
bool isShutdown_;
bool queryConnection;
};
class ConnectionFilter {
public:
virtual bool verifyConnection(Socket* s) = 0;
};
class SocketListener {
public:
SocketListener() : fd(0), filter(0) {}
virtual ~SocketListener() {}
// shutdown() stops the socket from accepting further connections
virtual void shutdown() = 0;
// accept() returns a new Socket object if there is a connection
// attempt in progress AND if the connection passes the filter
// if one is installed. Otherwise, returns 0.
virtual Socket* accept() = 0;
// setFilter() applies the specified filter to all new connections
void setFilter(ConnectionFilter* f) {filter = f;}
int getFd() {return fd;}
protected:
int fd;
ConnectionFilter* filter;
};
struct SocketException : public rdr::SystemException {
SocketException(const char* text, int err_) : rdr::SystemException(text, err_) {}
};
class SocketServer {
public:
virtual ~SocketServer() {}
// addSocket() tells the server to serve the Socket. The caller
// retains ownership of the Socket - the only way for the server
// to discard a Socket is by calling shutdown() on it.
// outgoing is set to true if the socket was created by connecting out
// to another host, or false if the socket was created by accept()ing
// an incoming connection.
virtual void addSocket(network::Socket* sock, bool outgoing=false) = 0;
// removeSocket() tells the server to stop serving the Socket. The
// caller retains ownership of the Socket - the server must NOT
// delete the Socket! This call is used mainly to cause per-Socket
// resources to be freed.
virtual void removeSocket(network::Socket* sock) = 0;
// processSocketEvent() tells the server there is a Socket read event.
// The implementation can indicate that the Socket is no longer active
// by calling shutdown() on it. The caller will then call removeSocket()
// soon after processSocketEvent returns, to allow any pre-Socket
// resources to be tidied up.
virtual void processSocketEvent(network::Socket* sock) = 0;
// checkTimeouts() allows the server to check socket timeouts, etc. The
// return value is the number of milliseconds to wait before
// checkTimeouts() should be called again. If this number is zero then
// there is no timeout and checkTimeouts() should be called the next time
// an event occurs.
virtual int checkTimeouts() = 0;
virtual bool getDisable() {return false;};
};
}
#endif // __NETWORK_SOCKET_H__
|