3 ** \author grymse@alhem.net
6 Copyright (C) 2004-2007 Anders Hedstrom
8 This software is made available under the terms of the GNU GPL.
10 If you would like to use this library in a closed-source application,
11 a separate license agreement is available. For information about
12 the closed-source license agreement for the C++ sockets library,
13 please visit http://www.alhem.net/Sockets/license.html and/or
14 email license@alhem.net.
16 This program is free software; you can redistribute it and/or
17 modify it under the terms of the GNU General Public License
18 as published by the Free Software Foundation; either version 2
19 of the License, or (at your option) any later version.
21 This program is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 GNU General Public License for more details.
26 You should have received a copy of the GNU General Public License
27 along with this program; if not, write to the Free Software
28 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
30 #ifndef _SOCKETS_Socket_H
31 #define _SOCKETS_Socket_H
32 #include "sockets-config.h"
38 #include <openssl/ssl.h>
41 #include "socket_include.h"
44 #include "SocketAddress.h"
48 #ifdef SOCKETS_NAMESPACE
49 namespace SOCKETS_NAMESPACE
{
58 /** \defgroup basic Basic sockets */
59 /** Socket base class.
63 friend class ISocketHandler
;
65 /** Detached socket run thread.
67 class SocketThread
: public Thread
70 SocketThread(Socket
*p
);
76 Socket
*GetSocket() const { return m_socket
; }
77 SocketThread(const SocketThread
& s
) : m_socket(s
.GetSocket()) {}
78 SocketThread
& operator=(const SocketThread
& ) { return *this; }
81 #endif // ENABLE_DETACH
83 #ifdef ENABLE_TRIGGERS
85 /** Data pass class from source to destination. */
89 TriggerData() : m_src(NULL
) {}
90 virtual ~TriggerData() {}
92 Socket
*GetSource() const { return m_src
; }
93 void SetSource(Socket
*x
) { m_src
= x
; }
98 #endif // ENABLE_TRIGGERS
100 /** Socket mode flags. */
104 SOCK_DEL = 0x01, ///< Delete by handler flag
105 SOCK_CLOSE = 0x02, ///< Close and delete flag
106 SOCK_DISABLE_READ = 0x04, ///< Disable checking for read events
107 SOCK_CONNECTED = 0x08, ///< Socket is connected (tcp/udp)
109 SOCK_ERASED_BY_HANDLER = 0x10, ///< Set by handler before delete
111 SOCK_ENABLE_SSL = 0x20, ///< Enable SSL for this TcpSocket
112 SOCK_SSL = 0x40, ///< ssl negotiation mode (TcpSocket)
113 SOCK_SSL_SERVER = 0x80, ///< True if this is an incoming ssl TcpSocket connection
116 SOCK_IPV6 = 0x0100, ///< This is an ipv6 socket if this one is true
118 SOCK_CLIENT = 0x0200, ///< only client connections are pooled
119 SOCK_RETAIN = 0x0400, ///< keep connection on close
120 SOCK_LOST = 0x0800, ///< connection lost
123 SOCK_SOCKS4 = 0x1000, ///< socks4 negotiation mode (TcpSocket)
125 SOCK_DETACH = 0x2000, ///< Socket ordered to detach flag
126 SOCK_DETACHED = 0x4000, ///< Socket has been detached
128 STREAMSOCK_CONNECTING = 0x8000, ///< Flag indicating connection in progress
130 STREAMSOCK_FLUSH_BEFORE_CLOSE = 0x010000L, ///< Send all data before closing (default true)
131 STREAMSOCK_CALL_ON_CONNECT = 0x020000L, ///< OnConnect will be called next ISocketHandler cycle if true
132 STREAMSOCK_RETRY_CONNECT = 0x040000L, ///< Try another connection attempt next ISocketHandler cycle
133 STREAMSOCK_LINE_PROTOCOL = 0x080000L, ///< Line protocol mode flag
139 /** "Default" constructor */
140 Socket(ISocketHandler
&);
144 /** Socket class instantiation method. Used when a "non-standard" constructor
145 * needs to be used for the socket class. Note: the socket class still needs
146 * the "default" constructor with one ISocketHandler& as input parameter.
148 virtual Socket
*Create() { return NULL
; }
150 /** Returns reference to sockethandler that owns the socket.
151 If the socket is detached, this is a reference to the slave sockethandler.
153 ISocketHandler
& Handler() const;
155 /** Returns reference to sockethandler that owns the socket.
156 This one always returns the reference to the original sockethandler,
157 even if the socket is detached.
159 ISocketHandler
& MasterHandler() const;
161 /** Called by ListenSocket after accept but before socket is added to handler.
162 * CTcpSocket uses this to create its ICrypt member variable.
163 * The ICrypt member variable is created by a virtual method, therefore
164 * it can't be called directly from the CTcpSocket constructor.
165 * Also used to determine if incoming HTTP connection is normal (port 80)
170 /** Create a socket file descriptor.
171 \param af Address family AF_INET / AF_INET6 / ...
172 \param type SOCK_STREAM / SOCK_DGRAM / ...
173 \param protocol "tcp" / "udp" / ... */
174 SOCKET
CreateSocket(int af
,int type
,const std::string
& protocol
= "");
176 /** Assign this socket a file descriptor created
177 by a call to socket() or otherwise. */
178 void Attach(SOCKET s
);
180 /** Return file descriptor assigned to this socket. */
183 /** Close connection immediately - internal use.
184 \sa SetCloseAndDelete */
187 /** Add file descriptor to sockethandler fd_set's. */
188 void Set(bool bRead
,bool bWrite
,bool bException
= true);
190 /** Returns true when socket file descriptor is valid
191 and socket is not about to be closed. */
192 virtual bool Ready();
194 /** Returns pointer to ListenSocket that created this instance
195 * on an incoming connection. */
198 /** Used by ListenSocket to set parent pointer of newly created
199 * socket instance. */
200 void SetParent(Socket
*);
202 /** Get listening port from ListenSocket<>. */
203 virtual port_t
GetPort();
205 /** Set socket non-block operation. */
206 bool SetNonblocking(bool);
208 /** Set socket non-block operation. */
209 bool SetNonblocking(bool, SOCKET
);
211 /** Total lifetime of instance. */
214 /** Set address/port of last connect() call. */
215 void SetClientRemoteAddress(SocketAddress
&);
217 /** Get address/port of last connect() call. */
218 std::auto_ptr
<SocketAddress
> GetClientRemoteAddress();
220 /** Common interface for SendBuf used by Tcp and Udp sockets. */
221 virtual void SendBuf(const char *,size_t,int = 0);
223 /** Common interface for Send used by Tcp and Udp sockets. */
224 virtual void Send(const std::string
&,int = 0);
226 /** Outgoing traffic counter. */
227 virtual uint64_t GetBytesSent(bool clear
= false);
229 /** Incoming traffic counter. */
230 virtual uint64_t GetBytesReceived(bool clear
= false);
234 /** Enable timeout control. 0=disable timeout check. */
235 void SetTimeout(time_t secs
);
237 /** Check timeout. \return true if time limit reached */
238 bool Timeout(time_t tnow
);
240 /** Used by ListenSocket. ipv4 and ipv6 */
241 void SetRemoteAddress(SocketAddress
&);
243 /** \name Event callbacks */
246 /** Called when there is something to be read from the file descriptor. */
247 virtual void OnRead();
248 /** Called when there is room for another write on the file descriptor. */
249 virtual void OnWrite();
250 /** Called on socket exception. */
251 virtual void OnException();
252 /** Called before a socket class is deleted by the ISocketHandler. */
253 virtual void OnDelete();
254 /** Called when a connection has completed. */
255 virtual void OnConnect();
256 /** Called when an incoming connection has been completed. */
257 virtual void OnAccept();
258 /** Called when a complete line has been read and the socket is in
259 * line protocol mode. */
260 virtual void OnLine(const std::string
& );
261 /** Called on connect timeout (5s). */
262 virtual void OnConnectFailed();
263 /** Called when a client socket is created, to set socket options.
264 \param family AF_INET, AF_INET6, etc
265 \param type SOCK_STREAM, SOCK_DGRAM, etc
266 \param protocol Protocol number (tcp, udp, sctp, etc)
267 \param s Socket file descriptor
269 virtual void OnOptions(int family
,int type
,int protocol
,SOCKET s
) = 0;
270 /** Connection retry callback - return false to abort connection attempts */
271 virtual bool OnConnectRetry();
272 #ifdef ENABLE_RECONNECT
273 /** a reconnect has been made */
274 virtual void OnReconnect();
275 /** When a socket is set to reconnect, and a disconnect has been detected. */
276 virtual void OnDisconnect();
278 /** Timeout callback. */
279 virtual void OnTimeout();
280 /** Connection timeout. */
281 virtual void OnConnectTimeout();
284 /** \name Socket mode flags, set/reset */
286 /** Set delete by handler true when you want the sockethandler to
287 delete the socket instance after use. */
288 void SetDeleteByHandler(bool = true);
289 /** Check delete by handler flag.
290 \return true if this instance should be deleted by the sockethandler */
291 bool DeleteByHandler();
293 // LIST_CLOSE - conditional event queue
295 /** Set close and delete to terminate the connection. */
296 void SetCloseAndDelete(bool = true);
297 /** Check close and delete flag.
298 \return true if this socket should be closed and the instance removed */
299 bool CloseAndDelete();
301 /** Return number of seconds since socket was ordered to close. \sa SetCloseAndDelete */
302 time_t TimeSinceClose();
304 /** Ignore read events for an output only socket. */
305 void DisableRead(bool x
= true);
306 /** Check ignore read events flag.
307 \return true if read events should be ignored */
308 bool IsDisableRead();
310 /** Set connected status. */
311 void SetConnected(bool = true);
312 /** Check connected status.
313 \return true if connected */
316 /** Set flag indicating the socket is being actively deleted by the sockethandler. */
317 void SetErasedByHandler(bool x
= true);
318 /** Get value of flag indicating socket is deleted by sockethandler. */
319 bool ErasedByHandler();
323 /** \name Information about remote connection */
325 /** Returns address of remote end. */
326 std::auto_ptr
<SocketAddress
> GetRemoteSocketAddress();
327 /** Returns address of remote end: ipv4. */
328 ipaddr_t
GetRemoteIP4();
330 /** Returns address of remote end: ipv6. */
332 struct in6_addr
GetRemoteIP6();
335 /** Returns remote port number: ipv4 and ipv6. */
336 port_t
GetRemotePort();
337 /** Returns remote ip as string? ipv4 and ipv6. */
338 std::string
GetRemoteAddress();
339 /** ipv4 and ipv6(not implemented) */
340 std::string
GetRemoteHostname();
343 // --------------------------------------------------------------------------
345 When an ip or socket option is available on all of the operating systems
346 I'm testing on (linux 2.4.x, _win32, macosx, solaris9 intel) they are not
347 checked with an #ifdef below.
348 This might cause a compile error on other operating systems. */
349 // --------------------------------------------------------------------------
354 bool SetIpOptions(const void *p
, socklen_t len
);
355 bool SetIpTOS(unsigned char tos
);
356 unsigned char IpTOS();
357 bool SetIpTTL(int ttl
);
359 bool SetIpHdrincl(bool x
= true);
360 bool SetIpMulticastTTL(int);
361 int IpMulticastTTL();
362 bool SetMulticastLoop(bool x
= true);
363 bool IpAddMembership(struct ip_mreq
&);
364 bool IpDropMembership(struct ip_mreq
&);
367 bool SetIpPktinfo(bool x
= true);
370 bool SetIpRecvTOS(bool x
= true);
373 bool SetIpRecvTTL(bool x
= true);
376 bool SetIpRecvopts(bool x
= true);
379 bool SetIpRetopts(bool x
= true);
382 bool SetIpRecverr(bool x
= true);
384 #ifdef IP_MTU_DISCOVER
385 bool SetIpMtudiscover(bool x
= true);
390 #ifdef IP_ROUTER_ALERT
391 bool SetIpRouterAlert(bool x
= true);
394 bool IpAddMembership(struct ip_mreqn
&);
397 bool IpDropMembership(struct ip_mreqn
&);
402 /** @name Socket Options */
406 bool SetSoBroadcast(bool x
= true);
407 bool SetSoDebug(bool x
= true);
409 bool SetSoDontroute(bool x
= true);
410 bool SetSoLinger(int onoff
, int linger
);
411 bool SetSoOobinline(bool x
= true);
412 bool SetSoRcvlowat(int);
413 bool SetSoSndlowat(int);
414 bool SetSoRcvtimeo(struct timeval
&);
415 bool SetSoSndtimeo(struct timeval
&);
416 bool SetSoRcvbuf(int);
418 bool SetSoSndbuf(int);
421 bool SetSoReuseaddr(bool x
= true);
422 bool SetSoKeepalive(bool x
= true);
425 bool SetSoBsdcompat(bool x
= true);
427 #ifdef SO_BINDTODEVICE
428 bool SetSoBindtodevice(const std::string
& intf
);
431 bool SetSoPasscred(bool x
= true);
434 bool SoPeercred(struct ucred
& );
437 bool SetSoPriority(int);
439 #ifdef SO_RCVBUFFORCE
440 bool SetSoRcvbufforce(int);
442 #ifdef SO_SNDBUFFORCE
443 bool SetSoSndbufforce(int);
446 bool SetSoTimestamp(bool x
= true);
449 bool SetSoNosigpipe(bool x
= true);
453 // TCP options in TcpSocket.h/TcpSocket.cpp
457 /** @name SSL Support */
459 /** SSL client/server support - internal use. \sa TcpSocket */
460 virtual void OnSSLConnect();
461 /** SSL client/server support - internal use. \sa TcpSocket */
462 virtual void OnSSLAccept();
463 /** SSL negotiation failed for client connect. */
464 virtual void OnSSLConnectFailed();
465 /** SSL negotiation failed for server accept. */
466 virtual void OnSSLAcceptFailed();
467 /** new SSL support */
468 virtual bool SSLNegotiate();
469 /** Check if SSL is Enabled for this TcpSocket.
470 \return true if this is a TcpSocket with SSL enabled */
472 /** Enable SSL operation for a TcpSocket. */
473 void EnableSSL(bool x
= true);
474 /** Still negotiating ssl connection.
475 \return true if ssl negotiating is still in progress */
476 bool IsSSLNegotiate();
477 /** Set flag indicating ssl handshaking still in progress. */
478 void SetSSLNegotiate(bool x
= true);
479 /** OnAccept called with SSL Enabled.
480 \return true if this is a TcpSocket with an incoming SSL connection */
482 /** Set flag indicating that this is a TcpSocket with incoming SSL connection. */
483 void SetSSLServer(bool x
= true);
484 /** SSL; Get pointer to ssl context structure. */
485 virtual SSL_CTX
*GetSslContext() { return NULL
; }
486 /** SSL; Get pointer to ssl structure. */
487 virtual SSL
*GetSsl() { return NULL
; }
489 #endif // HAVE_OPENSSL
492 /** Enable ipv6 for this socket. */
493 void SetIpv6(bool x
= true);
494 /** Check ipv6 socket.
495 \return true if this is an ipv6 socket */
500 /** @name Connection Pool */
502 /** Client = connecting TcpSocket. */
504 /** Socket type from socket() call. */
505 void SetSocketType(int x
);
506 /** Socket type from socket() call. */
508 /** Protocol type from socket() call. */
509 void SetSocketProtocol(const std::string
& x
);
510 /** Protocol type from socket() call. */
511 const std::string
& GetSocketProtocol();
512 /** Instruct a client socket to stay open in the connection pool after use.
513 If you have connected to a server using tcp, you can call SetRetain
514 to leave the connection open after your socket instance has been deleted.
515 The next connection you make to the same server will reuse the already
516 opened connection, if it is still available.
519 /** Check retain flag.
520 \return true if the socket should be moved to connection pool after use */
522 /** Connection lost - error while reading/writing from a socket - TcpSocket only. */
524 /** Check connection lost status flag, used by TcpSocket only.
525 \return true if there was an error while r/w causing the socket to close */
527 /** Copy connection parameters from sock. */
528 void CopyConnection(Socket
*sock
);
530 #endif // ENABLE_POOL
533 /** \name Socks4 support */
535 /** Socks4 client support internal use. \sa TcpSocket */
536 virtual void OnSocks4Connect();
537 /** Socks4 client support internal use. \sa TcpSocket */
538 virtual void OnSocks4ConnectFailed();
539 /** Socks4 client support internal use. \sa TcpSocket */
540 virtual bool OnSocks4Read();
541 /** Called when the last write caused the tcp output buffer to
543 /** socket still in socks4 negotiation mode */
545 /** Set flag indicating Socks4 handshaking in progress */
546 void SetSocks4(bool x
= true);
548 /** Set socks4 server host address to use */
549 void SetSocks4Host(ipaddr_t a
);
550 /** Set socks4 server hostname to use. */
551 void SetSocks4Host(const std::string
& );
552 /** Socks4 server port to use. */
553 void SetSocks4Port(port_t p
);
554 /** Provide a socks4 userid if required by the socks4 server. */
555 void SetSocks4Userid(const std::string
& x
);
556 /** Get the ip address of socks4 server to use.
557 \return socks4 server host address */
558 ipaddr_t
GetSocks4Host();
559 /** Get the socks4 server port to use.
560 \return socks4 server port */
561 port_t
GetSocks4Port();
562 /** Get socks4 userid.
563 \return Socks4 userid */
564 const std::string
& GetSocks4Userid();
566 #endif // ENABLE_SOCKS4
568 #ifdef ENABLE_RESOLVER
569 /** \name Asynchronous Resolver */
571 /** Request an asynchronous dns resolution.
572 \param host hostname to be resolved
573 \param port port number passed along for the ride
574 \return Resolve ID */
575 int Resolve(const std::string
& host
,port_t port
= 0);
577 int Resolve6(const std::string
& host
, port_t port
= 0);
579 /** Callback returning a resolved address.
580 \param id Resolve ID from Resolve call
581 \param a resolved ip address
582 \param port port number passed to Resolve */
583 virtual void OnResolved(int id
,ipaddr_t a
,port_t port
);
585 virtual void OnResolved(int id
,in6_addr
& a
,port_t port
);
587 /** Request asynchronous reverse dns lookup.
588 \param a in_addr to be translated */
589 int Resolve(ipaddr_t a
);
591 int Resolve(in6_addr
& a
);
593 /** Callback returning reverse resolve results.
595 \param name Resolved hostname */
596 virtual void OnReverseResolved(int id
,const std::string
& name
);
597 /** Callback indicating failed dns lookup.
598 \param id Resolve ID */
599 virtual void OnResolveFailed(int id
);
601 #endif // ENABLE_RESOLVER
604 /** \name Thread Support */
606 /** Callback fires when a new socket thread has started and this
607 socket is ready for operation again.
609 virtual void OnDetached();
614 void SetDetach(bool x
= true);
615 /** Check detach flag.
616 \return true if the socket should detach to its own thread */
620 void SetDetached(bool x
= true);
621 /** Check detached flag.
622 \return true if the socket runs in its own thread. */
623 const bool IsDetached() const;
624 /** Order this socket to start its own thread and call OnDetached
625 when ready for operation. */
627 /** Store the slave sockethandler pointer. */
628 void SetSlaveHandler(ISocketHandler
*);
629 /** Create new thread for this socket to run detached in. */
632 #endif // ENABLE_DETACH
634 /** Write traffic to an IFile. Socket will not delete this object. */
635 void SetTrafficMonitor(IFile
*p
) { m_traffic_monitor
= p
; }
637 #ifdef ENABLE_TRIGGERS
638 /** \name Triggers */
640 /** Subscribe to trigger id. */
641 void Subscribe(int id
);
642 /** Unsubscribe from trigger id. */
643 void Unsubscribe(int id
);
644 /** Trigger callback, with data passed from source to destination. */
645 virtual void OnTrigger(int id
, const TriggerData
& data
);
646 /** Trigger cancelled because source has been deleted (as in delete). */
647 virtual void OnCancelled(int id
);
652 /** default constructor not available */
653 Socket() : m_handler(m_handler
) {}
654 /** copy constructor not available */
655 Socket(const Socket
& s
) : m_handler(s
.m_handler
) {}
657 /** assignment operator not available. */
658 Socket
& operator=(const Socket
& ) { return *this; }
660 /** All traffic will be written to this IFile, if set. */
661 IFile
*GetTrafficMonitor() { return m_traffic_monitor
; }
663 // unsigned long m_flags; ///< boolean flags, replacing old 'bool' members
666 ISocketHandler
& m_handler
; ///< Reference of ISocketHandler in control of this socket
667 SOCKET m_socket
; ///< File descriptor
668 bool m_bDel
; ///< Delete by handler flag
669 bool m_bClose
; ///< Close and delete flag
670 time_t m_tCreate
; ///< Time in seconds when this socket was created
671 Socket
*m_parent
; ///< Pointer to ListenSocket class, valid for incoming sockets
672 bool m_b_disable_read
; ///< Disable checking for read events
673 bool m_connected
; ///< Socket is connected (tcp/udp)
674 bool m_b_erased_by_handler
; ///< Set by handler before delete
675 time_t m_tClose
; ///< Time in seconds when ordered to close
676 std::auto_ptr
<SocketAddress
> m_client_remote_address
; ///< Address of last connect()
677 std::auto_ptr
<SocketAddress
> m_remote_address
; ///< Remote end address
678 IFile
*m_traffic_monitor
;
679 time_t m_timeout_start
; ///< Set by SetTimeout
680 time_t m_timeout_limit
; ///< Defined by SetTimeout
683 static WSAInitializer m_winsock_init
; ///< Winsock initialization singleton class
687 bool m_b_enable_ssl
; ///< Enable SSL for this TcpSocket
688 bool m_b_ssl
; ///< ssl negotiation mode (TcpSocket)
689 bool m_b_ssl_server
; ///< True if this is an incoming ssl TcpSocket connection
693 bool m_ipv6
; ///< This is an ipv6 socket if this one is true
697 int m_socket_type
; ///< Type of socket, from socket() call
698 std::string m_socket_protocol
; ///< Protocol, from socket() call
699 bool m_bClient
; ///< only client connections are pooled
700 bool m_bRetain
; ///< keep connection on close
701 bool m_bLost
; ///< connection lost
705 bool m_bSocks4
; ///< socks4 negotiation mode (TcpSocket)
706 ipaddr_t m_socks4_host
; ///< socks4 server address
707 port_t m_socks4_port
; ///< socks4 server port number
708 std::string m_socks4_userid
; ///< socks4 server usedid
712 bool m_detach
; ///< Socket ordered to detach flag
713 bool m_detached
; ///< Socket has been detached
714 SocketThread
*m_pThread
; ///< Detach socket thread class pointer
715 ISocketHandler
*m_slave_handler
; ///< Actual sockethandler while detached
719 #ifdef SOCKETS_NAMESPACE
724 #endif // _SOCKETS_Socket_H