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"
43 #include "SocketAddress.h"
47 #ifdef SOCKETS_NAMESPACE
48 namespace SOCKETS_NAMESPACE
{
57 /** \defgroup basic Basic sockets */
58 /** Socket base class.
62 friend class ISocketHandler
;
64 /** Detached socket run thread.
66 class SocketThread
: public Thread
69 SocketThread(Socket
*p
);
75 Socket
*GetSocket() const { return m_socket
; }
76 SocketThread(const SocketThread
& s
) : m_socket(s
.GetSocket()) {}
77 SocketThread
& operator=(const SocketThread
& ) { return *this; }
80 #endif // ENABLE_DETACH
82 #ifdef ENABLE_TRIGGERS
84 /** Data pass class from source to destination. */
88 TriggerData() : m_src(NULL
) {}
89 virtual ~TriggerData() {}
91 Socket
*GetSource() const { return m_src
; }
92 void SetSource(Socket
*x
) { m_src
= x
; }
97 #endif // ENABLE_TRIGGERS
99 /** Socket mode flags. */
103 SOCK_DEL = 0x01, ///< Delete by handler flag
104 SOCK_CLOSE = 0x02, ///< Close and delete flag
105 SOCK_DISABLE_READ = 0x04, ///< Disable checking for read events
106 SOCK_CONNECTED = 0x08, ///< Socket is connected (tcp/udp)
108 SOCK_ERASED_BY_HANDLER = 0x10, ///< Set by handler before delete
110 SOCK_ENABLE_SSL = 0x20, ///< Enable SSL for this TcpSocket
111 SOCK_SSL = 0x40, ///< ssl negotiation mode (TcpSocket)
112 SOCK_SSL_SERVER = 0x80, ///< True if this is an incoming ssl TcpSocket connection
115 SOCK_IPV6 = 0x0100, ///< This is an ipv6 socket if this one is true
117 SOCK_CLIENT = 0x0200, ///< only client connections are pooled
118 SOCK_RETAIN = 0x0400, ///< keep connection on close
119 SOCK_LOST = 0x0800, ///< connection lost
122 SOCK_SOCKS4 = 0x1000, ///< socks4 negotiation mode (TcpSocket)
124 SOCK_DETACH = 0x2000, ///< Socket ordered to detach flag
125 SOCK_DETACHED = 0x4000, ///< Socket has been detached
127 STREAMSOCK_CONNECTING = 0x8000, ///< Flag indicating connection in progress
129 STREAMSOCK_FLUSH_BEFORE_CLOSE = 0x010000L, ///< Send all data before closing (default true)
130 STREAMSOCK_CALL_ON_CONNECT = 0x020000L, ///< OnConnect will be called next ISocketHandler cycle if true
131 STREAMSOCK_RETRY_CONNECT = 0x040000L, ///< Try another connection attempt next ISocketHandler cycle
132 STREAMSOCK_LINE_PROTOCOL = 0x080000L, ///< Line protocol mode flag
138 /** "Default" constructor */
139 Socket(ISocketHandler
&);
143 /** Socket class instantiation method. Used when a "non-standard" constructor
144 * needs to be used for the socket class. Note: the socket class still needs
145 * the "default" constructor with one ISocketHandler& as input parameter.
147 virtual Socket
*Create() { return NULL
; }
149 /** Returns reference to sockethandler that owns the socket.
150 If the socket is detached, this is a reference to the slave sockethandler.
152 ISocketHandler
& Handler() const;
154 /** Returns reference to sockethandler that owns the socket.
155 This one always returns the reference to the original sockethandler,
156 even if the socket is detached.
158 ISocketHandler
& MasterHandler() const;
160 /** Called by ListenSocket after accept but before socket is added to handler.
161 * CTcpSocket uses this to create its ICrypt member variable.
162 * The ICrypt member variable is created by a virtual method, therefore
163 * it can't be called directly from the CTcpSocket constructor.
164 * Also used to determine if incoming HTTP connection is normal (port 80)
169 /** Create a socket file descriptor.
170 \param af Address family AF_INET / AF_INET6 / ...
171 \param type SOCK_STREAM / SOCK_DGRAM / ...
172 \param protocol "tcp" / "udp" / ... */
173 SOCKET
CreateSocket(int af
,int type
,const std::string
& protocol
= "");
175 /** Assign this socket a file descriptor created
176 by a call to socket() or otherwise. */
177 void Attach(SOCKET s
);
179 /** Return file descriptor assigned to this socket. */
182 /** Close connection immediately - internal use.
183 \sa SetCloseAndDelete */
186 /** Add file descriptor to sockethandler fd_set's. */
187 void Set(bool bRead
,bool bWrite
,bool bException
= true);
189 /** Returns true when socket file descriptor is valid
190 and socket is not about to be closed. */
191 virtual bool Ready();
193 /** Returns pointer to ListenSocket that created this instance
194 * on an incoming connection. */
197 /** Used by ListenSocket to set parent pointer of newly created
198 * socket instance. */
199 void SetParent(Socket
*);
201 /** Get listening port from ListenSocket<>. */
202 virtual port_t
GetPort();
204 /** Set socket non-block operation. */
205 bool SetNonblocking(bool);
207 /** Set socket non-block operation. */
208 bool SetNonblocking(bool, SOCKET
);
210 /** Total lifetime of instance. */
213 /** Set address/port of last connect() call. */
214 void SetClientRemoteAddress(SocketAddress
&);
216 /** Get address/port of last connect() call. */
217 std::auto_ptr
<SocketAddress
> GetClientRemoteAddress();
219 /** Common interface for SendBuf used by Tcp and Udp sockets. */
220 virtual void SendBuf(const char *,size_t,int = 0);
222 /** Common interface for Send used by Tcp and Udp sockets. */
223 virtual void Send(const std::string
&,int = 0);
225 /** Outgoing traffic counter. */
226 virtual uint64_t GetBytesSent(bool clear
= false);
228 /** Incoming traffic counter. */
229 virtual uint64_t GetBytesReceived(bool clear
= false);
233 /** Enable timeout control. 0=disable timeout check. */
234 void SetTimeout(time_t secs
);
236 /** Check timeout. \return true if time limit reached */
237 bool Timeout(time_t tnow
);
239 /** Used by ListenSocket. ipv4 and ipv6 */
240 void SetRemoteAddress(SocketAddress
&);
242 /** \name Event callbacks */
245 /** Called when there is something to be read from the file descriptor. */
246 virtual void OnRead();
247 /** Called when there is room for another write on the file descriptor. */
248 virtual void OnWrite();
249 /** Called on socket exception. */
250 virtual void OnException();
251 /** Called before a socket class is deleted by the ISocketHandler. */
252 virtual void OnDelete();
253 /** Called when a connection has completed. */
254 virtual void OnConnect();
255 /** Called when an incoming connection has been completed. */
256 virtual void OnAccept();
257 /** Called when a complete line has been read and the socket is in
258 * line protocol mode. */
259 virtual void OnLine(const std::string
& );
260 /** Called on connect timeout (5s). */
261 virtual void OnConnectFailed();
262 /** Called when a client socket is created, to set socket options.
263 \param family AF_INET, AF_INET6, etc
264 \param type SOCK_STREAM, SOCK_DGRAM, etc
265 \param protocol Protocol number (tcp, udp, sctp, etc)
266 \param s Socket file descriptor
268 virtual void OnOptions(int family
,int type
,int protocol
,SOCKET s
) = 0;
269 /** Connection retry callback - return false to abort connection attempts */
270 virtual bool OnConnectRetry();
271 #ifdef ENABLE_RECONNECT
272 /** a reconnect has been made */
273 virtual void OnReconnect();
275 /** TcpSocket: When a disconnect has been detected (recv/SSL_read returns 0 bytes). */
276 virtual void OnDisconnect();
277 /** Timeout callback. */
278 virtual void OnTimeout();
279 /** Connection timeout. */
280 virtual void OnConnectTimeout();
283 /** \name Socket mode flags, set/reset */
285 /** Set delete by handler true when you want the sockethandler to
286 delete the socket instance after use. */
287 void SetDeleteByHandler(bool = true);
288 /** Check delete by handler flag.
289 \return true if this instance should be deleted by the sockethandler */
290 bool DeleteByHandler();
292 // LIST_CLOSE - conditional event queue
294 /** Set close and delete to terminate the connection. */
295 void SetCloseAndDelete(bool = true);
296 /** Check close and delete flag.
297 \return true if this socket should be closed and the instance removed */
298 bool CloseAndDelete();
300 /** Return number of seconds since socket was ordered to close. \sa SetCloseAndDelete */
301 time_t TimeSinceClose();
303 /** Ignore read events for an output only socket. */
304 void DisableRead(bool x
= true);
305 /** Check ignore read events flag.
306 \return true if read events should be ignored */
307 bool IsDisableRead();
309 /** Set connected status. */
310 void SetConnected(bool = true);
311 /** Check connected status.
312 \return true if connected */
315 /** Set flag indicating the socket is being actively deleted by the sockethandler. */
316 void SetErasedByHandler(bool x
= true);
317 /** Get value of flag indicating socket is deleted by sockethandler. */
318 bool ErasedByHandler();
322 /** \name Information about remote connection */
324 /** Returns address of remote end. */
325 std::auto_ptr
<SocketAddress
> GetRemoteSocketAddress();
326 /** Returns address of remote end: ipv4. */
327 ipaddr_t
GetRemoteIP4();
329 /** Returns address of remote end: ipv6. */
331 struct in6_addr
GetRemoteIP6();
334 /** Returns remote port number: ipv4 and ipv6. */
335 port_t
GetRemotePort();
336 /** Returns remote ip as string? ipv4 and ipv6. */
337 std::string
GetRemoteAddress();
338 /** ipv4 and ipv6(not implemented) */
339 std::string
GetRemoteHostname();
342 /** Returns local port number for bound socket file descriptor. */
343 port_t
GetSockPort();
344 /** Returns local ipv4 address for bound socket file descriptor. */
345 ipaddr_t
GetSockIP4();
346 /** Returns local ipv4 address as text for bound socket file descriptor. */
347 std::string
GetSockAddress();
350 /** Returns local ipv6 address for bound socket file descriptor. */
351 struct in6_addr
GetSockIP6();
352 /** Returns local ipv6 address as text for bound socket file descriptor. */
353 std::string
GetSockAddress6();
356 // --------------------------------------------------------------------------
358 When an ip or socket option is available on all of the operating systems
359 I'm testing on (linux 2.4.x, _win32, macosx, solaris9 intel) they are not
360 checked with an #ifdef below.
361 This might cause a compile error on other operating systems. */
362 // --------------------------------------------------------------------------
367 bool SetIpOptions(const void *p
, socklen_t len
);
368 bool SetIpTOS(unsigned char tos
);
369 unsigned char IpTOS();
370 bool SetIpTTL(int ttl
);
372 bool SetIpHdrincl(bool x
= true);
373 bool SetIpMulticastTTL(int);
374 int IpMulticastTTL();
375 bool SetMulticastLoop(bool x
= true);
376 bool IpAddMembership(struct ip_mreq
&);
377 bool IpDropMembership(struct ip_mreq
&);
380 bool SetIpPktinfo(bool x
= true);
383 bool SetIpRecvTOS(bool x
= true);
386 bool SetIpRecvTTL(bool x
= true);
389 bool SetIpRecvopts(bool x
= true);
392 bool SetIpRetopts(bool x
= true);
395 bool SetIpRecverr(bool x
= true);
397 #ifdef IP_MTU_DISCOVER
398 bool SetIpMtudiscover(bool x
= true);
403 #ifdef IP_ROUTER_ALERT
404 bool SetIpRouterAlert(bool x
= true);
407 bool IpAddMembership(struct ip_mreqn
&);
410 bool IpDropMembership(struct ip_mreqn
&);
415 /** @name Socket Options */
419 bool SetSoBroadcast(bool x
= true);
420 bool SetSoDebug(bool x
= true);
422 bool SetSoDontroute(bool x
= true);
423 bool SetSoLinger(int onoff
, int linger
);
424 bool SetSoOobinline(bool x
= true);
425 bool SetSoRcvlowat(int);
426 bool SetSoSndlowat(int);
427 bool SetSoRcvtimeo(struct timeval
&);
428 bool SetSoSndtimeo(struct timeval
&);
429 bool SetSoRcvbuf(int);
431 bool SetSoSndbuf(int);
434 bool SetSoReuseaddr(bool x
= true);
435 bool SetSoKeepalive(bool x
= true);
438 bool SetSoBsdcompat(bool x
= true);
440 #ifdef SO_BINDTODEVICE
441 bool SetSoBindtodevice(const std::string
& intf
);
444 bool SetSoPasscred(bool x
= true);
447 bool SoPeercred(struct ucred
& );
450 bool SetSoPriority(int);
452 #ifdef SO_RCVBUFFORCE
453 bool SetSoRcvbufforce(int);
455 #ifdef SO_SNDBUFFORCE
456 bool SetSoSndbufforce(int);
459 bool SetSoTimestamp(bool x
= true);
462 bool SetSoNosigpipe(bool x
= true);
466 // TCP options in TcpSocket.h/TcpSocket.cpp
470 /** @name SSL Support */
472 /** SSL client/server support - internal use. \sa TcpSocket */
473 virtual void OnSSLConnect();
474 /** SSL client/server support - internal use. \sa TcpSocket */
475 virtual void OnSSLAccept();
476 /** SSL negotiation failed for client connect. */
477 virtual void OnSSLConnectFailed();
478 /** SSL negotiation failed for server accept. */
479 virtual void OnSSLAcceptFailed();
480 /** new SSL support */
481 virtual bool SSLNegotiate();
482 /** Check if SSL is Enabled for this TcpSocket.
483 \return true if this is a TcpSocket with SSL enabled */
485 /** Enable SSL operation for a TcpSocket. */
486 void EnableSSL(bool x
= true);
487 /** Still negotiating ssl connection.
488 \return true if ssl negotiating is still in progress */
489 bool IsSSLNegotiate();
490 /** Set flag indicating ssl handshaking still in progress. */
491 void SetSSLNegotiate(bool x
= true);
492 /** OnAccept called with SSL Enabled.
493 \return true if this is a TcpSocket with an incoming SSL connection */
495 /** Set flag indicating that this is a TcpSocket with incoming SSL connection. */
496 void SetSSLServer(bool x
= true);
497 /** SSL; Get pointer to ssl context structure. */
498 virtual SSL_CTX
*GetSslContext() { return NULL
; }
499 /** SSL; Get pointer to ssl structure. */
500 virtual SSL
*GetSsl() { return NULL
; }
502 #endif // HAVE_OPENSSL
505 /** Enable ipv6 for this socket. */
506 void SetIpv6(bool x
= true);
507 /** Check ipv6 socket.
508 \return true if this is an ipv6 socket */
513 /** @name Connection Pool */
515 /** Client = connecting TcpSocket. */
517 /** Socket type from socket() call. */
518 void SetSocketType(int x
);
519 /** Socket type from socket() call. */
521 /** Protocol type from socket() call. */
522 void SetSocketProtocol(const std::string
& x
);
523 /** Protocol type from socket() call. */
524 const std::string
& GetSocketProtocol();
525 /** Instruct a client socket to stay open in the connection pool after use.
526 If you have connected to a server using tcp, you can call SetRetain
527 to leave the connection open after your socket instance has been deleted.
528 The next connection you make to the same server will reuse the already
529 opened connection, if it is still available.
532 /** Check retain flag.
533 \return true if the socket should be moved to connection pool after use */
535 /** Connection lost - error while reading/writing from a socket - TcpSocket only. */
537 /** Check connection lost status flag, used by TcpSocket only.
538 \return true if there was an error while r/w causing the socket to close */
540 /** Copy connection parameters from sock. */
541 void CopyConnection(Socket
*sock
);
543 #endif // ENABLE_POOL
546 /** \name Socks4 support */
548 /** Socks4 client support internal use. \sa TcpSocket */
549 virtual void OnSocks4Connect();
550 /** Socks4 client support internal use. \sa TcpSocket */
551 virtual void OnSocks4ConnectFailed();
552 /** Socks4 client support internal use. \sa TcpSocket */
553 virtual bool OnSocks4Read();
554 /** Called when the last write caused the tcp output buffer to
556 /** socket still in socks4 negotiation mode */
558 /** Set flag indicating Socks4 handshaking in progress */
559 void SetSocks4(bool x
= true);
561 /** Set socks4 server host address to use */
562 void SetSocks4Host(ipaddr_t a
);
563 /** Set socks4 server hostname to use. */
564 void SetSocks4Host(const std::string
& );
565 /** Socks4 server port to use. */
566 void SetSocks4Port(port_t p
);
567 /** Provide a socks4 userid if required by the socks4 server. */
568 void SetSocks4Userid(const std::string
& x
);
569 /** Get the ip address of socks4 server to use.
570 \return socks4 server host address */
571 ipaddr_t
GetSocks4Host();
572 /** Get the socks4 server port to use.
573 \return socks4 server port */
574 port_t
GetSocks4Port();
575 /** Get socks4 userid.
576 \return Socks4 userid */
577 const std::string
& GetSocks4Userid();
579 #endif // ENABLE_SOCKS4
581 #ifdef ENABLE_RESOLVER
582 /** \name Asynchronous Resolver */
584 /** Request an asynchronous dns resolution.
585 \param host hostname to be resolved
586 \param port port number passed along for the ride
587 \return Resolve ID */
588 int Resolve(const std::string
& host
,port_t port
= 0);
590 int Resolve6(const std::string
& host
, port_t port
= 0);
592 /** Callback returning a resolved address.
593 \param id Resolve ID from Resolve call
594 \param a resolved ip address
595 \param port port number passed to Resolve */
596 virtual void OnResolved(int id
,ipaddr_t a
,port_t port
);
598 virtual void OnResolved(int id
,in6_addr
& a
,port_t port
);
600 /** Request asynchronous reverse dns lookup.
601 \param a in_addr to be translated */
602 int Resolve(ipaddr_t a
);
604 int Resolve(in6_addr
& a
);
606 /** Callback returning reverse resolve results.
608 \param name Resolved hostname */
609 virtual void OnReverseResolved(int id
,const std::string
& name
);
610 /** Callback indicating failed dns lookup.
611 \param id Resolve ID */
612 virtual void OnResolveFailed(int id
);
614 #endif // ENABLE_RESOLVER
617 /** \name Thread Support */
619 /** Callback fires when a new socket thread has started and this
620 socket is ready for operation again.
622 virtual void OnDetached();
627 void SetDetach(bool x
= true);
628 /** Check detach flag.
629 \return true if the socket should detach to its own thread */
633 void SetDetached(bool x
= true);
634 /** Check detached flag.
635 \return true if the socket runs in its own thread. */
636 const bool IsDetached() const;
637 /** Order this socket to start its own thread and call OnDetached
638 when ready for operation. */
640 /** Store the slave sockethandler pointer. */
641 void SetSlaveHandler(ISocketHandler
*);
642 /** Create new thread for this socket to run detached in. */
645 #endif // ENABLE_DETACH
647 /** Write traffic to an IFile. Socket will not delete this object. */
648 void SetTrafficMonitor(IFile
*p
) { m_traffic_monitor
= p
; }
650 #ifdef ENABLE_TRIGGERS
651 /** \name Triggers */
653 /** Subscribe to trigger id. */
654 void Subscribe(int id
);
655 /** Unsubscribe from trigger id. */
656 void Unsubscribe(int id
);
657 /** Trigger callback, with data passed from source to destination. */
658 virtual void OnTrigger(int id
, const TriggerData
& data
);
659 /** Trigger cancelled because source has been deleted (as in delete). */
660 virtual void OnCancelled(int id
);
665 /** default constructor not available */
666 Socket() : m_handler(m_handler
) {}
667 /** copy constructor not available */
668 Socket(const Socket
& s
) : m_handler(s
.m_handler
) {}
670 /** assignment operator not available. */
671 Socket
& operator=(const Socket
& ) { return *this; }
673 /** All traffic will be written to this IFile, if set. */
674 IFile
*GetTrafficMonitor() { return m_traffic_monitor
; }
676 // unsigned long m_flags; ///< boolean flags, replacing old 'bool' members
679 ISocketHandler
& m_handler
; ///< Reference of ISocketHandler in control of this socket
680 SOCKET m_socket
; ///< File descriptor
681 bool m_bDel
; ///< Delete by handler flag
682 bool m_bClose
; ///< Close and delete flag
683 time_t m_tCreate
; ///< Time in seconds when this socket was created
684 Socket
*m_parent
; ///< Pointer to ListenSocket class, valid for incoming sockets
685 bool m_b_disable_read
; ///< Disable checking for read events
686 bool m_connected
; ///< Socket is connected (tcp/udp)
687 bool m_b_erased_by_handler
; ///< Set by handler before delete
688 time_t m_tClose
; ///< Time in seconds when ordered to close
689 std::auto_ptr
<SocketAddress
> m_client_remote_address
; ///< Address of last connect()
690 std::auto_ptr
<SocketAddress
> m_remote_address
; ///< Remote end address
691 IFile
*m_traffic_monitor
;
692 time_t m_timeout_start
; ///< Set by SetTimeout
693 time_t m_timeout_limit
; ///< Defined by SetTimeout
696 static WSAInitializer m_winsock_init
; ///< Winsock initialization singleton class
700 bool m_b_enable_ssl
; ///< Enable SSL for this TcpSocket
701 bool m_b_ssl
; ///< ssl negotiation mode (TcpSocket)
702 bool m_b_ssl_server
; ///< True if this is an incoming ssl TcpSocket connection
706 bool m_ipv6
; ///< This is an ipv6 socket if this one is true
710 int m_socket_type
; ///< Type of socket, from socket() call
711 std::string m_socket_protocol
; ///< Protocol, from socket() call
712 bool m_bClient
; ///< only client connections are pooled
713 bool m_bRetain
; ///< keep connection on close
714 bool m_bLost
; ///< connection lost
718 bool m_bSocks4
; ///< socks4 negotiation mode (TcpSocket)
719 ipaddr_t m_socks4_host
; ///< socks4 server address
720 port_t m_socks4_port
; ///< socks4 server port number
721 std::string m_socks4_userid
; ///< socks4 server usedid
725 bool m_detach
; ///< Socket ordered to detach flag
726 bool m_detached
; ///< Socket has been detached
727 SocketThread
*m_pThread
; ///< Detach socket thread class pointer
728 ISocketHandler
*m_slave_handler
; ///< Actual sockethandler while detached
732 #ifdef SOCKETS_NAMESPACE
737 #endif // _SOCKETS_Socket_H