summaryrefslogtreecommitdiff
path: root/lib/psocksxx/sockstreambuf.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/psocksxx/sockstreambuf.h')
-rw-r--r--lib/psocksxx/sockstreambuf.h345
1 files changed, 345 insertions, 0 deletions
diff --git a/lib/psocksxx/sockstreambuf.h b/lib/psocksxx/sockstreambuf.h
new file mode 100644
index 0000000..ac1ae2f
--- /dev/null
+++ b/lib/psocksxx/sockstreambuf.h
@@ -0,0 +1,345 @@
+/*
+* psocksxx - A C++ wrapper for POSIX sockets
+* Copyright (C) 2013 Uditha Atukorala
+*
+* This software library is free software; you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as published by
+* the Free Software Foundation; either version 3 of the License, or
+* (at your option) any later version.
+*
+* This software library 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 Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License
+* along with this software library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+#ifndef PSOCKSXX_SOCKSTREAMBUF_H
+#define PSOCKSXX_SOCKSTREAMBUF_H
+
+#include <psocksxx/socktimeoutexception.h>
+#include <psocksxx/sockaddr.h>
+
+#include <streambuf>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+
+#ifndef SOCKSTREAMBUF_SIZE
+#define SOCKSTREAMBUF_SIZE 1024
+#endif
+
+#ifndef SOCKSTREAMBUF_PUTBACK_SIZE
+#define SOCKSTREAMBUF_PUTBACK_SIZE 8
+#endif
+
+
+namespace psocksxx {
+
+ /**
+ * @brief Socket stream buffer class
+ *
+ * This buffer class associates its both input and output
+ * sequences with an external POSIX socket.
+ */
+ class sockstreambuf : public std::streambuf {
+ public:
+
+ /** socket data type definition */
+ typedef int socket_t;
+
+ /** socket end-of-file type */
+ enum eof_t {
+ eof = -1 /*!< end of file */
+ };
+
+ /** socket domains type definition */
+ enum socket_domain_t {
+ pf_local = PF_LOCAL, /*!< Host-internal protocols */
+ pf_inet = PF_INET, /*!< Internet version 4 protocols */
+ pf_route = PF_ROUTE, /*!< Internal Routing protocol */
+ pf_key = PF_KEY, /*!< Internal key-management function */
+ pf_inet6 = PF_INET6 /*!< Internet version 6 protocols */
+ };
+
+ /** socket types type definition */
+ enum socket_type_t {
+ sock_stream = SOCK_STREAM,
+ sock_dgram = SOCK_DGRAM,
+ sock_raw = SOCK_RAW,
+ sock_rdm = SOCK_RDM,
+ sock_seqpacket = SOCK_SEQPACKET
+ };
+
+ /** socket protocols type definition */
+ enum socket_protocol_t {
+ proto_unspec = 0, /*!< Unspecified system default */
+ ipproto_ip = IPPROTO_IP, /*!< Internet protocol */
+ ipproto_ipv6 = IPPROTO_IPV6, /*!< Internet Protocol Version 6 */
+ ipproto_icmp = IPPROTO_ICMP, /*!< Control message protocol */
+ ipproto_raw = IPPROTO_RAW, /*!< Raw IP Packets Protocol */
+ ipproto_tcp = IPPROTO_TCP, /*!< Transmission control protocol */
+ ipproto_udp = IPPROTO_UDP /*!< User datagram protocol */
+ };
+
+
+ sockstreambuf() throw(); //!< constructor
+ virtual ~sockstreambuf(); //!< destructor
+
+ /**
+ * @brief overloaded constructor
+ * @param socket socket data
+ *
+ * Create an instance with the passed in sockstreambuf::socket_t
+ * type socket. It is assumed that the socket is initialised and
+ * ready to use.
+ *
+ */
+ sockstreambuf( socket_t socket ) throw();
+
+ /**
+ * @brief get internal socket data
+ * @return socket data
+ *
+ * Returns a read-only reference to the internal POSIX socket
+ * data.
+ *
+ */
+ const socket_t & socket() const throw();
+
+ /**
+ * @brief open a socket
+ * @param domain communications domain for the socket
+ * @param type socket communications type
+ * @param proto socket communications protocol
+ * @throw psocksxx::sockexception socket exception
+ *
+ * Open a socket and initialise socket communications.
+ *
+ */
+ void open( socket_domain_t domain, socket_type_t type, socket_protocol_t proto = proto_unspec ) throw( sockexception );
+
+ /**
+ * @brief close open sockets
+ *
+ * Close any open socket connections used by this buffer. This
+ * will also flush any data in the buffer before closing.
+ *
+ */
+ void close() throw();
+
+ /**
+ * @brief flush the socket output buffer
+ * @return number of characters flushed
+ * @throw psocksxx::socktimeoutexception on socket timeout
+ *
+ * Flush the socket buffer by writing date into the
+ * socket and returns the number of characters flushed.
+ * If the output buffer is empty sockstreambuf::eof is returned.
+ *
+ */
+ virtual int flush() throw( socktimeoutexception );
+
+
+ /**
+ * @brief initiate a connection on a socket
+ * @param dest_addr destination address to connect to
+ * @param timeout connection timeout value in seconds
+ * @throw psocksxx::sockexception socket exception
+ * @throw psocksxx::socktimeoutexception connection timeout
+ * exception
+ *
+ * Initiate a connection on a socket previously opened using
+ * open() method. If the timeout value is 0 (default) then
+ * the timeouts are ignored.
+ *
+ */
+ void connect( const sockaddr * dest_addr, unsigned int timeout = 0 ) throw( sockexception, socktimeoutexception );
+
+ /**
+ * @brief initiate a connection on a socket
+ * @param dest_addr destination address to connect to
+ * @param timeout connection timeout value as a reference to a
+ * @c timeval structure
+ *
+ * @throw psocksxx::sockexception socket exception
+ * @throw psocksxx::socktimeoutexception connection timeout
+ * exception
+ *
+ * Initiate a connection on a socket previously opened using
+ * open() method.
+ *
+ */
+ void connect( const sockaddr * dest_addr, timeval * timeout ) throw( sockexception, socktimeoutexception );
+
+ /**
+ * @brief bind the socket to a specified address
+ * @param bind_addr address to bind to
+ * @param reuse_addr allow address to be re-used
+ * @throw psocksxx::sockexception socket exception
+ *
+ * After a socket is configured using open() this method can
+ * be used to assign an address to it. If @c reuse_addr is set
+ * to @c true then this will try to re-use the address unless
+ * the address is actively listening.
+ *
+ */
+ void bind( const sockaddr * bind_addr, bool reuse_addr = false ) throw( sockexception );
+
+ /**
+ * @brief make the socket passive and capable of accepting connections
+ * @param backlog maximum length of the queue for pending connections
+ * and defaults to SOMAXCONN (128) defined in @c <sys/socket.h>
+ *
+ * @throw psocksxx::sockexception socket exception
+ *
+ * This method will make the currently opened socket connection
+ * to passive and capable of accepting client connections using accept()
+ * method.
+ *
+ */
+ void listen( int backlog = SOMAXCONN ) throw( sockexception );
+
+ /**
+ * @brief accept a connection on a listening (passive) socket
+ * @throw psocksxx::sockexception socket exception
+ * @return peer socket data structure
+ *
+ * This method will accept incoming connections on a socket
+ * set to be passive using the listen() method. Upon success
+ * this will return the peer socket data structure that can be used
+ * to create a socket stream buffer instance to communicate
+ * with the accepted socket connection.
+ *
+ */
+ socket_t accept() throw( sockexception );
+
+ /**
+ * @brief set the timeout value for the socket
+ * @param sec seconds
+ * @param usec microseconds
+ * @return a reference to the internal timeout structure
+ *
+ * This method will set the timeout for the socket and make this
+ * a non-blocking socket. Note that you cannot clear the timeout
+ * by passing in a 0 timeout, use clear_timeout() method instead.
+ *
+ */
+ const timeval * timeout( time_t sec, suseconds_t usec ) throw();
+
+ /**
+ * @brief clear the timeout value for the socket
+ * @return a reference to the internal timeout structure which will
+ * always be a null-pointer (@c 0) after clearing the timeout
+ *
+ * This will clear any timeout values set for the socket affectively
+ * making this a blocking socket by default.
+ *
+ */
+ void * clear_timeout() throw();
+
+ /**
+ * @brief get the timed-out status
+ * @return boolean @c true if timed-out flag is set or @c false
+ * otherwise.
+ *
+ * Returns the timed-out status.
+ *
+ */
+ bool timedout() const throw();
+
+
+ protected:
+
+ /**
+ * @brief initialise internal buffers
+ */
+ void init_buffers() throw();
+
+ /**
+ * @brief cleanup internal buffers
+ */
+ void cleanup_buffers() throw();
+
+ /**
+ * @brief sync data with the socket
+ * @return 0 or -1 to denote success or failure
+ *
+ * Synchronise the buffer with the associated socket
+ * by flushing data from the buffer to the socket.
+ *
+ */
+ virtual int sync() throw();
+
+ /**
+ * @brief consumes the buffer by writing the contents to
+ * the socket
+ *
+ * @param c additional character to consume
+ * @return sockstreambuf::eof to indicate failure or @a c
+ * if successful.
+ *
+ * @throw psocksxx::socktimeoutexception on socket timeout
+ *
+ *
+ * Consumes the buffer contents and writes to the opened socket.
+ * If @a c is not sockstreambuf::eof then @a c is also written
+ * out.
+ *
+ */
+ virtual int overflow( int c = eof ) throw( socktimeoutexception );
+
+ /**
+ * @brief read more data into the buffer from the socket
+ * @return the first character from the buffer or sockstreambuf::eof
+ * if no data is available to read
+ *
+ * @throw psocksxx::socktimeoutexception on socket timeout
+ *
+ *
+ * This reads more data into the buffer from the socket when
+ * the input buffer is empty and returns the next readable
+ * character from the buffer. If the buffer is empty and no
+ * data is available through the socket, this returns sockstreambuf::eof.
+ *
+ */
+ virtual int underflow() throw( socktimeoutexception );
+
+ /**
+ * @brief check for the read/write availability on the socket
+ * @param timeout timeout value reference to a @c timeval structure
+ * @param chk_read check for read availability
+ * @param chk_write check for write availability
+ * @throw psocksxx::sockexception socket exception
+ * @return boolean @c true to denote availability or @c false
+ * if none of the checked actions are available.
+ *
+ * This will check the socket for read and/or write availability.
+ *
+ */
+ bool ready( timeval * timeout, bool chk_read = true, bool chk_write = true ) throw( sockexception );
+
+
+ private:
+
+ /** POSIX socket data */
+ socket_t _socket;
+
+ size_t _bufsize;
+ size_t _putbacksize;
+
+ timeval * _timeout;
+ bool _timed_out;
+
+
+ void init_defaults() throw();
+
+ };
+
+} /* end of namespace psocksxx */
+
+#endif /* !PSOCKSXX_SOCKSTREAMBUF_H */
+