1 /** \file SocketHandler.h
3 ** \author grymse@alhem.net
6 Copyright (C) 2004-2007 Anders Hedstrom
8 This library 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_SocketHandler_H
31 #define _SOCKETS_SocketHandler_H
33 #include "sockets-config.h"
37 #include "socket_include.h"
40 #include "ISocketHandler.h"
42 #ifdef SOCKETS_NAMESPACE
43 namespace SOCKETS_NAMESPACE
{
48 #ifdef ENABLE_RESOLVER
53 /** Socket container class, event generator.
55 class SocketHandler
: public ISocketHandler
58 /** Map type for holding file descriptors/socket object pointers. */
59 typedef std::map
<SOCKET
,Socket
*> socket_m
;
62 /** SocketHandler constructor.
63 \param log Optional log class pointer */
64 SocketHandler(StdLog
*log
= NULL
);
66 /** SocketHandler threadsafe constructor.
67 \param mutex Externally declared mutex variable
68 \param log Optional log class pointer */
69 SocketHandler(Mutex
& mutex
,StdLog
*log
= NULL
);
73 /** Get mutex reference for threadsafe operations. */
74 Mutex
& GetMutex() const;
76 /** Register StdLog object for error callback.
77 \param log Pointer to log class */
78 void RegStdLog(StdLog
*log
);
80 /** Log error to log class for print out / storage. */
81 void LogError(Socket
*p
,const std::string
& user_text
,int err
,const std::string
& sys_err
,loglevel_t t
= LOG_LEVEL_WARNING
);
83 /** Add socket instance to socket map. Removal is always automatic. */
86 /** Get status of read/write/exception file descriptor set for a socket. */
87 void Get(SOCKET s
,bool& r
,bool& w
,bool& e
);
89 /** Set read/write/exception file descriptor sets (fd_set). */
90 void Set(SOCKET s
,bool bRead
,bool bWrite
,bool bException
= true);
92 /** Wait for events, generate callbacks. */
93 int Select(long sec
,long usec
);
95 /** This method will not return until an event has been detected. */
98 /** Wait for events, generate callbacks. */
99 int Select(struct timeval
*tsel
);
101 /** Check that a socket really is handled by this socket handler. */
102 bool Valid(Socket
*);
104 /** Return number of sockets handled by this handler. */
107 /** Override and return false to deny all incoming connections.
108 \param p ListenSocket class pointer (use GetPort to identify which one) */
109 bool OkToAccept(Socket
*p
);
111 /** Called by Socket when a socket changes state. */
112 void AddList(SOCKET s
,list_t which_one
,bool add
);
116 /** Find available open connection (used by connection pool). */
117 ISocketHandler::PoolSocket
*FindConnection(int type
,const std::string
& protocol
,SocketAddress
&);
118 /** Enable connection pool (by default disabled). */
119 void EnablePool(bool x
= true);
120 /** Check pool status.
121 \return true if connection pool is enabled */
123 #endif // ENABLE_POOL
127 /** Set socks4 server ip that all new tcp sockets should use. */
128 void SetSocks4Host(ipaddr_t
);
129 /** Set socks4 server hostname that all new tcp sockets should use. */
130 void SetSocks4Host(const std::string
& );
131 /** Set socks4 server port number that all new tcp sockets should use. */
132 void SetSocks4Port(port_t
);
133 /** Set optional socks4 userid. */
134 void SetSocks4Userid(const std::string
& );
135 /** If connection to socks4 server fails, immediately try direct connection to final host. */
136 void SetSocks4TryDirect(bool x
= true);
137 /** Get socks4 server ip.
138 \return socks4 server ip */
139 ipaddr_t
GetSocks4Host();
140 /** Get socks4 port number.
141 \return socks4 port number */
142 port_t
GetSocks4Port();
143 /** Get socks4 userid (optional).
144 \return socks4 userid */
145 const std::string
& GetSocks4Userid();
146 /** Check status of socks4 try direct flag.
147 \return true if direct connection should be tried if connection to socks4 server fails */
148 bool Socks4TryDirect();
149 #endif // ENABLE_SOCKS4
151 // DNS resolve server
152 #ifdef ENABLE_RESOLVER
153 /** Enable asynchronous DNS.
154 \param port Listen port of asynchronous dns server */
155 void EnableResolver(port_t port
= 16667);
156 /** Check resolver status.
157 \return true if resolver is enabled */
158 bool ResolverEnabled();
159 /** Queue a dns request.
160 \param host Hostname to be resolved
161 \param port Port number will be echoed in Socket::OnResolved callback */
162 int Resolve(Socket
*,const std::string
& host
,port_t port
);
164 int Resolve6(Socket
*,const std::string
& host
,port_t port
);
166 /** Do a reverse dns lookup. */
167 int Resolve(Socket
*,ipaddr_t a
);
169 int Resolve(Socket
*,in6_addr
& a
);
171 /** Get listen port of asynchronous dns server. */
172 port_t
GetResolverPort();
173 /** Resolver thread ready for queries. */
174 bool ResolverReady();
175 #endif // ENABLE_RESOLVER
177 #ifdef ENABLE_TRIGGERS
178 /** Fetch unique trigger id. */
179 int TriggerID(Socket
*src
);
180 /** Subscribe socket to trigger id. */
181 bool Subscribe(int id
, Socket
*dst
);
182 /** Unsubscribe socket from trigger id. */
183 bool Unsubscribe(int id
, Socket
*dst
);
184 /** Execute OnTrigger for subscribed sockets.
186 \param data Data passed from source to destination
187 \param erase Empty trigger id source and destination maps if 'true',
188 Leave them in place if 'false' - if a trigger should be called many times */
189 void Trigger(int id
, Socket::TriggerData
& data
, bool erase
= true);
190 #endif // ENABLE_TRIGGERS
193 /** Indicates that the handler runs under SocketThread. */
194 void SetSlave(bool x
= true);
195 /** Indicates that the handler runs under SocketThread. */
199 /** Sanity check of those accursed lists. */
203 socket_m m_sockets
; ///< Active sockets map
204 socket_m m_add
; ///< Sockets to be added to sockets map
205 std::list
<Socket
*> m_delete
; ///< Sockets to be deleted (failed when Add)
208 StdLog
*m_stdlog
; ///< Registered log class, or NULL
209 Mutex
& m_mutex
; ///< Thread safety mutex
210 bool m_b_use_mutex
; ///< Mutex correctly initialized
213 void CheckList(socket_v
&,const std::string
&); ///< Used by CheckSanity
214 /** Remove socket from socket map, used by Socket class. */
215 void Remove(Socket
*);
216 SOCKET m_maxsock
; ///< Highest file descriptor + 1 in active sockets list
217 fd_set m_rfds
; ///< file descriptor set monitored for read events
218 fd_set m_wfds
; ///< file descriptor set monitored for write events
219 fd_set m_efds
; ///< file descriptor set monitored for exceptions
220 int m_preverror
; ///< debug select() error
221 int m_errcnt
; ///< debug select() error
222 time_t m_tlast
; ///< timeout control
225 socket_v m_fds
; ///< Active file descriptor list
226 socket_v m_fds_erase
; ///< File descriptors that are to be erased from m_sockets
227 socket_v m_fds_callonconnect
; ///< checklist CallOnConnect
229 socket_v m_fds_detach
; ///< checklist Detach
231 socket_v m_fds_timeout
; ///< checklist timeout
232 socket_v m_fds_retry
; ///< checklist retry client connect
233 socket_v m_fds_close
; ///< checklist close and delete
236 ipaddr_t m_socks4_host
; ///< Socks4 server host ip
237 port_t m_socks4_port
; ///< Socks4 server port number
238 std::string m_socks4_userid
; ///< Socks4 userid
239 bool m_bTryDirect
; ///< Try direct connection if socks4 server fails
241 #ifdef ENABLE_RESOLVER
242 int m_resolv_id
; ///< Resolver id counter
243 ResolvServer
*m_resolver
; ///< Resolver thread pointer
244 port_t m_resolver_port
; ///< Resolver listen port
247 bool m_b_enable_pool
; ///< Connection pool enabled if true
249 #ifdef ENABLE_TRIGGERS
250 int m_next_trigger_id
; ///< Unique trigger id counter
251 std::map
<int, Socket
*> m_trigger_src
; ///< mapping trigger id to source socket
252 std::map
<int, std::map
<Socket
*, bool> > m_trigger_dst
; ///< mapping trigger id to destination sockets
255 bool m_slave
; ///< Indicates that this is a ISocketHandler run in SocketThread
260 #ifdef SOCKETS_NAMESPACE
264 #endif // _SOCKETS_SocketHandler_H