/* 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 #include #include #include 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 char* getMyAddress() = 0; // a string e.g. "192.168.0.1" virtual int getMyPort() = 0; virtual char* getMyEndpoint() = 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; //
:: // 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__