root/trunk/dep/include/sockets/TcpSocket.h @ 2

Revision 2, 10.8 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/** \file TcpSocket.h
2 **     \date  2004-02-13
3 **     \author grymse@alhem.net
4**/
5/*
6Copyright (C) 2004-2007  Anders Hedstrom
7
8This library is made available under the terms of the GNU GPL.
9
10If you would like to use this library in a closed-source application,
11a separate license agreement is available. For information about
12the closed-source license agreement for the C++ sockets library,
13please visit http://www.alhem.net/Sockets/license.html and/or
14email license@alhem.net.
15
16This program is free software; you can redistribute it and/or
17modify it under the terms of the GNU General Public License
18as published by the Free Software Foundation; either version 2
19of the License, or (at your option) any later version.
20
21This program is distributed in the hope that it will be useful,
22but WITHOUT ANY WARRANTY; without even the implied warranty of
23MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24GNU General Public License for more details.
25
26You should have received a copy of the GNU General Public License
27along with this program; if not, write to the Free Software
28Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
29*/
30#ifndef _SOCKETS_TcpSocket_H
31#define _SOCKETS_TcpSocket_H
32#include "sockets-config.h"
33#include "StreamSocket.h"
34#ifdef HAVE_OPENSSL
35#include <openssl/ssl.h>
36#include "SSLInitializer.h"
37#endif
38
39#include <string.h>
40
41#define TCP_BUFSIZE_READ 16400
42#define TCP_OUTPUT_CAPACITY 1024000
43
44
45#ifdef SOCKETS_NAMESPACE
46namespace SOCKETS_NAMESPACE {
47#endif
48
49class SocketAddress;
50
51
52/** Socket implementation for TCP.
53        \ingroup basic */
54class TcpSocket : public StreamSocket
55{
56        /** \defgroup internal Internal utility */
57protected:
58        /** Buffer class containing one read/write circular buffer.
59                \ingroup internal */
60        class CircularBuffer
61        {
62        public:
63                CircularBuffer(size_t size);
64                ~CircularBuffer();
65
66                /** append l bytes from p to buffer */
67                bool Write(const char *p,size_t l);
68                /** copy l bytes from buffer to dest */
69                bool Read(char *dest,size_t l);
70        /** copy l bytes from buffer to dest, dont touch buffer pointers */
71        bool SoftRead(char *dest, size_t l);
72                /** skip l bytes from buffer */
73                bool Remove(size_t l);
74                /** read l bytes from buffer, returns as string. */
75                std::string ReadString(size_t l);
76
77                /** total buffer length */
78                size_t GetLength();
79                /** pointer to circular buffer beginning */
80                const char *GetStart();
81                /** return number of bytes from circular buffer beginning to buffer physical end */
82                size_t GetL();
83                /** return free space in buffer, number of bytes until buffer overrun */
84                size_t Space();
85
86                /** return total number of bytes written to this buffer, ever */
87                unsigned long ByteCounter(bool clear = false);
88
89        private:
90                CircularBuffer(const CircularBuffer& /*s*/) {}
91                CircularBuffer& operator=(const CircularBuffer& ) { return *this; }
92                char *buf;
93                size_t m_max;
94                size_t m_q;
95                size_t m_b;
96                size_t m_t;
97                unsigned long m_count;
98        };
99        /** Output buffer struct.
100                \ingroup internal */
101        struct OUTPUT {
102                OUTPUT() : _b(0), _t(0), _q(0) {}
103                OUTPUT(const char *buf, size_t len) : _b(0), _t(len), _q(len) {
104                        memcpy(_buf, buf, len);
105                }
106                size_t Space() {
107                        return TCP_OUTPUT_CAPACITY - _t;
108                }
109                void Add(const char *buf, size_t len) {
110                        memcpy(_buf + _t, buf, len);
111                        _t += len;
112                        _q += len;
113                }
114                size_t Remove(size_t len) {
115                        _b += len;
116                        _q -= len;
117                        return _q;
118                }
119                const char *Buf() {
120                        return _buf + _b;
121                }
122                size_t Len() {
123                        return _q;
124                }
125                size_t _b;
126                size_t _t;
127                size_t _q;
128                char _buf[TCP_OUTPUT_CAPACITY];
129        };
130        typedef std::list<OUTPUT *> output_l;
131
132public:
133        /** Constructor with standard values on input/output buffers. */
134        TcpSocket(ISocketHandler& );
135        /** Constructor with custom values for i/o buffer.
136                \param h ISocketHandler reference
137                \param isize Input buffer size
138                \param osize Output buffer size */
139        TcpSocket(ISocketHandler& h,size_t isize,size_t osize);
140        ~TcpSocket();
141
142        /** Open a connection to a remote server.
143            If you want your socket to connect to a server,
144            always call Open before Add'ing a socket to the sockethandler.
145            If not, the connection attempt will not be monitored by the
146            socket handler...
147                \param ip IP address
148                \param port Port number
149                \param skip_socks Do not use socks4 even if configured */
150        bool Open(ipaddr_t ip,port_t port,bool skip_socks = false);
151#ifdef ENABLE_IPV6
152#ifdef IPPROTO_IPV6
153        /** Open connection.
154                \param ip Ipv6 address
155                \param port Port number
156                \param skip_socks Do not use socks4 even if configured */
157        bool Open(in6_addr ip,port_t port,bool skip_socks = false);
158#endif
159#endif
160        bool Open(SocketAddress&,bool skip_socks = false);
161        bool Open(SocketAddress&,SocketAddress& bind_address,bool skip_socks = false);
162        /** Open connection.
163                \param host Hostname
164                \param port Port number */
165        bool Open(const std::string &host,port_t port);
166
167        /** Connect timeout callback. */
168        void OnConnectTimeout();
169#ifdef _WIN32
170        /** Connection failed reported as exception on win32 */
171        void OnException();
172#endif
173
174        /** Close file descriptor - internal use only.
175                \sa SetCloseAndDelete */
176        int Close();
177
178        /** Send a string.
179                \param s String to send
180                \param f Dummy flags -- not used */
181        void Send(const std::string &s,int f = 0);
182        /** Send string using printf formatting. */
183        void Sendf(const char *format, ...);
184        /** Send buffer of bytes.
185                \param buf Buffer pointer
186                \param len Length of data
187                \param f Dummy flags -- not used */
188        void SendBuf(const char *buf,size_t len,int f = 0);
189        /** This callback is executed after a successful read from the socket.
190                \param buf Pointer to the data
191                \param len Length of the data */
192        virtual void OnRawData(const char *buf,size_t len);
193
194        /** Called when output buffer has been sent.
195            Note: Will only be called IF the output buffer has been used.
196            Send's that was successful without needing the output buffer
197            will not generate a call to this method. */
198        virtual void OnWriteComplete();
199        /** Number of bytes in input buffer. */
200        size_t GetInputLength();
201        /** Number of bytes in output buffer. */
202        size_t GetOutputLength();
203
204        /** Callback fires when a socket in line protocol has read one full line.
205                \param line Line read */
206        void OnLine(const std::string& line);
207        /** Get counter of number of bytes received. */
208        uint64_t GetBytesReceived(bool clear = false);
209        /** Get counter of number of bytes sent. */
210        uint64_t GetBytesSent(bool clear = false);
211
212        /** Socks4 specific callback. */
213        void OnSocks4Connect();
214        /** Socks4 specific callback. */
215        void OnSocks4ConnectFailed();
216        /** Socks4 specific callback.
217                \return 'need_more' */
218        bool OnSocks4Read();
219
220#ifdef ENABLE_RESOLVER
221        /** Callback executed when resolver thread has finished a resolve request. */
222        void OnResolved(int id,ipaddr_t a,port_t port);
223#ifdef ENABLE_IPV6
224        void OnResolved(int id,in6_addr& a,port_t port);
225#endif
226#endif
227#ifdef HAVE_OPENSSL
228        /** Callback for 'New' ssl support - replaces SSLSocket. Internal use. */
229        void OnSSLConnect();
230        /** Callback for 'New' ssl support - replaces SSLSocket. Internal use. */
231        void OnSSLAccept();
232        /** This method must be implemented to initialize
233                the ssl context for an outgoing connection. */
234        virtual void InitSSLClient();
235        /** This method must be implemented to initialize
236                the ssl context for an incoming connection. */
237        virtual void InitSSLServer();
238#endif
239
240#ifdef ENABLE_RECONNECT
241        /** Flag that says a broken connection will try to reconnect. */
242        void SetReconnect(bool = true);
243        /** Check reconnect on lost connection flag status. */
244        bool Reconnect();
245        /** Flag to determine if a reconnect is in progress. */
246        void SetIsReconnect(bool x = true);
247        /** Socket is reconnecting. */
248        bool IsReconnect();
249#endif
250
251        void DisableInputBuffer(bool = true);
252
253        void OnOptions(int,int,int,SOCKET);
254
255        void SetLineProtocol(bool = true);
256
257        // TCP options
258        bool SetTcpNodelay(bool = true);
259
260        virtual int Protocol();
261
262        /** Trigger limit for callback OnTransferLimit. */
263        void SetTransferLimit(size_t sz);
264        /** This callback fires when the output buffer drops below the value
265            set by SetTransferLimit. Default: 0 (disabled). */
266        virtual void OnTransferLimit();
267
268protected:
269        TcpSocket(const TcpSocket& );
270        void OnRead();
271        void OnRead( char *buf, size_t n );
272        void OnWrite();
273#ifdef HAVE_OPENSSL
274        /** SSL; Initialize ssl context for a client socket.
275                \param meth_in SSL method */
276        void InitializeContext(const std::string& context, SSL_METHOD *meth_in = NULL);
277        /** SSL; Initialize ssl context for a server socket.
278                \param keyfile Combined private key/certificate file
279                \param password Password for private key
280                \param meth_in SSL method */
281        void InitializeContext(const std::string& context, const std::string& keyfile, const std::string& password, SSL_METHOD *meth_in = NULL);
282        /** SSL; Initialize ssl context for a server socket.
283                \param certfile Separate certificate file
284                \param keyfile Combined private key/certificate file
285                \param password Password for private key
286                \param meth_in SSL method */
287        void InitializeContext(const std::string& context, const std::string& certfile, const std::string& keyfile, const std::string& password, SSL_METHOD *meth_in = NULL);
288        /** SSL; Password callback method. */
289static  int SSL_password_cb(char *buf,int num,int rwflag,void *userdata);
290        /** SSL; Get pointer to ssl context structure. */
291        virtual SSL_CTX *GetSslContext();
292        /** SSL; Get pointer to ssl structure. */
293        virtual SSL *GetSsl();
294        /** ssl; still negotiating connection. */
295        bool SSLNegotiate();
296        /** SSL; Get ssl password. */
297        const std::string& GetPassword();
298#endif
299
300        CircularBuffer ibuf; ///< Circular input buffer
301
302private:
303        TcpSocket& operator=(const TcpSocket& ) { return *this; }
304
305        /** the actual send() */
306        int TryWrite(const char *buf, size_t len);
307        /** add data to output buffer top */
308        void Buffer(const char *buf, size_t len);
309
310        //
311        bool m_b_input_buffer_disabled;
312        uint64_t m_bytes_sent;
313        uint64_t m_bytes_received;
314        bool m_skip_c; ///< Skip second char of CRLF or LFCR sequence in OnRead
315        char m_c; ///< First char in CRLF or LFCR sequence
316        std::string m_line; ///< Current line in line protocol mode
317#ifdef SOCKETS_DYNAMIC_TEMP
318        char *m_buf; ///< temporary read buffer
319#endif
320        output_l m_obuf; ///< output buffer
321        OUTPUT *m_obuf_top; ///< output buffer on top
322        size_t m_transfer_limit;
323        size_t m_output_length;
324
325#ifdef HAVE_OPENSSL
326static  SSLInitializer m_ssl_init;
327        SSL_CTX *m_ssl_ctx; ///< ssl context
328        SSL *m_ssl; ///< ssl 'socket'
329        BIO *m_sbio; ///< ssl bio
330        std::string m_password; ///< ssl password
331#endif
332
333#ifdef ENABLE_SOCKS4
334        int m_socks4_state; ///< socks4 support
335        char m_socks4_vn; ///< socks4 support, temporary variable
336        char m_socks4_cd; ///< socks4 support, temporary variable
337        unsigned short m_socks4_dstport; ///< socks4 support
338        unsigned long m_socks4_dstip; ///< socks4 support
339#endif
340
341#ifdef ENABLE_RESOLVER
342        int m_resolver_id; ///< Resolver id (if any) for current Open call
343#endif
344
345#ifdef ENABLE_RECONNECT
346        bool m_b_reconnect; ///< Reconnect on lost connection flag
347        bool m_b_is_reconnect; ///< Trying to reconnect
348#endif
349
350};
351
352
353#ifdef SOCKETS_NAMESPACE
354}
355#endif
356
357#endif // _SOCKETS_TcpSocket_H
358
Note: See TracBrowser for help on using the browser.