![]() |
SocketHandler Class ReferenceSocket container class, event generator.
More...
|
Public Member Functions | |
SocketHandler (StdLog *log=NULL) | |
SocketHandler constructor. | |
SocketHandler (IMutex &mutex, StdLog *log=NULL) | |
SocketHandler threadsafe constructor. | |
SocketHandler (IMutex &, ISocketHandler &parent, StdLog *=NULL) | |
~SocketHandler () | |
virtual ISocketHandler * | Create (StdLog *=NULL) |
Return another instance. | |
virtual ISocketHandler * | Create (IMutex &, ISocketHandler &, StdLog *=NULL) |
Return another instance. | |
virtual bool | ParentHandlerIsValid () |
Handler created with parent. | |
virtual ISocketHandler & | ParentHandler () |
Get parent sockethandler. | |
virtual ISocketHandler & | GetRandomHandler () |
Get thread handler with least connections. | |
virtual ISocketHandler & | GetEffectiveHandler () |
Return parent handler if valid, otherwise return normal handler. | |
virtual void | SetNumberOfThreads (size_t n) |
Enable threading. | |
virtual bool | IsThreaded () |
Threading is enabled. | |
virtual void | EnableRelease () |
Enable select release. | |
virtual void | Release () |
Make select release. | |
IMutex & | GetMutex () const |
Get mutex reference for threadsafe operations. | |
void | RegStdLog (StdLog *log) |
Register StdLog object for error callback. | |
void | LogError (Socket *p, const std::string &user_text, int err, const std::string &sys_err, loglevel_t t=LOG_LEVEL_WARNING) |
Log error to log class for print out / storage. | |
void | Add (Socket *) |
Add socket instance to socket map. | |
void | ISocketHandler_Add (Socket *, bool bRead, bool bWrite) |
Set read/write/exception file descriptor sets (fd_set). | |
void | ISocketHandler_Mod (Socket *, bool bRead, bool bWrite) |
void | ISocketHandler_Del (Socket *) |
int | Select (long sec, long usec) |
Wait for events, generate callbacks. | |
int | Select () |
This method will not return until an event has been detected. | |
int | Select (struct timeval *tsel) |
Wait for events, generate callbacks. | |
bool | Valid (Socket *) |
Check that a socket really is handled by this socket handler. | |
bool | Valid (socketuid_t) |
Preferred method - Check that a socket still is handled by this socket handler. | |
size_t | GetCount () |
Return number of sockets handled by this handler. | |
size_t | MaxCount () |
Return maximum number of sockets allowed. | |
bool | OkToAccept (Socket *p) |
Override and return false to deny all incoming connections. | |
const std::map< SOCKET, Socket * > & | AllSockets () |
Use with care, always lock with h.GetMutex() if multithreaded. | |
size_t | MaxTcpLineSize () |
Override to accept longer lines than TCP_LINE_SIZE. | |
void | SetCallOnConnect (bool=true) |
void | SetDetach (bool=true) |
void | SetTimeout (bool=true) |
void | SetRetry (bool=true) |
void | SetClose (bool=true) |
ISocketHandler::PoolSocket * | FindConnection (int type, const std::string &protocol, SocketAddress &) |
Find available open connection (used by connection pool). | |
void | EnablePool (bool x=true) |
Enable connection pool (by default disabled). | |
bool | PoolEnabled () |
Check pool status. | |
void | SetSocks4Host (ipaddr_t) |
Set socks4 server ip that all new tcp sockets should use. | |
void | SetSocks4Host (const std::string &) |
Set socks4 server hostname that all new tcp sockets should use. | |
void | SetSocks4Port (port_t) |
Set socks4 server port number that all new tcp sockets should use. | |
void | SetSocks4Userid (const std::string &) |
Set optional socks4 userid. | |
void | SetSocks4TryDirect (bool x=true) |
If connection to socks4 server fails, immediately try direct connection to final host. | |
ipaddr_t | GetSocks4Host () |
Get socks4 server ip. | |
port_t | GetSocks4Port () |
Get socks4 port number. | |
const std::string & | GetSocks4Userid () |
Get socks4 userid (optional). | |
bool | Socks4TryDirect () |
Check status of socks4 try direct flag. | |
void | EnableResolver (port_t port=16667) |
Enable asynchronous DNS. | |
bool | ResolverEnabled () |
Check resolver status. | |
int | Resolve (Socket *, const std::string &host, port_t port) |
Queue a dns request. | |
int | Resolve (Socket *, ipaddr_t a) |
Do a reverse dns lookup. | |
port_t | GetResolverPort () |
Get listen port of asynchronous dns server. | |
bool | ResolverReady () |
Resolver thread ready for queries. | |
bool | Resolving (Socket *) |
Returns true if the socket is waiting for a resolve event. | |
void | SetSlave (bool x=true) |
Indicates that the handler runs under SocketThread. | |
bool | IsSlave () |
Indicates that the handler runs under SocketThread. | |
Protected Types | |
typedef std::map< SOCKET, Socket * > | socket_m |
Map type for holding file descriptors/socket object pointers. | |
Protected Member Functions | |
int | ISocketHandler_Select (struct timeval *) |
Actual call to select(). | |
void | Remove (Socket *) |
Remove socket from socket map, used by Socket class. | |
void | DeleteSocket (Socket *) |
Schedule socket for deletion. | |
void | AddIncoming () |
void | CheckErasedSockets () |
void | CheckCallOnConnect () |
void | CheckDetach () |
void | CheckTimeout (time_t) |
void | CheckRetry () |
void | CheckClose () |
Protected Attributes | |
socket_m | m_sockets |
Active sockets map. | |
std::list< Socket * > | m_add |
Sockets to be added to sockets map. | |
std::list< Socket * > | m_delete |
Sockets to be deleted (failed when Add). | |
StdLog * | m_stdlog |
Registered log class, or NULL. | |
IMutex & | m_mutex |
Thread safety mutex. | |
bool | m_b_use_mutex |
Mutex correctly initialized. | |
ISocketHandler & | m_parent |
bool | m_b_parent_is_valid |
Private Member Functions | |
void | RebuildFdset () |
void | Set (Socket *, bool, bool) |
Private Attributes | |
std::list< SocketHandlerThread * > | m_threads |
UdpSocket * | m_release |
SOCKET | m_maxsock |
Highest file descriptor + 1 in active sockets list. | |
fd_set | m_rfds |
file descriptor set monitored for read events | |
fd_set | m_wfds |
file descriptor set monitored for write events | |
fd_set | m_efds |
file descriptor set monitored for exceptions | |
time_t | m_tlast |
timeout control | |
std::list< socketuid_t > | m_fds_erase |
File descriptors that are to be erased from m_sockets. | |
bool | m_b_check_callonconnect |
bool | m_b_check_detach |
bool | m_b_check_timeout |
bool | m_b_check_retry |
bool | m_b_check_close |
ipaddr_t | m_socks4_host |
Socks4 server host ip. | |
port_t | m_socks4_port |
Socks4 server port number. | |
std::string | m_socks4_userid |
Socks4 userid. | |
bool | m_bTryDirect |
Try direct connection if socks4 server fails. | |
int | m_resolv_id |
Resolver id counter. | |
ResolvServer * | m_resolver |
Resolver thread pointer. | |
port_t | m_resolver_port |
Resolver listen port. | |
std::map< socketuid_t, bool > | m_resolve_q |
resolve queue | |
bool | m_b_enable_pool |
Connection pool enabled if true. | |
bool | m_slave |
Indicates that this is a ISocketHandler run in SocketThread. | |
Static Private Attributes | |
static FILE * | m_event_file |
static unsigned long | m_event_counter |
Definition at line 57 of file SocketHandler.h.
typedef std::map<SOCKET,Socket *> SocketHandler::socket_m [protected] |
Map type for holding file descriptors/socket object pointers.
Definition at line 61 of file SocketHandler.h.
SocketHandler::SocketHandler | ( | StdLog * | log = NULL |
) |
SocketHandler constructor.
log | Optional log class pointer |
Definition at line 64 of file SocketHandler.cpp.
References m_efds, m_rfds, and m_wfds.
Referenced by Create().
00065 :m_stdlog(p) 00066 ,m_mutex(m_mutex) 00067 ,m_b_use_mutex(false) 00068 ,m_parent(m_parent) 00069 ,m_b_parent_is_valid(false) 00070 ,m_release(NULL) 00071 ,m_maxsock(0) 00072 ,m_tlast(0) 00073 ,m_b_check_callonconnect(false) 00074 ,m_b_check_detach(false) 00075 ,m_b_check_timeout(false) 00076 ,m_b_check_retry(false) 00077 ,m_b_check_close(false) 00078 #ifdef ENABLE_SOCKS4 00079 ,m_socks4_host(0) 00080 ,m_socks4_port(0) 00081 ,m_bTryDirect(false) 00082 #endif 00083 #ifdef ENABLE_RESOLVER 00084 ,m_resolv_id(0) 00085 ,m_resolver(NULL) 00086 #endif 00087 #ifdef ENABLE_POOL 00088 ,m_b_enable_pool(false) 00089 #endif 00090 #ifdef ENABLE_DETACH 00091 ,m_slave(false) 00092 #endif 00093 { 00094 FD_ZERO(&m_rfds); 00095 FD_ZERO(&m_wfds); 00096 FD_ZERO(&m_efds); 00097 }
SocketHandler threadsafe constructor.
mutex | Externally declared mutex variable | |
log | Optional log class pointer |
Definition at line 100 of file SocketHandler.cpp.
References IMutex::Lock(), m_efds, m_mutex, m_rfds, and m_wfds.
00101 :m_stdlog(p) 00102 ,m_mutex(mutex) 00103 ,m_b_use_mutex(true) 00104 ,m_parent(m_parent) 00105 ,m_b_parent_is_valid(false) 00106 ,m_release(NULL) 00107 ,m_maxsock(0) 00108 ,m_tlast(0) 00109 ,m_b_check_callonconnect(false) 00110 ,m_b_check_detach(false) 00111 ,m_b_check_timeout(false) 00112 ,m_b_check_retry(false) 00113 ,m_b_check_close(false) 00114 #ifdef ENABLE_SOCKS4 00115 ,m_socks4_host(0) 00116 ,m_socks4_port(0) 00117 ,m_bTryDirect(false) 00118 #endif 00119 #ifdef ENABLE_RESOLVER 00120 ,m_resolv_id(0) 00121 ,m_resolver(NULL) 00122 #endif 00123 #ifdef ENABLE_POOL 00124 ,m_b_enable_pool(false) 00125 #endif 00126 #ifdef ENABLE_DETACH 00127 ,m_slave(false) 00128 #endif 00129 { 00130 m_mutex.Lock(); 00131 FD_ZERO(&m_rfds); 00132 FD_ZERO(&m_wfds); 00133 FD_ZERO(&m_efds); 00134 }
SocketHandler::SocketHandler | ( | IMutex & | mutex, | |
ISocketHandler & | parent, | |||
StdLog * | p = NULL | |||
) |
Definition at line 137 of file SocketHandler.cpp.
References IMutex::Lock(), m_efds, m_mutex, m_rfds, and m_wfds.
00138 :m_stdlog(p) 00139 ,m_mutex(mutex) 00140 ,m_b_use_mutex(true) 00141 ,m_parent(parent) 00142 ,m_b_parent_is_valid(true) 00143 ,m_release(NULL) 00144 ,m_maxsock(0) 00145 ,m_tlast(0) 00146 ,m_b_check_callonconnect(false) 00147 ,m_b_check_detach(false) 00148 ,m_b_check_timeout(false) 00149 ,m_b_check_retry(false) 00150 ,m_b_check_close(false) 00151 #ifdef ENABLE_SOCKS4 00152 ,m_socks4_host(0) 00153 ,m_socks4_port(0) 00154 ,m_bTryDirect(false) 00155 #endif 00156 #ifdef ENABLE_RESOLVER 00157 ,m_resolv_id(0) 00158 ,m_resolver(NULL) 00159 #endif 00160 #ifdef ENABLE_POOL 00161 ,m_b_enable_pool(false) 00162 #endif 00163 #ifdef ENABLE_DETACH 00164 ,m_slave(false) 00165 #endif 00166 { 00167 m_mutex.Lock(); 00168 FD_ZERO(&m_rfds); 00169 FD_ZERO(&m_wfds); 00170 FD_ZERO(&m_efds); 00171 }
SocketHandler::~SocketHandler | ( | ) |
Definition at line 174 of file SocketHandler.cpp.
References DEB, ENABLE_DETACH, ENABLE_RESOLVER, m_b_use_mutex, m_mutex, m_resolver, m_slave, m_sockets, m_threads, and IMutex::Unlock().
00175 { 00176 for (std::list<SocketHandlerThread *>::iterator it = m_threads.begin(); it != m_threads.end(); ++it) 00177 { 00178 SocketHandlerThread *p = *it; 00179 p -> Stop(); 00180 } 00181 #ifdef ENABLE_RESOLVER 00182 if (m_resolver) 00183 { 00184 m_resolver -> Quit(); 00185 } 00186 #endif 00187 { 00188 while (m_sockets.size()) 00189 { 00190 DEB( fprintf(stderr, "Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) 00191 socket_m::iterator it = m_sockets.begin(); 00192 Socket *p = it -> second; 00193 if (p) 00194 { 00195 DEB( fprintf(stderr, " fd %d\n", p -> GetSocket());) 00196 p -> Close(); 00197 DEB( fprintf(stderr, " fd closed %d\n", p -> GetSocket());) 00198 // p -> OnDelete(); // hey, I turn this back on. what's the worst that could happen??!! 00199 // MinionSocket breaks, calling MinderHandler methods in OnDelete - 00200 // MinderHandler is already gone when that happens... 00201 00202 // only delete socket when controlled 00203 // ie master sockethandler can delete non-detached sockets 00204 // and a slave sockethandler can only delete a detach socket 00205 if (p -> DeleteByHandler() 00206 #ifdef ENABLE_DETACH 00207 && !(m_slave ^ p -> IsDetached()) 00208 #endif 00209 ) 00210 { 00211 p -> SetErasedByHandler(); 00212 delete p; 00213 } 00214 m_sockets.erase(it); 00215 } 00216 else 00217 { 00218 m_sockets.erase(it); 00219 } 00220 DEB( fprintf(stderr, "next\n");) 00221 } 00222 DEB( fprintf(stderr, "/Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) 00223 } 00224 #ifdef ENABLE_RESOLVER 00225 if (m_resolver) 00226 { 00227 delete m_resolver; 00228 } 00229 #endif 00230 if (m_b_use_mutex) 00231 { 00232 m_mutex.Unlock(); 00233 } 00234 }
ISocketHandler * SocketHandler::Create | ( | StdLog * | = NULL |
) | [virtual] |
Return another instance.
Implements ISocketHandler.
Reimplemented in SocketHandlerEp.
Definition at line 237 of file SocketHandler.cpp.
References SocketHandler().
00238 { 00239 return new SocketHandler(log); 00240 }
ISocketHandler * SocketHandler::Create | ( | IMutex & | , | |
ISocketHandler & | , | |||
StdLog * | = NULL | |||
) | [virtual] |
Return another instance.
Implements ISocketHandler.
Reimplemented in SocketHandlerEp.
Definition at line 243 of file SocketHandler.cpp.
References SocketHandler().
00244 { 00245 return new SocketHandler(mutex, parent, log); 00246 }
bool SocketHandler::ParentHandlerIsValid | ( | ) | [virtual] |
Handler created with parent.
Implements ISocketHandler.
Definition at line 249 of file SocketHandler.cpp.
References m_b_parent_is_valid.
00250 { 00251 return m_b_parent_is_valid; 00252 }
ISocketHandler & SocketHandler::ParentHandler | ( | ) | [virtual] |
Get parent sockethandler.
Implements ISocketHandler.
Definition at line 255 of file SocketHandler.cpp.
References m_b_parent_is_valid, and m_parent.
00256 { 00257 if (!m_b_parent_is_valid) 00258 throw Exception("No parent sockethandler available"); 00259 return m_parent; 00260 }
ISocketHandler & SocketHandler::GetRandomHandler | ( | ) | [virtual] |
Get thread handler with least connections.
Implements ISocketHandler.
Definition at line 263 of file SocketHandler.cpp.
References ISocketHandler::GetCount(), ISocketHandler::GetMutex(), and m_threads.
00264 { 00265 if (m_threads.empty()) 00266 throw Exception("SocketHandler is not multithreaded"); 00267 size_t min_count = 99999; 00268 SocketHandlerThread *match = NULL; 00269 for (std::list<SocketHandlerThread *>::iterator it = m_threads.begin(); it != m_threads.end(); ++it) 00270 { 00271 SocketHandlerThread *thr = *it; 00272 ISocketHandler& h = thr -> Handler(); 00273 { 00274 Lock lock(h.GetMutex()); 00275 size_t sz = h.GetCount(); 00276 if (sz < min_count) 00277 { 00278 min_count = sz; 00279 match = thr; 00280 } 00281 } 00282 } 00283 if (match) 00284 return match -> Handler(); 00285 throw Exception("Can't locate free threaded sockethandler"); 00286 }
ISocketHandler & SocketHandler::GetEffectiveHandler | ( | ) | [virtual] |
Return parent handler if valid, otherwise return normal handler.
Implements ISocketHandler.
Definition at line 289 of file SocketHandler.cpp.
References m_b_parent_is_valid, and m_parent.
00290 { 00291 return m_b_parent_is_valid ? m_parent : *this; 00292 }
void SocketHandler::SetNumberOfThreads | ( | size_t | n | ) | [virtual] |
Enable threading.
Implements ISocketHandler.
Definition at line 295 of file SocketHandler.cpp.
References m_threads.
00296 { 00297 if (!m_threads.empty()) 00298 { 00299 return; // already set 00300 } 00301 if (n > 1 && n < 256) 00302 { 00303 for (int i = 1; i <= (int)n; i++) 00304 { 00305 SocketHandlerThread *p = new SocketHandlerThread(*this); 00306 m_threads.push_back(p); 00307 p -> SetDeleteOnExit(); 00308 p -> Start(); 00309 p -> Wait(); 00310 } 00311 } 00312 }
bool SocketHandler::IsThreaded | ( | ) | [virtual] |
Threading is enabled.
Implements ISocketHandler.
Definition at line 315 of file SocketHandler.cpp.
References m_threads.
00316 { 00317 return !m_threads.empty(); 00318 }
void SocketHandler::EnableRelease | ( | ) | [virtual] |
Enable select release.
Implements ISocketHandler.
Definition at line 321 of file SocketHandler.cpp.
References Add(), and m_release.
Referenced by EventHandler::EventHandler(), and SocketThread::Run().
00322 { 00323 if (m_release) 00324 return; 00325 m_release = new UdpSocket(*this); 00326 m_release -> SetDeleteByHandler(); 00327 port_t port = 0; 00328 m_release -> Bind("127.0.0.1", port); 00329 Add(m_release); 00330 }
void SocketHandler::Release | ( | ) | [virtual] |
Make select release.
Implements ISocketHandler.
Definition at line 333 of file SocketHandler.cpp.
References m_release.
Referenced by EventHandler::AddEvent(), and SocketThread::~SocketThread().
00334 { 00335 if (!m_release) 00336 return; 00337 m_release -> SendTo("127.0.0.1", m_release -> GetPort(), "\n"); 00338 }
IMutex & SocketHandler::GetMutex | ( | ) | const [virtual] |
Get mutex reference for threadsafe operations.
Implements ISocketHandler.
Definition at line 341 of file SocketHandler.cpp.
References m_mutex.
00342 { 00343 return m_mutex; 00344 }
void SocketHandler::RegStdLog | ( | StdLog * | log | ) | [virtual] |
Register StdLog object for error callback.
log | Pointer to log class |
Implements ISocketHandler.
Definition at line 361 of file SocketHandler.cpp.
References m_stdlog.
00362 { 00363 m_stdlog = log; 00364 }
void SocketHandler::LogError | ( | Socket * | p, | |
const std::string & | user_text, | |||
int | err, | |||
const std::string & | sys_err, | |||
loglevel_t | t = LOG_LEVEL_WARNING | |||
) | [virtual] |
Log error to log class for print out / storage.
Implements ISocketHandler.
Definition at line 367 of file SocketHandler.cpp.
References m_stdlog.
Referenced by AddIncoming(), CheckClose(), CheckRetry(), ISocketHandler_Select(), RebuildFdset(), Remove(), and Resolve().
00368 { 00369 if (m_stdlog) 00370 { 00371 m_stdlog -> error(this, p, user_text, err, sys_err, t); 00372 } 00373 }
void SocketHandler::Add | ( | Socket * | p | ) | [virtual] |
Add socket instance to socket map.
Removal is always automatic.
Implements ISocketHandler.
Reimplemented in EventHandler.
Definition at line 376 of file SocketHandler.cpp.
References m_add.
Referenced by EventHandler::Add(), CheckClose(), CheckRetry(), EnableRelease(), Resolve(), SocketThread::Run(), and ResolvServer::Run().
00377 { 00378 m_add.push_back(p); // no checks here 00379 }
void SocketHandler::ISocketHandler_Add | ( | Socket * | p, | |
bool | bRead, | |||
bool | bWrite | |||
) | [virtual] |
Set read/write/exception file descriptor sets (fd_set).
Implements ISocketHandler.
Definition at line 382 of file SocketHandler.cpp.
References Set().
Referenced by AddIncoming().
00383 { 00384 Set(p, bRead, bWrite); 00385 }
void SocketHandler::ISocketHandler_Mod | ( | Socket * | p, | |
bool | bRead, | |||
bool | bWrite | |||
) | [virtual] |
Implements ISocketHandler.
Definition at line 388 of file SocketHandler.cpp.
References Set().
00389 { 00390 Set(p, bRead, bWrite); 00391 }
void SocketHandler::ISocketHandler_Del | ( | Socket * | p | ) | [virtual] |
Implements ISocketHandler.
Definition at line 394 of file SocketHandler.cpp.
References Set().
Referenced by CheckClose(), and CheckDetach().
00395 { 00396 Set(p, false, false); 00397 }
int SocketHandler::Select | ( | long | sec, | |
long | usec | |||
) | [virtual] |
Wait for events, generate callbacks.
Implements ISocketHandler.
Definition at line 1354 of file SocketHandler.cpp.
References Select().
Referenced by SocketThread::Run(), and ResolvServer::Run().
01355 { 01356 struct timeval tv; 01357 tv.tv_sec = sec; 01358 tv.tv_usec = usec; 01359 return Select(&tv); 01360 }
int SocketHandler::Select | ( | ) | [virtual] |
This method will not return until an event has been detected.
Implements ISocketHandler.
Definition at line 1363 of file SocketHandler.cpp.
References m_b_check_callonconnect, m_b_check_close, m_b_check_detach, m_b_check_retry, and m_b_check_timeout.
Referenced by EventHandler::EventLoop(), and Select().
01364 { 01365 if (m_b_check_callonconnect || 01366 m_b_check_detach || 01367 m_b_check_timeout || 01368 m_b_check_retry || 01369 m_b_check_close) 01370 { 01371 return Select(0, m_b_check_detach ? 10000 : 200000); 01372 } 01373 return Select(NULL); 01374 }
int SocketHandler::Select | ( | struct timeval * | tsel | ) | [virtual] |
Wait for events, generate callbacks.
Implements ISocketHandler.
Definition at line 1377 of file SocketHandler.cpp.
References AddIncoming(), CheckCallOnConnect(), CheckClose(), CheckDetach(), CheckErasedSockets(), CheckRetry(), CheckTimeout(), ENABLE_DETACH, ISocketHandler_Select(), m_add, m_b_check_callonconnect, m_b_check_close, m_b_check_detach, m_b_check_retry, m_b_check_timeout, m_delete, m_fds_erase, m_slave, and m_tlast.
01378 { 01379 if (!m_add.empty()) 01380 { 01381 AddIncoming(); 01382 } 01383 int n = ISocketHandler_Select(tsel); 01384 // check CallOnConnect - EVENT 01385 if (m_b_check_callonconnect) 01386 { 01387 CheckCallOnConnect(); 01388 } 01389 01390 #ifdef ENABLE_DETACH 01391 // check detach of socket if master handler - EVENT 01392 if (!m_slave && m_b_check_detach) 01393 { 01394 CheckDetach(); 01395 } 01396 #endif 01397 01398 // check Connecting - connection timeout - conditional event 01399 if (m_b_check_timeout) 01400 { 01401 time_t tnow = time(NULL); 01402 if (tnow != m_tlast) 01403 { 01404 CheckTimeout(tnow); 01405 m_tlast = tnow; 01406 } // tnow != tlast 01407 } 01408 01409 // check retry client connect - EVENT 01410 if (m_b_check_retry) 01411 { 01412 CheckRetry(); 01413 } 01414 01415 // check close and delete - conditional event 01416 if (m_b_check_close) 01417 { 01418 CheckClose(); 01419 } 01420 01421 if (!m_fds_erase.empty()) 01422 { 01423 CheckErasedSockets(); 01424 } 01425 01426 // remove Add's that fizzed 01427 while (m_delete.size()) 01428 { 01429 std::list<Socket *>::iterator it = m_delete.begin(); 01430 Socket *p = *it; 01431 p -> OnDelete(); 01432 m_delete.erase(it); 01433 if (p -> DeleteByHandler() 01434 #ifdef ENABLE_DETACH 01435 && !(m_slave ^ p -> IsDetached()) 01436 #endif 01437 ) 01438 { 01439 p -> SetErasedByHandler(); 01440 delete p; 01441 } 01442 } 01443 01444 return n; 01445 }
bool SocketHandler::Valid | ( | Socket * | p0 | ) | [virtual] |
Check that a socket really is handled by this socket handler.
Implements ISocketHandler.
Definition at line 452 of file SocketHandler.cpp.
References m_sockets.
Referenced by CheckCallOnConnect(), CheckClose(), EventHandler::CheckEvents(), CheckRetry(), CheckTimeout(), and RebuildFdset().
00453 { 00454 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 00455 { 00456 Socket *p = it -> second; 00457 if (p0 == p) 00458 return true; 00459 } 00460 return false; 00461 }
bool SocketHandler::Valid | ( | socketuid_t | ) | [virtual] |
Preferred method - Check that a socket still is handled by this socket handler.
Implements ISocketHandler.
Definition at line 464 of file SocketHandler.cpp.
References m_sockets.
00465 { 00466 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 00467 { 00468 Socket *p = it -> second; 00469 if (p -> UniqueIdentifier() == uid) 00470 return true; 00471 } 00472 return false; 00473 }
size_t SocketHandler::GetCount | ( | ) | [virtual] |
Return number of sockets handled by this handler.
Implements ISocketHandler.
Definition at line 482 of file SocketHandler.cpp.
References m_add, m_delete, and m_sockets.
Referenced by SocketThread::Run().
size_t SocketHandler::MaxCount | ( | ) | [inline, virtual] |
Return maximum number of sockets allowed.
Implements ISocketHandler.
Definition at line 127 of file SocketHandler.h.
Referenced by AddIncoming().
bool SocketHandler::OkToAccept | ( | Socket * | p | ) | [virtual] |
Override and return false to deny all incoming connections.
p | ListenSocket class pointer (use GetPort to identify which one) |
Implements ISocketHandler.
Definition at line 476 of file SocketHandler.cpp.
Use with care, always lock with h.GetMutex() if multithreaded.
Implements ISocketHandler.
Definition at line 134 of file SocketHandler.h.
00134 { return m_sockets; }
size_t SocketHandler::MaxTcpLineSize | ( | ) | [inline, virtual] |
Override to accept longer lines than TCP_LINE_SIZE.
Implements ISocketHandler.
Definition at line 136 of file SocketHandler.h.
References TCP_LINE_SIZE.
00136 { return TCP_LINE_SIZE; }
void SocketHandler::SetCallOnConnect | ( | bool | x = true |
) | [virtual] |
Implements ISocketHandler.
Definition at line 732 of file SocketHandler.cpp.
References m_b_check_callonconnect.
Referenced by CheckCallOnConnect().
00733 { 00734 m_b_check_callonconnect = x; 00735 }
void SocketHandler::SetDetach | ( | bool | x = true |
) | [virtual] |
Implements ISocketHandler.
Definition at line 738 of file SocketHandler.cpp.
References m_b_check_detach.
00739 { 00740 m_b_check_detach = x; 00741 }
void SocketHandler::SetTimeout | ( | bool | x = true |
) | [virtual] |
Implements ISocketHandler.
Definition at line 744 of file SocketHandler.cpp.
References m_b_check_timeout.
Referenced by CheckTimeout().
00745 { 00746 m_b_check_timeout = x; 00747 }
void SocketHandler::SetRetry | ( | bool | x = true |
) | [virtual] |
Implements ISocketHandler.
Definition at line 750 of file SocketHandler.cpp.
References m_b_check_retry.
00751 { 00752 m_b_check_retry = x; 00753 }
void SocketHandler::SetClose | ( | bool | x = true |
) | [virtual] |
Implements ISocketHandler.
Definition at line 756 of file SocketHandler.cpp.
References m_b_check_close.
00757 { 00758 m_b_check_close = x; 00759 }
ISocketHandler::PoolSocket * SocketHandler::FindConnection | ( | int | type, | |
const std::string & | protocol, | |||
SocketAddress & | ad | |||
) | [virtual] |
Find available open connection (used by connection pool).
Implements ISocketHandler.
Definition at line 656 of file SocketHandler.cpp.
References m_sockets.
00657 { 00658 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end() && m_sockets.size(); ++it) 00659 { 00660 PoolSocket *pools = dynamic_cast<PoolSocket *>(it -> second); 00661 if (pools) 00662 { 00663 if (pools -> GetSocketType() == type && 00664 pools -> GetSocketProtocol() == protocol && 00665 // %! pools -> GetClientRemoteAddress() && 00666 *pools -> GetClientRemoteAddress() == ad) 00667 { 00668 m_sockets.erase(it); 00669 pools -> SetRetain(); // avoid Close in Socket destructor 00670 return pools; // Caller is responsible that this socket is deleted 00671 } 00672 } 00673 } 00674 return NULL; 00675 }
void SocketHandler::EnablePool | ( | bool | x = true |
) | [virtual] |
Enable connection pool (by default disabled).
Implements ISocketHandler.
Definition at line 678 of file SocketHandler.cpp.
References m_b_enable_pool.
00679 { 00680 m_b_enable_pool = x; 00681 }
bool SocketHandler::PoolEnabled | ( | ) | [virtual] |
Check pool status.
Implements ISocketHandler.
Definition at line 684 of file SocketHandler.cpp.
References m_b_enable_pool.
00685 { 00686 return m_b_enable_pool; 00687 }
void SocketHandler::SetSocks4Host | ( | ipaddr_t | a | ) | [virtual] |
Set socks4 server ip that all new tcp sockets should use.
Implements ISocketHandler.
Definition at line 489 of file SocketHandler.cpp.
References m_socks4_host.
00490 { 00491 m_socks4_host = a; 00492 }
void SocketHandler::SetSocks4Host | ( | const std::string & | host | ) | [virtual] |
Set socks4 server hostname that all new tcp sockets should use.
Implements ISocketHandler.
Definition at line 495 of file SocketHandler.cpp.
References m_socks4_host, and Utility::u2ip().
00496 { 00497 Utility::u2ip(host, m_socks4_host); 00498 }
void SocketHandler::SetSocks4Port | ( | port_t | port | ) | [virtual] |
Set socks4 server port number that all new tcp sockets should use.
Implements ISocketHandler.
Definition at line 501 of file SocketHandler.cpp.
References m_socks4_port.
00502 { 00503 m_socks4_port = port; 00504 }
void SocketHandler::SetSocks4Userid | ( | const std::string & | id | ) | [virtual] |
Set optional socks4 userid.
Implements ISocketHandler.
Definition at line 507 of file SocketHandler.cpp.
References m_socks4_userid.
00508 { 00509 m_socks4_userid = id; 00510 }
void SocketHandler::SetSocks4TryDirect | ( | bool | x = true |
) | [virtual] |
If connection to socks4 server fails, immediately try direct connection to final host.
Implements ISocketHandler.
Definition at line 610 of file SocketHandler.cpp.
References m_bTryDirect.
00611 { 00612 m_bTryDirect = x; 00613 }
ipaddr_t SocketHandler::GetSocks4Host | ( | ) | [virtual] |
Get socks4 server ip.
Implements ISocketHandler.
Definition at line 616 of file SocketHandler.cpp.
References m_socks4_host.
00617 { 00618 return m_socks4_host; 00619 }
port_t SocketHandler::GetSocks4Port | ( | ) | [virtual] |
Get socks4 port number.
Implements ISocketHandler.
Definition at line 622 of file SocketHandler.cpp.
References m_socks4_port.
00623 { 00624 return m_socks4_port; 00625 }
const std::string & SocketHandler::GetSocks4Userid | ( | ) | [virtual] |
Get socks4 userid (optional).
Implements ISocketHandler.
Definition at line 628 of file SocketHandler.cpp.
References m_socks4_userid.
00629 { 00630 return m_socks4_userid; 00631 }
bool SocketHandler::Socks4TryDirect | ( | ) | [virtual] |
Check status of socks4 try direct flag.
Implements ISocketHandler.
Definition at line 634 of file SocketHandler.cpp.
References m_bTryDirect.
00635 { 00636 return m_bTryDirect; 00637 }
void SocketHandler::EnableResolver | ( | port_t | port = 16667 |
) | [virtual] |
Enable asynchronous DNS.
port | Listen port of asynchronous dns server |
Implements ISocketHandler.
Definition at line 592 of file SocketHandler.cpp.
References m_resolver, and m_resolver_port.
00593 { 00594 if (!m_resolver) 00595 { 00596 m_resolver_port = port; 00597 m_resolver = new ResolvServer(port); 00598 } 00599 }
bool SocketHandler::ResolverEnabled | ( | ) | [virtual] |
Check resolver status.
Implements ISocketHandler.
Definition at line 642 of file SocketHandler.cpp.
References m_resolver.
00643 { 00644 return m_resolver ? true : false; 00645 }
Queue a dns request.
host | Hostname to be resolved | |
port | Port number will be echoed in Socket::OnResolved callback |
Implements ISocketHandler.
Definition at line 515 of file SocketHandler.cpp.
References Add(), DEB, LOG_LEVEL_FATAL, LogError(), m_resolv_id, m_resolve_q, m_resolver_port, and Utility::u2ip().
00516 { 00517 // check cache 00518 ResolvSocket *resolv = new ResolvSocket(*this, p, host, port); 00519 resolv -> SetId(++m_resolv_id); 00520 resolv -> SetDeleteByHandler(); 00521 ipaddr_t local; 00522 Utility::u2ip("127.0.0.1", local); 00523 if (!resolv -> Open(local, m_resolver_port)) 00524 { 00525 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); 00526 } 00527 Add(resolv); 00528 m_resolve_q[p -> UniqueIdentifier()] = true; 00529 DEB( fprintf(stderr, " *** Resolve '%s:%d' id#%d m_resolve_q size: %d p: %p\n", host.c_str(), port, resolv -> GetId(), m_resolve_q.size(), p);) 00530 return resolv -> GetId(); 00531 }
Do a reverse dns lookup.
Implements ISocketHandler.
Definition at line 554 of file SocketHandler.cpp.
References Add(), LOG_LEVEL_FATAL, LogError(), m_resolv_id, m_resolve_q, m_resolver_port, and Utility::u2ip().
00555 { 00556 // check cache 00557 ResolvSocket *resolv = new ResolvSocket(*this, p, a); 00558 resolv -> SetId(++m_resolv_id); 00559 resolv -> SetDeleteByHandler(); 00560 ipaddr_t local; 00561 Utility::u2ip("127.0.0.1", local); 00562 if (!resolv -> Open(local, m_resolver_port)) 00563 { 00564 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); 00565 } 00566 Add(resolv); 00567 m_resolve_q[p -> UniqueIdentifier()] = true; 00568 return resolv -> GetId(); 00569 }
port_t SocketHandler::GetResolverPort | ( | ) | [virtual] |
Get listen port of asynchronous dns server.
Implements ISocketHandler.
Definition at line 648 of file SocketHandler.cpp.
References m_resolver_port.
00649 { 00650 return m_resolver_port; 00651 }
bool SocketHandler::ResolverReady | ( | ) | [virtual] |
Resolver thread ready for queries.
Implements ISocketHandler.
Definition at line 602 of file SocketHandler.cpp.
References m_resolver.
00603 { 00604 return m_resolver ? m_resolver -> Ready() : false; 00605 }
bool SocketHandler::Resolving | ( | Socket * | p0 | ) | [virtual] |
Returns true if the socket is waiting for a resolve event.
Implements ISocketHandler.
Definition at line 444 of file SocketHandler.cpp.
References m_resolve_q.
00445 { 00446 std::map<socketuid_t, bool>::iterator it = m_resolve_q.find(p0 -> UniqueIdentifier()); 00447 return it != m_resolve_q.end(); 00448 }
void SocketHandler::SetSlave | ( | bool | x = true |
) | [virtual] |
Indicates that the handler runs under SocketThread.
Implements ISocketHandler.
Definition at line 348 of file SocketHandler.cpp.
References m_slave.
Referenced by SocketThread::Run().
00349 { 00350 m_slave = x; 00351 }
bool SocketHandler::IsSlave | ( | ) | [virtual] |
Indicates that the handler runs under SocketThread.
Implements ISocketHandler.
Definition at line 354 of file SocketHandler.cpp.
References m_slave.
00355 { 00356 return m_slave; 00357 }
int SocketHandler::ISocketHandler_Select | ( | struct timeval * | tsel | ) | [protected, virtual] |
Actual call to select().
Implements ISocketHandler.
Definition at line 1217 of file SocketHandler.cpp.
References DEB, Errno, IMutex::Lock(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LogError(), m_b_use_mutex, m_efds, m_maxsock, m_mutex, m_rfds, m_sockets, m_wfds, RebuildFdset(), StrError, and IMutex::Unlock().
Referenced by Select().
01218 { 01219 #ifdef MACOSX 01220 fd_set rfds; 01221 fd_set wfds; 01222 fd_set efds; 01223 FD_COPY(&m_rfds, &rfds); 01224 FD_COPY(&m_wfds, &wfds); 01225 FD_COPY(&m_efds, &efds); 01226 #else 01227 fd_set rfds = m_rfds; 01228 fd_set wfds = m_wfds; 01229 fd_set efds = m_efds; 01230 #endif 01231 int n; 01232 DEB( 01233 printf("select( %d, [", m_maxsock + 1); 01234 for (size_t i = 0; i <= m_maxsock; i++) 01235 if (FD_ISSET(i, &rfds)) 01236 printf(" %d", i); 01237 printf("], ["); 01238 for (size_t i = 0; i <= m_maxsock; i++) 01239 if (FD_ISSET(i, &wfds)) 01240 printf(" %d", i); 01241 printf("], ["); 01242 for (size_t i = 0; i <= m_maxsock; i++) 01243 if (FD_ISSET(i, &efds)) 01244 printf(" %d", i); 01245 printf("]\n"); 01246 ) 01247 if (m_b_use_mutex) 01248 { 01249 m_mutex.Unlock(); 01250 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); 01251 m_mutex.Lock(); 01252 } 01253 else 01254 { 01255 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); 01256 } 01257 if (n == -1) // error on select 01258 { 01259 int err = Errno; 01260 /* 01261 EBADF An invalid file descriptor was given in one of the sets. 01262 EINTR A non blocked signal was caught. 01263 EINVAL n is negative. Or struct timeval contains bad time values (<0). 01264 ENOMEM select was unable to allocate memory for internal tables. 01265 */ 01266 #ifdef _WIN32 01267 switch (err) 01268 { 01269 case WSAENOTSOCK: 01270 RebuildFdset(); 01271 break; 01272 case WSAEINTR: 01273 case WSAEINPROGRESS: 01274 break; 01275 case WSAEINVAL: 01276 LogError(NULL, "SocketHandler::Select", err, StrError(err), LOG_LEVEL_FATAL); 01277 throw Exception("select(n): n is negative. Or struct timeval contains bad time values (<0)."); 01278 case WSAEFAULT: 01279 LogError(NULL, "SocketHandler::Select", err, StrError(err), LOG_LEVEL_ERROR); 01280 break; 01281 case WSANOTINITIALISED: 01282 throw Exception("WSAStartup not successfully called"); 01283 case WSAENETDOWN: 01284 throw Exception("Network subsystem failure"); 01285 } 01286 #else 01287 switch (err) 01288 { 01289 case EBADF: 01290 RebuildFdset(); 01291 break; 01292 case EINTR: 01293 break; 01294 case EINVAL: 01295 LogError(NULL, "SocketHandler::Select", err, StrError(err), LOG_LEVEL_FATAL); 01296 throw Exception("select(n): n is negative. Or struct timeval contains bad time values (<0)."); 01297 case ENOMEM: 01298 LogError(NULL, "SocketHandler::Select", err, StrError(err), LOG_LEVEL_ERROR); 01299 break; 01300 } 01301 #endif 01302 printf("error on select(): %d %s\n", Errno, StrError(err)); 01303 } 01304 else 01305 if (!n) // timeout 01306 { 01307 } 01308 else 01309 if (n > 0) 01310 { 01311 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 01312 { 01313 SOCKET i = it -> first; 01314 Socket *p = it -> second; 01315 // --------------------------------------------------------------------------------- 01316 if (FD_ISSET(i, &rfds)) 01317 { 01318 #ifdef HAVE_OPENSSL 01319 if (p -> IsSSLNegotiate()) 01320 { 01321 p -> SSLNegotiate(); 01322 } 01323 else 01324 #endif 01325 { 01326 p -> OnRead(); 01327 } 01328 } 01329 // --------------------------------------------------------------------------------- 01330 if (FD_ISSET(i, &wfds)) 01331 { 01332 #ifdef HAVE_OPENSSL 01333 if (p -> IsSSLNegotiate()) 01334 { 01335 p -> SSLNegotiate(); 01336 } 01337 else 01338 #endif 01339 { 01340 p -> OnWrite(); 01341 } 01342 } 01343 // --------------------------------------------------------------------------------- 01344 if (FD_ISSET(i, &efds)) 01345 { 01346 p -> OnException(); 01347 } 01348 } // m_sockets ... 01349 } // if (n > 0) 01350 return n; 01351 }
void SocketHandler::Remove | ( | Socket * | p | ) | [protected, virtual] |
Remove socket from socket map, used by Socket class.
Implements ISocketHandler.
Definition at line 691 of file SocketHandler.cpp.
References LOG_LEVEL_WARNING, LogError(), m_add, m_delete, m_resolve_q, and m_sockets.
00692 { 00693 #ifdef ENABLE_RESOLVER 00694 std::map<socketuid_t, bool>::iterator it4 = m_resolve_q.find(p -> UniqueIdentifier()); 00695 if (it4 != m_resolve_q.end()) 00696 m_resolve_q.erase(it4); 00697 #endif 00698 if (p -> ErasedByHandler()) 00699 { 00700 return; 00701 } 00702 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 00703 { 00704 if (it -> second == p) 00705 { 00706 LogError(p, "Remove", -1, "Socket destructor called while still in use", LOG_LEVEL_WARNING); 00707 m_sockets.erase(it); 00708 return; 00709 } 00710 } 00711 for (std::list<Socket *>::iterator it2 = m_add.begin(); it2 != m_add.end(); ++it2) 00712 { 00713 if (*it2 == p) 00714 { 00715 LogError(p, "Remove", -2, "Socket destructor called while still in use", LOG_LEVEL_WARNING); 00716 m_add.erase(it2); 00717 return; 00718 } 00719 } 00720 for (std::list<Socket *>::iterator it3 = m_delete.begin(); it3 != m_delete.end(); ++it3) 00721 { 00722 if (*it3 == p) 00723 { 00724 LogError(p, "Remove", -3, "Socket destructor called while still in use", LOG_LEVEL_WARNING); 00725 m_delete.erase(it3); 00726 return; 00727 } 00728 } 00729 }
void SocketHandler::DeleteSocket | ( | Socket * | p | ) | [protected] |
Schedule socket for deletion.
Definition at line 762 of file SocketHandler.cpp.
References m_fds_erase.
Referenced by AddIncoming(), CheckClose(), and RebuildFdset().
00763 { 00764 p -> OnDelete(); 00765 if (p -> DeleteByHandler() && !p -> ErasedByHandler()) 00766 { 00767 p -> SetErasedByHandler(); 00768 } 00769 m_fds_erase.push_back(p -> UniqueIdentifier()); 00770 }
void SocketHandler::AddIncoming | ( | ) | [protected] |
Definition at line 827 of file SocketHandler.cpp.
References CheckTimeout(), DEB, DeleteSocket(), INVALID_SOCKET, ISocketHandler_Add(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, LogError(), m_add, m_b_check_callonconnect, m_b_check_detach, m_b_check_retry, m_b_check_timeout, m_delete, m_maxsock, m_sockets, and MaxCount().
Referenced by Select().
00828 { 00829 while (m_add.size() > 0) 00830 { 00831 if (m_sockets.size() >= MaxCount()) 00832 { 00833 LogError(NULL, "Select", (int)m_sockets.size(), "socket limit reached", LOG_LEVEL_WARNING); 00834 break; 00835 } 00836 std::list<Socket *>::iterator it = m_add.begin(); 00837 Socket *p = *it; 00838 SOCKET s = p -> GetSocket(); 00839 DEB( fprintf(stderr, "Trying to add fd %d, m_add.size() %d\n", (int)s, (int)m_add.size());) 00840 // 00841 if (s == INVALID_SOCKET) 00842 { 00843 LogError(p, "Add", -1, "Invalid socket", LOG_LEVEL_WARNING); 00844 m_delete.push_back(p); 00845 m_add.erase(it); 00846 continue; 00847 } 00848 socket_m::iterator it2; 00849 if ((it2 = m_sockets.find(s)) != m_sockets.end()) 00850 { 00851 Socket *found = it2 -> second; 00852 if (p -> UniqueIdentifier() > found -> UniqueIdentifier()) 00853 { 00854 LogError(p, "Add", (int)p -> GetSocket(), "Replacing socket already in controlled queue (newer uid)", LOG_LEVEL_WARNING); 00855 // replace 00856 DeleteSocket(found); 00857 } 00858 else 00859 if (p -> UniqueIdentifier() == found -> UniqueIdentifier()) 00860 { 00861 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in controlled queue (same uid)", LOG_LEVEL_ERROR); 00862 // same - ignore 00863 if (p != found) 00864 m_delete.push_back(p); 00865 m_add.erase(it); 00866 continue; 00867 } 00868 else 00869 { 00870 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in controlled queue (older uid)", LOG_LEVEL_FATAL); 00871 // %! it's a dup, don't add to delete queue, just ignore it 00872 m_delete.push_back(p); 00873 m_add.erase(it); 00874 continue; 00875 } 00876 } 00877 if (p -> CloseAndDelete()) 00878 { 00879 LogError(p, "Add", (int)p -> GetSocket(), "Added socket with SetCloseAndDelete() true", LOG_LEVEL_WARNING); 00880 m_sockets[s] = p; 00881 DeleteSocket(p); 00882 p -> Close(); 00883 } 00884 else 00885 { 00886 m_b_check_callonconnect |= p -> CallOnConnect(); 00887 m_b_check_detach |= p -> IsDetach(); 00888 m_b_check_timeout |= p -> CheckTimeout(); 00889 m_b_check_retry |= p -> RetryClientConnect(); 00890 /* 00891 if (p -> CallOnConnect()) 00892 { 00893 m_b_check_callonconnect = true; 00894 } 00895 if (p -> IsDetach()) 00896 { 00897 m_b_check_detach = true; 00898 } 00899 if (p -> CheckTimeout()) 00900 { 00901 m_b_check_timeout = true; 00902 } 00903 if (p -> RetryClientConnect()) 00904 { 00905 m_b_check_retry = true; 00906 } 00907 */ 00908 StreamSocket *scp = dynamic_cast<StreamSocket *>(p); 00909 if (scp && scp -> Connecting()) // 'Open' called before adding socket 00910 { 00911 ISocketHandler_Add(p,false,true); 00912 } 00913 else 00914 { 00915 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 00916 bool bWrite = tcp ? tcp -> GetOutputLength() != 0 : false; 00917 if (p -> IsDisableRead()) 00918 { 00919 ISocketHandler_Add(p, false, bWrite); 00920 } 00921 else 00922 { 00923 ISocketHandler_Add(p, true, bWrite); 00924 } 00925 } 00926 m_maxsock = (s > m_maxsock) ? s : m_maxsock; 00927 m_sockets[s] = p; 00928 } 00929 // 00930 m_add.erase(it); 00931 } 00932 }
void SocketHandler::CheckErasedSockets | ( | ) | [protected] |
Definition at line 935 of file SocketHandler.cpp.
References m_fds_erase, m_maxsock, m_slave, and m_sockets.
Referenced by Select().
00936 { 00937 // check erased sockets 00938 bool check_max_fd = false; 00939 while (m_fds_erase.size()) 00940 { 00941 std::list<socketuid_t>::iterator it = m_fds_erase.begin(); 00942 socketuid_t uid = *it; 00943 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 00944 { 00945 Socket *p = it -> second; 00946 if (p -> UniqueIdentifier() == uid) 00947 { 00948 /* Sometimes a SocketThread class can finish its run before the master 00949 sockethandler gets here. In that case, the SocketThread has set the 00950 'ErasedByHandler' flag on the socket which will make us end up with a 00951 double delete on the socket instance. 00952 The fix is to make sure that the master sockethandler only can delete 00953 non-detached sockets, and a slave sockethandler only can delete 00954 detach sockets. */ 00955 if (p -> ErasedByHandler() 00956 #ifdef ENABLE_DETACH 00957 && !(m_slave ^ p -> IsDetached()) 00958 #endif 00959 ) 00960 { 00961 delete p; 00962 } 00963 m_sockets.erase(it); 00964 break; 00965 } 00966 } 00967 m_fds_erase.erase(it); 00968 check_max_fd = true; 00969 } 00970 // calculate max file descriptor for select() call 00971 if (check_max_fd) 00972 { 00973 m_maxsock = 0; 00974 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 00975 { 00976 SOCKET s = it -> first; 00977 m_maxsock = s > m_maxsock ? s : m_maxsock; 00978 } 00979 } 00980 }
void SocketHandler::CheckCallOnConnect | ( | ) | [protected] |
Definition at line 983 of file SocketHandler.cpp.
References m_b_check_callonconnect, m_sockets, SetCallOnConnect(), and Valid().
Referenced by Select().
00984 { 00985 m_b_check_callonconnect = false; 00986 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 00987 { 00988 Socket *p = it -> second; 00989 if (Valid(p) && Valid(p -> UniqueIdentifier()) && p -> CallOnConnect()) 00990 { 00991 p -> SetConnected(); // moved here from inside if (tcp) check below 00992 #ifdef HAVE_OPENSSL 00993 if (p -> IsSSL()) // SSL Enabled socket 00994 p -> OnSSLConnect(); 00995 else 00996 #endif 00997 #ifdef ENABLE_SOCKS4 00998 if (p -> Socks4()) 00999 p -> OnSocks4Connect(); 01000 else 01001 #endif 01002 { 01003 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 01004 if (tcp) 01005 { 01006 if (tcp -> GetOutputLength()) 01007 { 01008 p -> OnWrite(); 01009 } 01010 } 01011 #ifdef ENABLE_RECONNECT 01012 if (tcp && tcp -> IsReconnect()) 01013 p -> OnReconnect(); 01014 else 01015 #endif 01016 { 01017 p -> OnConnect(); 01018 } 01019 } 01020 p -> SetCallOnConnect( false ); 01021 m_b_check_callonconnect = true; 01022 } 01023 } 01024 }
void SocketHandler::CheckDetach | ( | ) | [protected] |
Definition at line 1028 of file SocketHandler.cpp.
References ISocketHandler_Del(), m_add, m_b_check_detach, and m_sockets.
Referenced by Select().
01029 { 01030 m_b_check_detach = false; 01031 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 01032 { 01033 Socket *p = it -> second; 01034 if (p -> IsDetach()) 01035 { 01036 ISocketHandler_Del(p); 01037 m_sockets.erase(it); // we don't want this around anymore 01038 // After DetachSocket(), all calls to Handler() will return a reference 01039 // to the new slave SocketHandler running in the new thread. 01040 p -> DetachSocket(); 01041 // Adding the file descriptor to m_fds_erase will now also remove the 01042 // socket from the detach queue - tnx knightmad 01043 // m_fds_erase.push_back(p -> UniqueIdentifier()); 01044 m_b_check_detach = true; 01045 break; // 'it' is invalid 01046 } 01047 } 01048 for (std::list<Socket *>::iterator it = m_add.begin(); it != m_add.end() && !m_b_check_detach; ++it) 01049 { 01050 Socket *p = *it; 01051 m_b_check_detach |= p -> IsDetach(); 01052 } 01053 }
void SocketHandler::CheckTimeout | ( | time_t | tnow | ) | [protected] |
Definition at line 1057 of file SocketHandler.cpp.
References m_b_check_timeout, m_sockets, SetTimeout(), and Valid().
Referenced by AddIncoming(), and Select().
01058 { 01059 m_b_check_timeout = false; 01060 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 01061 { 01062 Socket *p = it -> second; 01063 if (Valid(p) && Valid(p -> UniqueIdentifier()) && p -> CheckTimeout()) 01064 { 01065 if (p -> Timeout(tnow)) 01066 { 01067 StreamSocket *scp = dynamic_cast<StreamSocket *>(p); 01068 p -> SetTimeout(0); 01069 if (scp && scp -> Connecting()) 01070 { 01071 p -> OnConnectTimeout(); 01072 // restart timer 01073 p -> SetTimeout( scp -> GetConnectTimeout() ); 01074 } 01075 else 01076 { 01077 p -> OnTimeout(); 01078 } 01079 } 01080 m_b_check_timeout = true; 01081 } 01082 } 01083 }
void SocketHandler::CheckRetry | ( | ) | [protected] |
Definition at line 1086 of file SocketHandler.cpp.
References Add(), DEB, LOG_LEVEL_ERROR, LogError(), m_b_check_retry, m_fds_erase, m_sockets, and Valid().
Referenced by Select().
01087 { 01088 m_b_check_retry = false; 01089 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 01090 { 01091 Socket *p = it -> second; 01092 if (Valid(p) && Valid(p -> UniqueIdentifier()) && p -> RetryClientConnect()) 01093 { 01094 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 01095 tcp -> SetRetryClientConnect(false); 01096 DEB( fprintf(stderr, "Close() before retry client connect\n");) 01097 p -> Close(); // removes from m_fds_retry 01098 std::auto_ptr<SocketAddress> ad = p -> GetClientRemoteAddress(); 01099 if (ad.get()) 01100 { 01101 tcp -> Open(*ad); 01102 } 01103 else 01104 { 01105 LogError(p, "RetryClientConnect", 0, "no address", LOG_LEVEL_ERROR); 01106 } 01107 Add(p); 01108 m_fds_erase.push_back(p -> UniqueIdentifier()); 01109 m_b_check_retry = true; 01110 } 01111 } 01112 }
void SocketHandler::CheckClose | ( | ) | [protected] |
Definition at line 1115 of file SocketHandler.cpp.
References Add(), DEB, DeleteSocket(), Errno, HAVE_OPENSSL, INVALID_SOCKET, ISocketHandler_Del(), LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LogError(), m_b_check_close, m_fds_erase, m_sockets, StrError, and Valid().
Referenced by Select().
01116 { 01117 m_b_check_close = false; 01118 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 01119 { 01120 Socket *p = it -> second; 01121 if (Valid(p) && Valid(p -> UniqueIdentifier()) && p -> CloseAndDelete() ) 01122 { 01123 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 01124 #ifdef ENABLE_RECONNECT 01125 if (p -> Lost() && !(tcp && tcp -> Reconnect())) 01126 #else 01127 if (p -> Lost()) 01128 #endif 01129 { 01130 // remove instance when Lost, if not reconnect flag is set 01131 DeleteSocket(p); 01132 } 01133 else 01134 // new graceful tcp - flush and close timeout 5s 01135 if (tcp && p -> IsConnected() && tcp -> GetFlushBeforeClose() && 01136 #ifdef HAVE_OPENSSL 01137 !tcp -> IsSSL() && 01138 #endif 01139 p -> TimeSinceClose() < 5) 01140 { 01141 DEB( fprintf(stderr, " close(1)\n");) 01142 if (tcp -> GetOutputLength()) 01143 { 01144 LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Sending all data before closing", LOG_LEVEL_INFO); 01145 } 01146 else // shutdown write when output buffer is empty 01147 if (!(tcp -> GetShutdown() & SHUT_WR)) 01148 { 01149 SOCKET nn = it -> first; 01150 if (nn != INVALID_SOCKET && shutdown(nn, SHUT_WR) == -1) 01151 { 01152 LogError(p, "graceful shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR); 01153 } 01154 tcp -> SetShutdown(SHUT_WR); 01155 } 01156 else 01157 { 01158 ISocketHandler_Del(p); 01159 tcp -> Close(); 01160 DeleteSocket(p); 01161 } 01162 } 01163 else 01164 #ifdef ENABLE_RECONNECT 01165 if (tcp && p -> IsConnected() && tcp -> Reconnect()) 01166 { 01167 p -> SetCloseAndDelete(false); 01168 tcp -> SetIsReconnect(); 01169 p -> SetConnected(false); 01170 DEB( fprintf(stderr, "Close() before reconnect\n");) 01171 p -> Close(); // dispose of old file descriptor (Open creates a new) 01172 p -> OnDisconnect(); 01173 std::auto_ptr<SocketAddress> ad = p -> GetClientRemoteAddress(); 01174 if (ad.get()) 01175 { 01176 tcp -> Open(*ad); 01177 } 01178 else 01179 { 01180 LogError(p, "Reconnect", 0, "no address", LOG_LEVEL_ERROR); 01181 } 01182 tcp -> ResetConnectionRetries(); 01183 Add(p); 01184 m_fds_erase.push_back(p -> UniqueIdentifier()); 01185 } 01186 else 01187 #endif 01188 { 01189 if (tcp && p -> IsConnected() && tcp -> GetOutputLength()) 01190 { 01191 LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Closing socket while data still left to send", LOG_LEVEL_WARNING); 01192 } 01193 #ifdef ENABLE_POOL 01194 if (p -> Retain() && !p -> Lost()) 01195 { 01196 PoolSocket *p2 = new PoolSocket(*this, p); 01197 p2 -> SetDeleteByHandler(); 01198 Add(p2); 01199 // 01200 p -> SetCloseAndDelete(false); // added - remove from m_fds_close 01201 } 01202 else 01203 #endif // ENABLE_POOL 01204 { 01205 ISocketHandler_Del(p); 01206 DEB( fprintf(stderr, "Close() before OnDelete\n");) 01207 p -> Close(); 01208 } 01209 DeleteSocket(p); 01210 } 01211 m_b_check_close = true; 01212 } 01213 } 01214 }
void SocketHandler::RebuildFdset | ( | ) | [private] |
Definition at line 773 of file SocketHandler.cpp.
References DeleteSocket(), Errno, LOG_LEVEL_ERROR, LogError(), m_efds, m_rfds, m_sockets, m_wfds, and Valid().
Referenced by ISocketHandler_Select().
00774 { 00775 fd_set rfds; 00776 fd_set wfds; 00777 fd_set efds; 00778 // rebuild fd_set's from active sockets list (m_sockets) here 00779 FD_ZERO(&rfds); 00780 FD_ZERO(&wfds); 00781 FD_ZERO(&efds); 00782 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); ++it) 00783 { 00784 SOCKET s = it -> first; 00785 Socket *p = it -> second; 00786 if (s == p -> GetSocket() && s >= 0) 00787 { 00788 fd_set fds; 00789 FD_ZERO(&fds); 00790 FD_SET(s, &fds); 00791 struct timeval tv; 00792 tv.tv_sec = 0; 00793 tv.tv_usec = 0; 00794 int n = select((int)s + 1, &fds, NULL, NULL, &tv); 00795 if (n == -1 && Errno == EBADF) 00796 { 00797 // %! bad fd, remove 00798 LogError(p, "Select", (int)s, "Bad fd in fd_set (2)", LOG_LEVEL_ERROR); 00799 if (Valid(p) && Valid(p -> UniqueIdentifier())) 00800 { 00801 DeleteSocket(p); 00802 } 00803 } 00804 else 00805 { 00806 if (FD_ISSET(s, &m_rfds)) 00807 FD_SET(s, &rfds); 00808 if (FD_ISSET(s, &m_wfds)) 00809 FD_SET(s, &wfds); 00810 if (FD_ISSET(s, &m_efds)) 00811 FD_SET(s, &efds); 00812 } 00813 } 00814 else 00815 { 00816 // %! mismatch 00817 LogError(p, "Select", (int)s, "Bad fd in fd_set (3)", LOG_LEVEL_ERROR); 00818 DeleteSocket(p); 00819 } 00820 } 00821 m_rfds = rfds; 00822 m_wfds = wfds; 00823 m_efds = efds; 00824 }
void SocketHandler::Set | ( | Socket * | p, | |
bool | bRead, | |||
bool | bWrite | |||
) | [private] |
Definition at line 400 of file SocketHandler.cpp.
References m_efds, m_rfds, and m_wfds.
Referenced by ISocketHandler_Add(), ISocketHandler_Del(), and ISocketHandler_Mod().
00401 { 00402 SOCKET s = p -> GetSocket(); 00403 if (s >= 0) 00404 { 00405 bool bException = true; 00406 if (bRead) 00407 { 00408 if (!FD_ISSET(s, &m_rfds)) 00409 { 00410 FD_SET(s, &m_rfds); 00411 } 00412 } 00413 else 00414 { 00415 FD_CLR(s, &m_rfds); 00416 } 00417 if (bWrite) 00418 { 00419 if (!FD_ISSET(s, &m_wfds)) 00420 { 00421 FD_SET(s, &m_wfds); 00422 } 00423 } 00424 else 00425 { 00426 FD_CLR(s, &m_wfds); 00427 } 00428 if (bException) 00429 { 00430 if (!FD_ISSET(s, &m_efds)) 00431 { 00432 FD_SET(s, &m_efds); 00433 } 00434 } 00435 else 00436 { 00437 FD_CLR(s, &m_efds); 00438 } 00439 } 00440 }
FILE* SocketHandler::m_event_file [static, private] |
Definition at line 145 of file SocketHandler.h.
unsigned long SocketHandler::m_event_counter [static, private] |
Definition at line 146 of file SocketHandler.h.
socket_m SocketHandler::m_sockets [protected] |
Active sockets map.
Definition at line 222 of file SocketHandler.h.
Referenced by AddIncoming(), CheckCallOnConnect(), CheckClose(), CheckDetach(), CheckErasedSockets(), CheckRetry(), CheckTimeout(), FindConnection(), GetCount(), ISocketHandler_Select(), RebuildFdset(), Remove(), Valid(), and ~SocketHandler().
std::list<Socket *> SocketHandler::m_add [protected] |
Sockets to be added to sockets map.
Definition at line 223 of file SocketHandler.h.
Referenced by Add(), AddIncoming(), CheckDetach(), GetCount(), Remove(), and Select().
std::list<Socket *> SocketHandler::m_delete [protected] |
Sockets to be deleted (failed when Add).
Definition at line 224 of file SocketHandler.h.
Referenced by AddIncoming(), GetCount(), Remove(), and Select().
StdLog* SocketHandler::m_stdlog [protected] |
Registered log class, or NULL.
Definition at line 241 of file SocketHandler.h.
Referenced by LogError(), and RegStdLog().
IMutex& SocketHandler::m_mutex [protected] |
Thread safety mutex.
Definition at line 242 of file SocketHandler.h.
Referenced by GetMutex(), ISocketHandler_Select(), SocketHandler(), and ~SocketHandler().
bool SocketHandler::m_b_use_mutex [protected] |
Mutex correctly initialized.
Definition at line 243 of file SocketHandler.h.
Referenced by ISocketHandler_Select(), and ~SocketHandler().
ISocketHandler& SocketHandler::m_parent [protected] |
Definition at line 244 of file SocketHandler.h.
Referenced by GetEffectiveHandler(), and ParentHandler().
bool SocketHandler::m_b_parent_is_valid [protected] |
Definition at line 245 of file SocketHandler.h.
Referenced by GetEffectiveHandler(), ParentHandler(), and ParentHandlerIsValid().
std::list<SocketHandlerThread *> SocketHandler::m_threads [private] |
Definition at line 251 of file SocketHandler.h.
Referenced by GetRandomHandler(), IsThreaded(), SetNumberOfThreads(), and ~SocketHandler().
UdpSocket* SocketHandler::m_release [private] |
SOCKET SocketHandler::m_maxsock [private] |
Highest file descriptor + 1 in active sockets list.
Definition at line 254 of file SocketHandler.h.
Referenced by AddIncoming(), CheckErasedSockets(), and ISocketHandler_Select().
fd_set SocketHandler::m_rfds [private] |
file descriptor set monitored for read events
Definition at line 255 of file SocketHandler.h.
Referenced by ISocketHandler_Select(), RebuildFdset(), Set(), and SocketHandler().
fd_set SocketHandler::m_wfds [private] |
file descriptor set monitored for write events
Definition at line 256 of file SocketHandler.h.
Referenced by ISocketHandler_Select(), RebuildFdset(), Set(), and SocketHandler().
fd_set SocketHandler::m_efds [private] |
file descriptor set monitored for exceptions
Definition at line 257 of file SocketHandler.h.
Referenced by ISocketHandler_Select(), RebuildFdset(), Set(), and SocketHandler().
time_t SocketHandler::m_tlast [private] |
std::list<socketuid_t> SocketHandler::m_fds_erase [private] |
File descriptors that are to be erased from m_sockets.
Definition at line 261 of file SocketHandler.h.
Referenced by CheckClose(), CheckErasedSockets(), CheckRetry(), DeleteSocket(), and Select().
bool SocketHandler::m_b_check_callonconnect [private] |
Definition at line 263 of file SocketHandler.h.
Referenced by AddIncoming(), CheckCallOnConnect(), Select(), and SetCallOnConnect().
bool SocketHandler::m_b_check_detach [private] |
Definition at line 264 of file SocketHandler.h.
Referenced by AddIncoming(), CheckDetach(), Select(), and SetDetach().
bool SocketHandler::m_b_check_timeout [private] |
Definition at line 265 of file SocketHandler.h.
Referenced by AddIncoming(), CheckTimeout(), Select(), and SetTimeout().
bool SocketHandler::m_b_check_retry [private] |
Definition at line 266 of file SocketHandler.h.
Referenced by AddIncoming(), CheckRetry(), Select(), and SetRetry().
bool SocketHandler::m_b_check_close [private] |
Definition at line 267 of file SocketHandler.h.
Referenced by CheckClose(), Select(), and SetClose().
ipaddr_t SocketHandler::m_socks4_host [private] |
Socks4 server host ip.
Definition at line 270 of file SocketHandler.h.
Referenced by GetSocks4Host(), and SetSocks4Host().
port_t SocketHandler::m_socks4_port [private] |
Socks4 server port number.
Definition at line 271 of file SocketHandler.h.
Referenced by GetSocks4Port(), and SetSocks4Port().
std::string SocketHandler::m_socks4_userid [private] |
Socks4 userid.
Definition at line 272 of file SocketHandler.h.
Referenced by GetSocks4Userid(), and SetSocks4Userid().
bool SocketHandler::m_bTryDirect [private] |
Try direct connection if socks4 server fails.
Definition at line 273 of file SocketHandler.h.
Referenced by SetSocks4TryDirect(), and Socks4TryDirect().
int SocketHandler::m_resolv_id [private] |
ResolvServer* SocketHandler::m_resolver [private] |
Resolver thread pointer.
Definition at line 277 of file SocketHandler.h.
Referenced by EnableResolver(), ResolverEnabled(), ResolverReady(), and ~SocketHandler().
port_t SocketHandler::m_resolver_port [private] |
Resolver listen port.
Definition at line 278 of file SocketHandler.h.
Referenced by EnableResolver(), GetResolverPort(), and Resolve().
std::map<socketuid_t, bool> SocketHandler::m_resolve_q [private] |
resolve queue
Definition at line 279 of file SocketHandler.h.
Referenced by Remove(), Resolve(), and Resolving().
bool SocketHandler::m_b_enable_pool [private] |
Connection pool enabled if true.
Definition at line 282 of file SocketHandler.h.
Referenced by EnablePool(), and PoolEnabled().
bool SocketHandler::m_slave [private] |
Indicates that this is a ISocketHandler run in SocketThread.
Definition at line 285 of file SocketHandler.h.
Referenced by CheckErasedSockets(), IsSlave(), Select(), SetSlave(), and ~SocketHandler().