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 & | 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 | Get (SOCKET s, bool &r, bool &w, bool &e) |
| Get status of read/write/exception file descriptor set for a socket. | |
| void | Set (SOCKET s, bool bRead, bool bWrite, bool bException=true) |
| Set read/write/exception file descriptor sets (fd_set). | |
| 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. | |
| size_t | GetCount () |
| Return number of sockets handled by this handler. | |
| bool | OkToAccept (Socket *p) |
| Override and return false to deny all incoming connections. | |
| void | AddList (SOCKET s, list_t which_one, bool add) |
| Called by Socket when a socket changes state. | |
| 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. | |
| void | CheckSanity () |
| Sanity check of those accursed lists. | |
Protected Types | |
| typedef std::map< SOCKET, Socket * > | socket_m |
| Map type for holding file descriptors/socket object pointers. | |
Protected Member Functions | |
| void | Remove (Socket *) |
| Remove socket from socket map, used by Socket class. | |
Protected Attributes | |
| socket_m | m_sockets |
| Active sockets map. | |
| socket_m | 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. | |
Private Member Functions | |
| void | CheckList (socket_v &, const std::string &) |
| Used by CheckSanity. | |
Private Attributes | |
| 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 | |
| int | m_preverror |
| debug select() error | |
| int | m_errcnt |
| debug select() error | |
| time_t | m_tlast |
| timeout control | |
| socket_v | m_fds |
| Active file descriptor list. | |
| socket_v | m_fds_erase |
| File descriptors that are to be erased from m_sockets. | |
| socket_v | m_fds_callonconnect |
| checklist CallOnConnect | |
| socket_v | m_fds_detach |
| checklist Detach | |
| socket_v | m_fds_timeout |
| checklist timeout | |
| socket_v | m_fds_retry |
| checklist retry client connect | |
| socket_v | m_fds_close |
| checklist close and delete | |
| 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< Socket *, 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. | |
Definition at line 53 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 57 of file SocketHandler.h.
| SocketHandler::SocketHandler | ( | StdLog * | log = NULL |
) |
SocketHandler constructor.
| log | Optional log class pointer |
Definition at line 59 of file SocketHandler.cpp.
References m_efds, m_rfds, and m_wfds.
00060 :m_stdlog(p) 00061 ,m_mutex(m_mutex) 00062 ,m_b_use_mutex(false) 00063 ,m_maxsock(0) 00064 ,m_preverror(-1) 00065 ,m_errcnt(0) 00066 ,m_tlast(0) 00067 #ifdef ENABLE_SOCKS4 00068 ,m_socks4_host(0) 00069 ,m_socks4_port(0) 00070 ,m_bTryDirect(false) 00071 #endif 00072 #ifdef ENABLE_RESOLVER 00073 ,m_resolv_id(0) 00074 ,m_resolver(NULL) 00075 #endif 00076 #ifdef ENABLE_POOL 00077 ,m_b_enable_pool(false) 00078 #endif 00079 #ifdef ENABLE_TRIGGERS 00080 ,m_next_trigger_id(0) 00081 #endif 00082 #ifdef ENABLE_DETACH 00083 ,m_slave(false) 00084 #endif 00085 { 00086 FD_ZERO(&m_rfds); 00087 FD_ZERO(&m_wfds); 00088 FD_ZERO(&m_efds); 00089 }
SocketHandler threadsafe constructor.
| mutex | Externally declared mutex variable | |
| log | Optional log class pointer |
Definition at line 92 of file SocketHandler.cpp.
References IMutex::Lock(), m_efds, m_mutex, m_rfds, and m_wfds.
00093 :m_stdlog(p) 00094 ,m_mutex(mutex) 00095 ,m_b_use_mutex(true) 00096 ,m_maxsock(0) 00097 ,m_preverror(-1) 00098 ,m_errcnt(0) 00099 ,m_tlast(0) 00100 #ifdef ENABLE_SOCKS4 00101 ,m_socks4_host(0) 00102 ,m_socks4_port(0) 00103 ,m_bTryDirect(false) 00104 #endif 00105 #ifdef ENABLE_RESOLVER 00106 ,m_resolv_id(0) 00107 ,m_resolver(NULL) 00108 #endif 00109 #ifdef ENABLE_POOL 00110 ,m_b_enable_pool(false) 00111 #endif 00112 #ifdef ENABLE_TRIGGERS 00113 ,m_next_trigger_id(0) 00114 #endif 00115 #ifdef ENABLE_DETACH 00116 ,m_slave(false) 00117 #endif 00118 { 00119 m_mutex.Lock(); 00120 FD_ZERO(&m_rfds); 00121 FD_ZERO(&m_wfds); 00122 FD_ZERO(&m_efds); 00123 }
| SocketHandler::~SocketHandler | ( | ) |
Definition at line 126 of file SocketHandler.cpp.
References DEB, ENABLE_DETACH, ENABLE_RESOLVER, m_b_use_mutex, m_mutex, m_resolver, m_slave, m_sockets, and IMutex::Unlock().
00127 { 00128 #ifdef ENABLE_RESOLVER 00129 if (m_resolver) 00130 { 00131 m_resolver -> Quit(); 00132 } 00133 #endif 00134 { 00135 while (m_sockets.size()) 00136 { 00137 DEB( fprintf(stderr, "Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) 00138 socket_m::iterator it = m_sockets.begin(); 00139 Socket *p = it -> second; 00140 if (p) 00141 { 00142 DEB( fprintf(stderr, " fd %d\n", p -> GetSocket());) 00143 p -> Close(); 00144 DEB( fprintf(stderr, " fd closed %d\n", p -> GetSocket());) 00145 // p -> OnDelete(); // hey, I turn this back on. what's the worst that could happen??!! 00146 // MinionSocket breaks, calling MinderHandler methods in OnDelete - 00147 // MinderHandler is already gone when that happens... 00148 00149 // only delete socket when controlled 00150 // ie master sockethandler can delete non-detached sockets 00151 // and a slave sockethandler can only delete a detach socket 00152 if (p -> DeleteByHandler() 00153 #ifdef ENABLE_DETACH 00154 && !(m_slave ^ p -> IsDetached()) 00155 #endif 00156 ) 00157 { 00158 p -> SetErasedByHandler(); 00159 delete p; 00160 } 00161 m_sockets.erase(it); 00162 } 00163 else 00164 { 00165 m_sockets.erase(it); 00166 } 00167 DEB( fprintf(stderr, "next\n");) 00168 } 00169 DEB( fprintf(stderr, "/Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) 00170 } 00171 #ifdef ENABLE_RESOLVER 00172 if (m_resolver) 00173 { 00174 delete m_resolver; 00175 } 00176 #endif 00177 if (m_b_use_mutex) 00178 { 00179 m_mutex.Unlock(); 00180 } 00181 }
| IMutex & SocketHandler::GetMutex | ( | ) | const [virtual] |
Get mutex reference for threadsafe operations.
Implements ISocketHandler.
Definition at line 184 of file SocketHandler.cpp.
References m_mutex.
00185 { 00186 return m_mutex; 00187 }
| void SocketHandler::RegStdLog | ( | StdLog * | log | ) | [virtual] |
Register StdLog object for error callback.
| log | Pointer to log class |
Implements ISocketHandler.
Definition at line 204 of file SocketHandler.cpp.
References m_stdlog.
00205 { 00206 m_stdlog = log; 00207 }
| 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 210 of file SocketHandler.cpp.
References m_stdlog.
Referenced by Add(), AddList(), Remove(), Resolve(), and Select().
00211 { 00212 if (m_stdlog) 00213 { 00214 m_stdlog -> error(this, p, user_text, err, sys_err, t); 00215 } 00216 }
| void SocketHandler::Add | ( | Socket * | p | ) | [virtual] |
Add socket instance to socket map.
Removal is always automatic.
Implements ISocketHandler.
Reimplemented in EventHandler.
Definition at line 219 of file SocketHandler.cpp.
References INVALID_SOCKET, LOG_LEVEL_FATAL, LOG_LEVEL_WARNING, LogError(), m_add, and m_delete.
Referenced by EventHandler::Add(), Resolve(), Socket::SocketThread::Run(), ResolvServer::Run(), and Select().
00220 { 00221 if (p -> GetSocket() == INVALID_SOCKET) 00222 { 00223 LogError(p, "Add", -1, "Invalid socket", LOG_LEVEL_WARNING); 00224 if (p -> CloseAndDelete()) 00225 { 00226 m_delete.push_back(p); 00227 } 00228 return; 00229 } 00230 if (m_add.find(p -> GetSocket()) != m_add.end()) 00231 { 00232 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in add queue", LOG_LEVEL_FATAL); 00233 m_delete.push_back(p); 00234 return; 00235 } 00236 m_add[p -> GetSocket()] = p; 00237 }
| void SocketHandler::Get | ( | SOCKET | s, | |
| bool & | r, | |||
| bool & | w, | |||
| bool & | e | |||
| ) | [virtual] |
Get status of read/write/exception file descriptor set for a socket.
Implements ISocketHandler.
Definition at line 240 of file SocketHandler.cpp.
References m_efds, m_rfds, and m_wfds.
00241 { 00242 if (s >= 0) 00243 { 00244 r = FD_ISSET(s, &m_rfds) ? true : false; 00245 w = FD_ISSET(s, &m_wfds) ? true : false; 00246 e = FD_ISSET(s, &m_efds) ? true : false; 00247 } 00248 }
| void SocketHandler::Set | ( | SOCKET | s, | |
| bool | bRead, | |||
| bool | bWrite, | |||
| bool | bException = true | |||
| ) | [virtual] |
Set read/write/exception file descriptor sets (fd_set).
Implements ISocketHandler.
Definition at line 251 of file SocketHandler.cpp.
References DEB, m_efds, m_rfds, and m_wfds.
Referenced by Select().
00252 { 00253 DEB( fprintf(stderr, "Set(%d, %s, %s, %s)\n", s, bRead ? "true" : "false", bWrite ? "true" : "false", bException ? "true" : "false");) 00254 if (s >= 0) 00255 { 00256 if (bRead) 00257 { 00258 if (!FD_ISSET(s, &m_rfds)) 00259 { 00260 FD_SET(s, &m_rfds); 00261 } 00262 } 00263 else 00264 { 00265 FD_CLR(s, &m_rfds); 00266 } 00267 if (bWrite) 00268 { 00269 if (!FD_ISSET(s, &m_wfds)) 00270 { 00271 FD_SET(s, &m_wfds); 00272 } 00273 } 00274 else 00275 { 00276 FD_CLR(s, &m_wfds); 00277 } 00278 if (bException) 00279 { 00280 if (!FD_ISSET(s, &m_efds)) 00281 { 00282 FD_SET(s, &m_efds); 00283 } 00284 } 00285 else 00286 { 00287 FD_CLR(s, &m_efds); 00288 } 00289 } 00290 }
| int SocketHandler::Select | ( | long | sec, | |
| long | usec | |||
| ) | [virtual] |
Wait for events, generate callbacks.
Implements ISocketHandler.
Definition at line 293 of file SocketHandler.cpp.
References Select().
Referenced by Socket::SocketThread::Run(), and ResolvServer::Run().
00294 { 00295 struct timeval tv; 00296 tv.tv_sec = sec; 00297 tv.tv_usec = usec; 00298 return Select(&tv); 00299 }
| int SocketHandler::Select | ( | ) | [virtual] |
This method will not return until an event has been detected.
Implements ISocketHandler.
Definition at line 302 of file SocketHandler.cpp.
References m_fds_callonconnect, m_fds_close, m_fds_detach, m_fds_erase, m_fds_retry, m_fds_timeout, and m_slave.
Referenced by EventHandler::EventLoop(), and Select().
00303 { 00304 if (m_fds_callonconnect.size() || 00305 #ifdef ENABLE_DETACH 00306 (!m_slave && m_fds_detach.size()) || 00307 #endif 00308 m_fds_timeout.size() || 00309 m_fds_retry.size() || 00310 m_fds_close.size() || 00311 m_fds_erase.size()) 00312 { 00313 return Select(0, 200000); 00314 } 00315 return Select(NULL); 00316 }
| int SocketHandler::Select | ( | struct timeval * | tsel | ) | [virtual] |
Wait for events, generate callbacks.
Implements ISocketHandler.
Definition at line 319 of file SocketHandler.cpp.
References Add(), AddList(), DEB, ENABLE_DETACH, Errno, INVALID_SOCKET, LIST_CALLONCONNECT, IMutex::Lock(), LOG_LEVEL_ERROR, LOG_LEVEL_FATAL, LOG_LEVEL_INFO, LOG_LEVEL_WARNING, LogError(), m_add, m_b_use_mutex, m_delete, m_efds, m_errcnt, m_fds, m_fds_callonconnect, m_fds_close, m_fds_detach, m_fds_erase, m_fds_retry, m_fds_timeout, m_maxsock, m_mutex, m_preverror, m_rfds, m_slave, m_sockets, m_tlast, m_wfds, Set(), StrError, IMutex::Unlock(), and Valid().
00320 { 00321 size_t ignore = 0; 00322 while (m_add.size() > ignore) 00323 { 00324 if (m_sockets.size() >= FD_SETSIZE) 00325 { 00326 LogError(NULL, "Select", (int)m_sockets.size(), "FD_SETSIZE reached", LOG_LEVEL_WARNING); 00327 break; 00328 } 00329 socket_m::iterator it = m_add.begin(); 00330 SOCKET s = it -> first; 00331 Socket *p = it -> second; 00332 DEB( fprintf(stderr, "Trying to add fd %d, m_add.size() %d, ignore %d\n", (int)s, (int)m_add.size(), (int)ignore);) 00333 // 00334 if (m_sockets.find(p -> GetSocket()) != m_sockets.end()) 00335 { 00336 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in controlled queue", LOG_LEVEL_FATAL); 00337 // %! it's a dup, don't add to delete queue, just ignore it 00338 m_delete.push_back(p); 00339 m_add.erase(it); 00340 // ignore++; 00341 continue; 00342 } 00343 if (!p -> CloseAndDelete()) 00344 { 00345 StreamSocket *scp = dynamic_cast<StreamSocket *>(p); 00346 if (scp && scp -> Connecting()) // 'Open' called before adding socket 00347 { 00348 Set(s,false,true); 00349 } 00350 else 00351 { 00352 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 00353 bool bWrite = tcp ? tcp -> GetOutputLength() != 0 : false; 00354 if (p -> IsDisableRead()) 00355 { 00356 Set(s, false, bWrite); 00357 } 00358 else 00359 { 00360 Set(s, true, bWrite); 00361 } 00362 } 00363 m_maxsock = (s > m_maxsock) ? s : m_maxsock; 00364 } 00365 else 00366 { 00367 LogError(p, "Add", (int)p -> GetSocket(), "Trying to add socket with SetCloseAndDelete() true", LOG_LEVEL_WARNING); 00368 } 00369 // only add to m_fds (process fd_set events) if 00370 // slave handler and detached/detaching socket 00371 // master handler and non-detached socket 00372 #ifdef ENABLE_DETACH 00373 if (!(m_slave ^ p -> IsDetach())) 00374 #endif 00375 { 00376 m_fds.push_back(s); 00377 } 00378 m_sockets[s] = p; 00379 // 00380 m_add.erase(it); 00381 } 00382 #ifdef MACOSX 00383 fd_set rfds; 00384 fd_set wfds; 00385 fd_set efds; 00386 FD_COPY(&m_rfds, &rfds); 00387 FD_COPY(&m_wfds, &wfds); 00388 FD_COPY(&m_efds, &efds); 00389 #else 00390 fd_set rfds = m_rfds; 00391 fd_set wfds = m_wfds; 00392 fd_set efds = m_efds; 00393 #endif 00394 int n; 00395 if (m_b_use_mutex) 00396 { 00397 m_mutex.Unlock(); 00398 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); 00399 m_mutex.Lock(); 00400 } 00401 else 00402 { 00403 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); 00404 } 00405 if (n == -1) 00406 { 00407 /* 00408 EBADF An invalid file descriptor was given in one of the sets. 00409 EINTR A non blocked signal was caught. 00410 EINVAL n is negative. Or struct timeval contains bad time values (<0). 00411 ENOMEM select was unable to allocate memory for internal tables. 00412 */ 00413 if (Errno != m_preverror || m_errcnt++ % 10000 == 0) 00414 { 00415 LogError(NULL, "select", Errno, StrError(Errno)); 00416 DEB( fprintf(stderr, "m_maxsock: %d\n", m_maxsock); 00417 fprintf(stderr, "%s\n", Errno == EINVAL ? "EINVAL" : 00418 Errno == EINTR ? "EINTR" : 00419 Errno == EBADF ? "EBADF" : 00420 Errno == ENOMEM ? "ENOMEM" : "<another>"); 00421 // test bad fd 00422 for (SOCKET i = 0; i <= m_maxsock; i++) 00423 { 00424 bool t = false; 00425 FD_ZERO(&rfds); 00426 FD_ZERO(&wfds); 00427 FD_ZERO(&efds); 00428 if (FD_ISSET(i, &m_rfds)) 00429 { 00430 FD_SET(i, &rfds); 00431 t = true; 00432 } 00433 if (FD_ISSET(i, &m_wfds)) 00434 { 00435 FD_SET(i, &wfds); 00436 t = true; 00437 } 00438 if (FD_ISSET(i, &m_efds)) 00439 { 00440 FD_SET(i, &efds); 00441 t = true; 00442 } 00443 if (t && m_sockets.find(i) == m_sockets.end()) 00444 { 00445 fprintf(stderr, "Bad fd in fd_set: %d\n", i); 00446 } 00447 } 00448 ) // DEB 00449 m_preverror = Errno; 00450 } 00452 } 00453 else 00454 if (!n) 00455 { 00456 m_preverror = -1; 00457 } 00458 else 00459 if (n > 0) 00460 { 00461 for (socket_v::iterator it2 = m_fds.begin(); it2 != m_fds.end() && n; it2++) 00462 { 00463 SOCKET i = *it2; 00464 if (FD_ISSET(i, &rfds)) 00465 { 00466 socket_m::iterator itmp = m_sockets.find(i); 00467 if (itmp != m_sockets.end()) // found 00468 { 00469 Socket *p = itmp -> second; 00470 // new SSL negotiate method 00471 #ifdef HAVE_OPENSSL 00472 if (p -> IsSSLNegotiate()) 00473 { 00474 p -> SSLNegotiate(); 00475 } 00476 else 00477 #endif 00478 { 00479 p -> OnRead(); 00480 } 00481 } 00482 else 00483 { 00484 LogError(NULL, "GetSocket/handler/1", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00485 } 00486 n--; 00487 } 00488 if (FD_ISSET(i, &wfds)) 00489 { 00490 socket_m::iterator itmp = m_sockets.find(i); 00491 if (itmp != m_sockets.end()) // found 00492 { 00493 Socket *p = itmp -> second; 00494 // new SSL negotiate method 00495 #ifdef HAVE_OPENSSL 00496 if (p -> IsSSLNegotiate()) 00497 { 00498 p -> SSLNegotiate(); 00499 } 00500 else 00501 #endif 00502 { 00503 p -> OnWrite(); 00504 } 00505 } 00506 else 00507 { 00508 LogError(NULL, "GetSocket/handler/2", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00509 } 00510 n--; 00511 } 00512 if (FD_ISSET(i, &efds)) 00513 { 00514 socket_m::iterator itmp = m_sockets.find(i); 00515 if (itmp != m_sockets.end()) // found 00516 { 00517 Socket *p = itmp -> second; 00518 p -> OnException(); 00519 } 00520 else 00521 { 00522 LogError(NULL, "GetSocket/handler/3", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00523 } 00524 n--; 00525 } 00526 } // m_fds loop 00527 m_preverror = -1; 00528 } // if (n > 0) 00529 00530 // check CallOnConnect - EVENT 00531 if (m_fds_callonconnect.size()) 00532 { 00533 socket_v tmp = m_fds_callonconnect; 00534 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) 00535 { 00536 Socket *p = NULL; 00537 { 00538 socket_m::iterator itmp = m_sockets.find(*it); 00539 if (itmp != m_sockets.end()) // found 00540 { 00541 p = itmp -> second; 00542 } 00543 else 00544 { 00545 LogError(NULL, "GetSocket/handler/4", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00546 } 00547 } 00548 if (p) 00549 { 00550 // if (p -> CallOnConnect() && p -> Ready() ) 00551 { 00552 p -> SetConnected(); // moved here from inside if (tcp) check below 00553 #ifdef HAVE_OPENSSL 00554 if (p -> IsSSL()) // SSL Enabled socket 00555 p -> OnSSLConnect(); 00556 else 00557 #endif 00558 #ifdef ENABLE_SOCKS4 00559 if (p -> Socks4()) 00560 p -> OnSocks4Connect(); 00561 else 00562 #endif 00563 { 00564 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 00565 if (tcp) 00566 { 00567 if (tcp -> GetOutputLength()) 00568 { 00569 p -> OnWrite(); 00570 } 00571