![]() |
SocketHandler Class ReferenceSocket container class, event generator.
More...
|
Public Member Functions | |
SocketHandler (StdLog *log=NULL) | |
SocketHandler constructor. | |
SocketHandler (Mutex &mutex, StdLog *log=NULL) | |
SocketHandler threadsafe constructor. | |
~SocketHandler () | |
Mutex & | 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. | |
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 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. | |
Mutex & | 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. | |
void | Remove (Socket *) |
Remove socket from socket map, used by Socket class. | |
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. | |
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 55 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 59 of file SocketHandler.h.
SocketHandler::SocketHandler | ( | StdLog * | log = NULL |
) |
SocketHandler constructor.
log | Optional log class pointer |
Definition at line 58 of file SocketHandler.cpp.
References m_efds, m_rfds, and m_wfds.
00059 :m_stdlog(p) 00060 ,m_mutex(m_mutex) 00061 ,m_b_use_mutex(false) 00062 ,m_maxsock(0) 00063 ,m_preverror(-1) 00064 ,m_errcnt(0) 00065 ,m_tlast(0) 00066 #ifdef ENABLE_SOCKS4 00067 ,m_socks4_host(0) 00068 ,m_socks4_port(0) 00069 ,m_bTryDirect(false) 00070 #endif 00071 #ifdef ENABLE_RESOLVER 00072 ,m_resolv_id(0) 00073 ,m_resolver(NULL) 00074 #endif 00075 #ifdef ENABLE_POOL 00076 ,m_b_enable_pool(false) 00077 #endif 00078 #ifdef ENABLE_TRIGGERS 00079 ,m_next_trigger_id(0) 00080 #endif 00081 #ifdef ENABLE_DETACH 00082 ,m_slave(false) 00083 #endif 00084 { 00085 FD_ZERO(&m_rfds); 00086 FD_ZERO(&m_wfds); 00087 FD_ZERO(&m_efds); 00088 }
SocketHandler threadsafe constructor.
mutex | Externally declared mutex variable | |
log | Optional log class pointer |
Definition at line 91 of file SocketHandler.cpp.
References Mutex::Lock, m_efds, m_mutex, m_rfds, and m_wfds.
00092 :m_stdlog(p) 00093 ,m_mutex(mutex) 00094 ,m_b_use_mutex(true) 00095 ,m_maxsock(0) 00096 ,m_preverror(-1) 00097 ,m_errcnt(0) 00098 ,m_tlast(0) 00099 #ifdef ENABLE_SOCKS4 00100 ,m_socks4_host(0) 00101 ,m_socks4_port(0) 00102 ,m_bTryDirect(false) 00103 #endif 00104 #ifdef ENABLE_RESOLVER 00105 ,m_resolv_id(0) 00106 ,m_resolver(NULL) 00107 #endif 00108 #ifdef ENABLE_POOL 00109 ,m_b_enable_pool(false) 00110 #endif 00111 #ifdef ENABLE_TRIGGERS 00112 ,m_next_trigger_id(0) 00113 #endif 00114 #ifdef ENABLE_DETACH 00115 ,m_slave(false) 00116 #endif 00117 { 00118 m_mutex.Lock(); 00119 FD_ZERO(&m_rfds); 00120 FD_ZERO(&m_wfds); 00121 FD_ZERO(&m_efds); 00122 }
SocketHandler::~SocketHandler | ( | ) |
Definition at line 125 of file SocketHandler.cpp.
References DEB, ENABLE_DETACH, ENABLE_RESOLVER, m_b_use_mutex, m_mutex, m_resolver, m_slave, m_sockets, and Mutex::Unlock().
00126 { 00127 #ifdef ENABLE_RESOLVER 00128 if (m_resolver) 00129 { 00130 m_resolver -> Quit(); 00131 } 00132 #endif 00133 { 00134 while (m_sockets.size()) 00135 { 00136 DEB( fprintf(stderr, "Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) 00137 socket_m::iterator it = m_sockets.begin(); 00138 Socket *p = it -> second; 00139 if (p) 00140 { 00141 DEB( fprintf(stderr, " fd %d\n", p -> GetSocket());) 00142 p -> Close(); 00143 DEB( fprintf(stderr, " fd closed %d\n", p -> GetSocket());) 00144 // p -> OnDelete(); // hey, I turn this back on. what's the worst that could happen??!! 00145 // MinionSocket breaks, calling MinderHandler methods in OnDelete - 00146 // MinderHandler is already gone when that happens... 00147 00148 // only delete socket when controlled 00149 // ie master sockethandler can delete non-detached sockets 00150 // and a slave sockethandler can only delete a detach socket 00151 if (p -> DeleteByHandler() 00152 #ifdef ENABLE_DETACH 00153 && !(m_slave ^ p -> IsDetached()) 00154 #endif 00155 ) 00156 { 00157 p -> SetErasedByHandler(); 00158 delete p; 00159 } 00160 m_sockets.erase(it); 00161 } 00162 else 00163 { 00164 m_sockets.erase(it); 00165 } 00166 DEB( fprintf(stderr, "next\n");) 00167 } 00168 DEB( fprintf(stderr, "/Emptying sockets list in SocketHandler destructor, %d instances\n", (int)m_sockets.size());) 00169 } 00170 #ifdef ENABLE_RESOLVER 00171 if (m_resolver) 00172 { 00173 delete m_resolver; 00174 } 00175 #endif 00176 if (m_b_use_mutex) 00177 { 00178 m_mutex.Unlock(); 00179 } 00180 }
Mutex & SocketHandler::GetMutex | ( | ) | const [virtual] |
Get mutex reference for threadsafe operations.
Implements ISocketHandler.
Definition at line 183 of file SocketHandler.cpp.
References m_mutex.
00184 { 00185 return m_mutex; 00186 }
void SocketHandler::RegStdLog | ( | StdLog * | log | ) | [virtual] |
Register StdLog object for error callback.
log | Pointer to log class |
Implements ISocketHandler.
Definition at line 203 of file SocketHandler.cpp.
References m_stdlog.
00204 { 00205 m_stdlog = log; 00206 }
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 209 of file SocketHandler.cpp.
References m_stdlog.
Referenced by Add(), AddList(), Remove(), Resolve(), and Select().
00210 { 00211 if (m_stdlog) 00212 { 00213 m_stdlog -> error(this, p, user_text, err, sys_err, t); 00214 } 00215 }
void SocketHandler::Add | ( | Socket * | ) | [virtual] |
Add socket instance to socket map.
Removal is always automatic.
Implements ISocketHandler.
Reimplemented in EventHandler.
Definition at line 218 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().
00219 { 00220 if (p -> GetSocket() == INVALID_SOCKET) 00221 { 00222 LogError(p, "Add", -1, "Invalid socket", LOG_LEVEL_WARNING); 00223 if (p -> CloseAndDelete()) 00224 { 00225 m_delete.push_back(p); 00226 } 00227 return; 00228 } 00229 if (m_add.find(p -> GetSocket()) != m_add.end()) 00230 { 00231 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in add queue", LOG_LEVEL_FATAL); 00232 m_delete.push_back(p); 00233 return; 00234 } 00235 m_add[p -> GetSocket()] = p; 00236 }
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 239 of file SocketHandler.cpp.
References m_efds, m_rfds, and m_wfds.
00240 { 00241 if (s >= 0) 00242 { 00243 r = FD_ISSET(s, &m_rfds) ? true : false; 00244 w = FD_ISSET(s, &m_wfds) ? true : false; 00245 e = FD_ISSET(s, &m_efds) ? true : false; 00246 } 00247 }
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 250 of file SocketHandler.cpp.
References DEB, m_efds, m_rfds, and m_wfds.
Referenced by Select().
00251 { 00252 DEB( fprintf(stderr, "Set(%d, %s, %s, %s)\n", s, bRead ? "true" : "false", bWrite ? "true" : "false", bException ? "true" : "false");) 00253 if (s >= 0) 00254 { 00255 if (bRead) 00256 { 00257 if (!FD_ISSET(s, &m_rfds)) 00258 { 00259 FD_SET(s, &m_rfds); 00260 } 00261 } 00262 else 00263 { 00264 FD_CLR(s, &m_rfds); 00265 } 00266 if (bWrite) 00267 { 00268 if (!FD_ISSET(s, &m_wfds)) 00269 { 00270 FD_SET(s, &m_wfds); 00271 } 00272 } 00273 else 00274 { 00275 FD_CLR(s, &m_wfds); 00276 } 00277 if (bException) 00278 { 00279 if (!FD_ISSET(s, &m_efds)) 00280 { 00281 FD_SET(s, &m_efds); 00282 } 00283 } 00284 else 00285 { 00286 FD_CLR(s, &m_efds); 00287 } 00288 } 00289 }
int SocketHandler::Select | ( | long | sec, | |
long | usec | |||
) | [virtual] |
Wait for events, generate callbacks.
Implements ISocketHandler.
Definition at line 292 of file SocketHandler.cpp.
References Select().
Referenced by Socket::SocketThread::Run(), and ResolvServer::Run().
00293 { 00294 struct timeval tv; 00295 tv.tv_sec = sec; 00296 tv.tv_usec = usec; 00297 return Select(&tv); 00298 }
int SocketHandler::Select | ( | ) | [virtual] |
This method will not return until an event has been detected.
Implements ISocketHandler.
Definition at line 301 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().
00302 { 00303 if (m_fds_callonconnect.size() || 00304 #ifdef ENABLE_DETACH 00305 (!m_slave && m_fds_detach.size()) || 00306 #endif 00307 m_fds_timeout.size() || 00308 m_fds_retry.size() || 00309 m_fds_close.size() || 00310 m_fds_erase.size()) 00311 { 00312 return Select(0, 200000); 00313 } 00314 return Select(NULL); 00315 }
int SocketHandler::Select | ( | struct timeval * | tsel | ) | [virtual] |
Wait for events, generate callbacks.
Implements ISocketHandler.
Definition at line 318 of file SocketHandler.cpp.
References Add(), AddList(), DEB, ENABLE_DETACH, Errno, HAVE_OPENSSL, INVALID_SOCKET, LIST_CALLONCONNECT, Mutex::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, Mutex::Unlock(), and Valid().
00319 { 00320 size_t ignore = 0; 00321 while (m_add.size() > ignore) 00322 { 00323 if (m_sockets.size() >= FD_SETSIZE) 00324 { 00325 LogError(NULL, "Select", (int)m_sockets.size(), "FD_SETSIZE reached", LOG_LEVEL_WARNING); 00326 break; 00327 } 00328 socket_m::iterator it = m_add.begin(); 00329 SOCKET s = it -> first; 00330 Socket *p = it -> second; 00331 DEB( fprintf(stderr, "Trying to add fd %d, m_add.size() %d, ignore %d\n", (int)s, (int)m_add.size(), (int)ignore);) 00332 // 00333 if (m_sockets.find(p -> GetSocket()) != m_sockets.end()) 00334 { 00335 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in controlled queue", LOG_LEVEL_FATAL); 00336 // %! it's a dup, don't add to delete queue, just ignore it 00337 m_delete.push_back(p); 00338 m_add.erase(it); 00339 // ignore++; 00340 continue; 00341 } 00342 if (!p -> CloseAndDelete()) 00343 { 00344 StreamSocket *scp = dynamic_cast<StreamSocket *>(p); 00345 if (scp && scp -> Connecting()) // 'Open' called before adding socket 00346 { 00347 Set(s,false,true); 00348 } 00349 else 00350 { 00351 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 00352 bool bWrite = tcp ? tcp -> GetOutputLength() != 0 : false; 00353 if (p -> IsDisableRead()) 00354 { 00355 Set(s, false, bWrite); 00356 } 00357 else 00358 { 00359 Set(s, true, bWrite); 00360 } 00361 } 00362 m_maxsock = (s > m_maxsock) ? s : m_maxsock; 00363 } 00364 else 00365 { 00366 LogError(p, "Add", (int)p -> GetSocket(), "Trying to add socket with SetCloseAndDelete() true", LOG_LEVEL_WARNING); 00367 } 00368 // only add to m_fds (process fd_set events) if 00369 // slave handler and detached/detaching socket 00370 // master handler and non-detached socket 00371 #ifdef ENABLE_DETACH 00372 if (!(m_slave ^ p -> IsDetach())) 00373 #endif 00374 { 00375 m_fds.push_back(s); 00376 } 00377 m_sockets[s] = p; 00378 // 00379 m_add.erase(it); 00380 } 00381 #ifdef MACOSX 00382 fd_set rfds; 00383 fd_set wfds; 00384 fd_set efds; 00385 FD_COPY(&m_rfds, &rfds); 00386 FD_COPY(&m_wfds, &wfds); 00387 FD_COPY(&m_efds, &efds); 00388 #else 00389 fd_set rfds = m_rfds; 00390 fd_set wfds = m_wfds; 00391 fd_set efds = m_efds; 00392 #endif 00393 int n; 00394 if (m_b_use_mutex) 00395 { 00396 m_mutex.Unlock(); 00397 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); 00398 m_mutex.Lock(); 00399 } 00400 else 00401 { 00402 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel); 00403 } 00404 if (n == -1) 00405 { 00406 /* 00407 EBADF An invalid file descriptor was given in one of the sets. 00408 EINTR A non blocked signal was caught. 00409 EINVAL n is negative. Or struct timeval contains bad time values (<0). 00410 ENOMEM select was unable to allocate memory for internal tables. 00411 */ 00412 if (Errno != m_preverror || m_errcnt++ % 10000 == 0) 00413 { 00414 LogError(NULL, "select", Errno, StrError(Errno)); 00415 DEB( fprintf(stderr, "m_maxsock: %d\n", m_maxsock); 00416 fprintf(stderr, "%s\n", Errno == EINVAL ? "EINVAL" : 00417 Errno == EINTR ? "EINTR" : 00418 Errno == EBADF ? "EBADF" : 00419 Errno == ENOMEM ? "ENOMEM" : "<another>"); 00420 // test bad fd 00421 for (SOCKET i = 0; i <= m_maxsock; i++) 00422 { 00423 bool t = false; 00424 FD_ZERO(&rfds); 00425 FD_ZERO(&wfds); 00426 FD_ZERO(&efds); 00427 if (FD_ISSET(i, &m_rfds)) 00428 { 00429 FD_SET(i, &rfds); 00430 t = true; 00431 } 00432 if (FD_ISSET(i, &m_wfds)) 00433 { 00434 FD_SET(i, &wfds); 00435 t = true; 00436 } 00437 if (FD_ISSET(i, &m_efds)) 00438 { 00439 FD_SET(i, &efds); 00440 t = true; 00441 } 00442 if (t && m_sockets.find(i) == m_sockets.end()) 00443 { 00444 fprintf(stderr, "Bad fd in fd_set: %d\n", i); 00445 } 00446 } 00447 ) // DEB 00448 m_preverror = Errno; 00449 } 00451 } 00452 else 00453 if (!n) 00454 { 00455 m_preverror = -1; 00456 } 00457 else 00458 if (n > 0) 00459 { 00460 for (socket_v::iterator it2 = m_fds.begin(); it2 != m_fds.end() && n; it2++) 00461 { 00462 SOCKET i = *it2; 00463 if (FD_ISSET(i, &rfds)) 00464 { 00465 socket_m::iterator itmp = m_sockets.find(i); 00466 if (itmp != m_sockets.end()) // found 00467 { 00468 Socket *p = itmp -> second; 00469 // new SSL negotiate method 00470 #ifdef HAVE_OPENSSL 00471 if (p -> IsSSLNegotiate()) 00472 { 00473 p -> SSLNegotiate(); 00474 } 00475 else 00476 #endif 00477 { 00478 p -> OnRead(); 00479 } 00480 } 00481 else 00482 { 00483 LogError(NULL, "GetSocket/handler/1", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00484 } 00485 n--; 00486 } 00487 if (FD_ISSET(i, &wfds)) 00488 { 00489 socket_m::iterator itmp = m_sockets.find(i); 00490 if (itmp != m_sockets.end()) // found 00491 { 00492 Socket *p = itmp -> second; 00493 // new SSL negotiate method 00494 #ifdef HAVE_OPENSSL 00495 if (p -> IsSSLNegotiate()) 00496 { 00497 p -> SSLNegotiate(); 00498 } 00499 else 00500 #endif 00501 { 00502 p -> OnWrite(); 00503 } 00504 } 00505 else 00506 { 00507 LogError(NULL, "GetSocket/handler/2", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00508 } 00509 n--; 00510 } 00511 if (FD_ISSET(i, &efds)) 00512 { 00513 socket_m::iterator itmp = m_sockets.find(i); 00514 if (itmp != m_sockets.end()) // found 00515 { 00516 Socket *p = itmp -> second; 00517 p -> OnException(); 00518 } 00519 else 00520 { 00521 LogError(NULL, "GetSocket/handler/3", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00522 } 00523 n--; 00524 } 00525 } // m_fds loop 00526 m_preverror = -1; 00527 } // if (n > 0) 00528 00529 // check CallOnConnect - EVENT 00530 if (m_fds_callonconnect.size()) 00531 { 00532 socket_v tmp = m_fds_callonconnect; 00533 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) 00534 { 00535 Socket *p = NULL; 00536 { 00537 socket_m::iterator itmp = m_sockets.find(*it); 00538 if (itmp != m_sockets.end()) // found 00539 { 00540 p = itmp -> second; 00541 } 00542 else 00543 { 00544 LogError(NULL, "GetSocket/handler/4", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00545 } 00546 } 00547 if (p) 00548 { 00549 // if (p -> CallOnConnect() && p -> Ready() ) 00550 { 00551 p -> SetConnected(); // moved here from inside if (tcp) check below 00552 #ifdef HAVE_OPENSSL 00553 if (p -> IsSSL()) // SSL Enabled socket 00554 p -> OnSSLConnect(); 00555 else 00556 #endif 00557 #ifdef ENABLE_SOCKS4 00558 if (p -> Socks4()) 00559 p -> OnSocks4Connect(); 00560 else 00561 #endif 00562 { 00563 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 00564 if (tcp) 00565 { 00566 if (tcp -> GetOutputLength()) 00567 { 00568 p -> OnWrite(); 00569 } 00570 } 00571 #ifdef ENABLE_RECONNECT 00572 if (tcp && tcp -> IsReconnect()) 00573 p -> OnReconnect(); 00574 else 00575 #endif 00576 { 00577 // LogError(p, "Calling OnConnect", 0, "Because CallOnConnect", LOG_LEVEL_INFO); 00578 p -> OnConnect(); 00579 } 00580 } 00581 // p -> SetCallOnConnect( false ); 00582 AddList(p -> GetSocket(), LIST_CALLONCONNECT, false); 00583 } 00584 } 00585 } 00586 } 00587 #ifdef ENABLE_DETACH 00588 // check detach of socket if master handler - EVENT 00589 if (!m_slave && m_fds_detach.size()) 00590 { 00591 // %! why not using tmp list here??!? 00592 for (socket_v::iterator it = m_fds_detach.begin(); it != m_fds_detach.end(); it++) 00593 { 00594 Socket *p = NULL; 00595 { 00596 socket_m::iterator itmp = m_sockets.find(*it); 00597 if (itmp != m_sockets.end()) // found 00598 { 00599 p = itmp -> second; 00600 } 00601 else 00602 { 00603 LogError(NULL, "GetSocket/handler/5", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00604 } 00605 } 00606 if (p) 00607 { 00608 // if (p -> IsDetach()) 00609 { 00610 Set(p -> GetSocket(), false, false, false); 00611 // After DetachSocket(), all calls to Handler() will return a reference 00612 // to the new slave SocketHandler running in the new thread. 00613 p -> DetachSocket(); 00614 // Adding the file descriptor to m_fds_erase will now also remove the 00615 // socket from the detach queue - tnx knightmad 00616 m_fds_erase.push_back(p -> GetSocket()); 00617 } 00618 } 00619 } 00620 } 00621 #endif 00622 // check Connecting - connection timeout - conditional event 00623 if (m_fds_timeout.size()) 00624 { 00625 time_t tnow = time(NULL); 00626 if (tnow != m_tlast) 00627 { 00628 socket_v tmp = m_fds_timeout; 00629 DEB( fprintf(stderr, "Checking %d socket(s) for timeout\n", tmp.size());) 00630 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) 00631 { 00632 Socket *p = NULL; 00633 { 00634 socket_m::iterator itmp = m_sockets.find(*it); 00635 if (itmp != m_sockets.end()) // found 00636 { 00637 p = itmp -> second; 00638 } 00639 else 00640 { 00641 itmp = m_add.find(*it); 00642 if (itmp != m_add.end()) 00643 { 00644 p = itmp -> second; 00645 } 00646 else 00647 { 00648 LogError(NULL, "GetSocket/handler/6", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00649 } 00650 } 00651 } 00652 if (p) 00653 { 00654 if (p -> Timeout(tnow)) 00655 { 00656 StreamSocket *scp = dynamic_cast<StreamSocket *>(p); 00657 if (scp && scp -> Connecting()) 00658 p -> OnConnectTimeout(); 00659 else 00660 p -> OnTimeout(); 00661 p -> SetTimeout(0); 00662 } 00663 } 00664 } 00665 m_tlast = tnow; 00666 } // tnow != tlast 00667 } 00668 // check retry client connect - EVENT 00669 if (m_fds_retry.size()) 00670 { 00671 socket_v tmp = m_fds_retry; 00672 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) 00673 { 00674 Socket *p = NULL; 00675 { 00676 socket_m::iterator itmp = m_sockets.find(*it); 00677 if (itmp != m_sockets.end()) // found 00678 { 00679 p = itmp -> second; 00680 } 00681 else 00682 { 00683 LogError(NULL, "GetSocket/handler/7", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00684 } 00685 } 00686 if (p) 00687 { 00688 // if (p -> RetryClientConnect()) 00689 { 00690 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 00691 SOCKET nn = *it; //(*it3).first; 00692 tcp -> SetRetryClientConnect(false); 00693 DEB( fprintf(stderr, "Close() before retry client connect\n");) 00694 p -> Close(); // removes from m_fds_retry 00695 std::auto_ptr<SocketAddress> ad = p -> GetClientRemoteAddress(); 00696 if (ad.get()) 00697 { 00698 tcp -> Open(*ad); 00699 } 00700 else 00701 { 00702 LogError(p, "RetryClientConnect", 0, "no address", LOG_LEVEL_ERROR); 00703 } 00704 Add(p); 00705 m_fds_erase.push_back(nn); 00706 } 00707 } 00708 } 00709 } 00710 // check close and delete - conditional event 00711 if (m_fds_close.size()) 00712 { 00713 socket_v tmp = m_fds_close; 00714 DEB( fprintf(stderr, "m_fds_close.size() == %d\n", (int)m_fds_close.size());) 00715 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++) 00716 { 00717 Socket *p = NULL; 00718 { 00719 socket_m::iterator itmp = m_sockets.find(*it); 00720 if (itmp != m_sockets.end()) // found 00721 { 00722 p = itmp -> second; 00723 } 00724 else 00725 { 00726 itmp = m_add.find(*it); 00727 if (itmp != m_add.end()) 00728 { 00729 p = itmp -> second; 00730 } 00731 else 00732 { 00733 LogError(NULL, "GetSocket/handler/8", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING); 00734 } 00735 } 00736 } 00737 if (p) 00738 { 00739 // if (p -> CloseAndDelete() ) 00740 { 00741 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p); 00742 // new graceful tcp - flush and close timeout 5s 00743 if (tcp && p -> IsConnected() && tcp -> GetFlushBeforeClose() && 00744 #ifdef HAVE_OPENSSL 00745 !tcp -> IsSSL() && 00746 #endif 00747 p -> TimeSinceClose() < 5) 00748 { 00749 DEB( fprintf(stderr, " close(1)\n");) 00750 if (tcp -> GetOutputLength()) 00751 { 00752 LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Sending all data before closing", LOG_LEVEL_INFO); 00753 } 00754 else // shutdown write when output buffer is empty 00755 if (!(tcp -> GetShutdown() & SHUT_WR)) 00756 { 00757 SOCKET nn = *it; 00758 if (nn != INVALID_SOCKET && shutdown(nn, SHUT_WR) == -1) 00759 { 00760 LogError(p, "graceful shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR); 00761 } 00762 tcp -> SetShutdown(SHUT_WR); 00763 } 00764 } 00765 else 00766 #ifdef ENABLE_RECONNECT 00767 if (tcp && p -> IsConnected() && tcp -> Reconnect()) 00768 { 00769 SOCKET nn = *it; //(*it3).first; 00770 DEB( fprintf(stderr, " close(2) fd %d\n", nn);) 00771 p -> SetCloseAndDelete(false); 00772 tcp -> SetIsReconnect(); 00773 p -> SetConnected(false); 00774 DEB( fprintf(stderr, "Close() before reconnect\n");) 00775 p -> Close(); // dispose of old file descriptor (Open creates a new) 00776 p -> OnDisconnect(); 00777 std::auto_ptr<SocketAddress> ad = p -> GetClientRemoteAddress(); 00778 if (ad.get()) 00779 { 00780 tcp -> Open(*ad); 00781 } 00782 else 00783 { 00784 LogError(p, "Reconnect", 0, "no address", LOG_LEVEL_ERROR); 00785 } 00786 tcp -> ResetConnectionRetries(); 00787 Add(p); 00788 m_fds_erase.push_back(nn); 00789 } 00790 else 00791 #endif 00792 { 00793 SOCKET nn = *it; //(*it3).first; 00794 DEB( fprintf(stderr, " close(3) fd %d GetSocket() %d\n", nn, p -> GetSocket());) 00795 if (tcp && p -> IsConnected() && tcp -> GetOutputLength()) 00796 { 00797 LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Closing socket while data still left to send", LOG_LEVEL_WARNING); 00798 } 00799 #ifdef ENABLE_POOL 00800 if (p -> Retain() && !p -> Lost()) 00801 { 00802 PoolSocket *p2 = new PoolSocket(*this, p); 00803 p2 -> SetDeleteByHandler(); 00804 Add(p2); 00805 // 00806 p -> SetCloseAndDelete(false); // added - remove from m_fds_close 00807 } 00808 else 00809 #endif // ENABLE_POOL 00810 { 00811 Set(p -> GetSocket(),false,false,false); 00812 DEB( fprintf(stderr, "Close() before OnDelete\n");) 00813 p -> Close(); 00814 } 00815 p -> OnDelete(); 00816 if (p -> DeleteByHandler()) 00817 { 00818 p -> SetErasedByHandler(); 00819 } 00820 m_fds_erase.push_back(nn); 00821 } 00822 } 00823 } 00824 } 00825 } 00826 00827 // check erased sockets 00828 bool check_max_fd = false; 00829 while (m_fds_erase.size()) 00830 { 00831 socket_v::iterator it = m_fds_erase.begin(); 00832 SOCKET nn = *it; 00833 #ifdef ENABLE_DETACH 00834 { 00835 for (socket_v::iterator it = m_fds_detach.begin(); it != m_fds_detach.end(); it++) 00836 { 00837 if (*it == nn) 00838 { 00839 m_fds_detach.erase(it); 00840 break; 00841 } 00842 } 00843 } 00844 #endif 00845 { 00846 for (socket_v::iterator it = m_fds.begin(); it != m_fds.end(); it++) 00847 { 00848 if (*it == nn) 00849 { 00850 m_fds.erase(it); 00851 break; 00852 } 00853 } 00854 } 00855 { 00856 socket_m::iterator it = m_sockets.find(nn); 00857 if (it != m_sockets.end()) 00858 { 00859 Socket *p = it -> second; 00860 /* Sometimes a SocketThread class can finish its run before the master 00861 sockethandler gets here. In that case, the SocketThread has set the 00862 'ErasedByHandler' flag on the socket which will make us end up with a 00863 double delete on the socket instance. 00864 The fix is to make sure that the master sockethandler only can delete 00865 non-detached sockets, and a slave sockethandler only can delete 00866 detach sockets. */ 00867 if (p -> ErasedByHandler() 00868 #ifdef ENABLE_DETACH 00869 && !(m_slave ^ p -> IsDetached()) 00870 #endif 00871 ) 00872 { 00873 #ifdef ENABLE_TRIGGERS 00874 bool again = false; 00875 do 00876 { 00877 again = false; 00878 for (std::map<int, Socket *>::iterator it = m_trigger_src.begin(); it != m_trigger_src.end(); it++) 00879 { 00880 int id = it -> first; 00881 Socket *src = it -> second; 00882 if (src == p) 00883 { 00884 for (std::map<Socket *, bool>::iterator it = m_trigger_dst[id].begin(); it != m_trigger_dst[id].end(); it++) 00885 { 00886 Socket *dst = it -> first; 00887 if (Valid(dst)) 00888 { 00889 dst -> OnCancelled(id); 00890 } 00891 } 00892 m_trigger_src.erase(m_trigger_src.find(id)); 00893 m_trigger_dst.erase(m_trigger_dst.find(id)); 00894 again = true; 00895 break; 00896 } 00897 } 00898 } while (again); 00899 #endif 00900 delete p; 00901 } 00902 m_sockets.erase(it); 00903 } 00904 } 00905 m_fds_erase.erase(it); 00906 check_max_fd = true; 00907 } 00908 // calculate max file descriptor for select() call 00909 if (check_max_fd) 00910 { 00911 m_maxsock = 0; 00912 for (socket_v::iterator it = m_fds.begin(); it != m_fds.end(); it++) 00913 { 00914 SOCKET s = *it; 00915 m_maxsock = s > m_maxsock ? s : m_maxsock; 00916 } 00917 } 00918 // remove Add's that fizzed 00919 while (m_delete.size()) 00920 { 00921 std::list<Socket *>::iterator it = m_delete.begin(); 00922 Socket *p = *it; 00923 p -> OnDelete(); 00924 m_delete.erase(it); 00925 if (p -> DeleteByHandler() 00926 #ifdef ENABLE_DETACH 00927 && !(m_slave ^ p -> IsDetached()) 00928 #endif 00929 ) 00930 { 00931 p -> SetErasedByHandler(); 00932 #ifdef ENABLE_TRIGGERS 00933 bool again = false; 00934 do 00935 { 00936 again = false; 00937 for (std::map<int, Socket *>::iterator it = m_trigger_src.begin(); it != m_trigger_src.end(); it++) 00938 { 00939 int id = it -> first; 00940 Socket *src = it -> second; 00941 if (src == p) 00942 { 00943 for (std::map<Socket *, bool>::iterator it = m_trigger_dst[id].begin(); it != m_trigger_dst[id].end(); it++) 00944 { 00945 Socket *dst = it -> first; 00946 if (Valid(dst)) 00947 { 00948 dst -> OnCancelled(id); 00949 } 00950 } 00951 m_trigger_src.erase(m_trigger_src.find(id)); 00952 m_trigger_dst.erase(m_trigger_dst.find(id)); 00953 again = true; 00954 break; 00955 } 00956 } 00957 } while (again); 00958 #endif 00959 delete p; 00960 } 00961 } 00962 return n; 00963 }
bool SocketHandler::Valid | ( | Socket * | ) | [virtual] |
Check that a socket really is handled by this socket handler.
Implements ISocketHandler.
Definition at line 966 of file SocketHandler.cpp.
References m_sockets.
Referenced by AddList(), EventHandler::CheckEvents(), and Select().
00967 { 00968 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++) 00969 { 00970 Socket *p = it -> second; 00971 if (p0 == p) 00972 return true; 00973 } 00974 return false; 00975 }
size_t SocketHandler::GetCount | ( | ) | [virtual] |
Return number of sockets handled by this handler.
Implements ISocketHandler.
Definition at line 984 of file SocketHandler.cpp.
References m_add, m_delete, and m_sockets.
Referenced by Socket::SocketThread::Run().
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 978 of file SocketHandler.cpp.
Called by Socket when a socket changes state.
Implements ISocketHandler.
Definition at line 1265 of file SocketHandler.cpp.
References DEB, ENABLE_DETACH, INVALID_SOCKET, LIST_CALLONCONNECT, LIST_CLOSE, LIST_DETACH, LIST_RETRY, LIST_TIMEOUT, LOG_LEVEL_INFO, LogError(), m_fds_callonconnect, m_fds_close, m_fds_detach, m_fds_retry, m_fds_timeout, and Valid().
Referenced by Select().
01266 { 01267 if (s == INVALID_SOCKET) 01268 { 01269 DEB( fprintf(stderr, "AddList: invalid_socket\n");) 01270 return; 01271 } 01272 socket_v& ref = 01273 (which_one == LIST_CALLONCONNECT) ? m_fds_callonconnect : 01274 #ifdef ENABLE_DETACH 01275 (which_one == LIST_DETACH) ? m_fds_detach : 01276 #endif 01277 (which_one == LIST_TIMEOUT) ? m_fds_timeout : 01278 (which_one == LIST_RETRY) ? m_fds_retry : 01279 (which_one == LIST_CLOSE) ? m_fds_close : m_fds_close; 01280 if (add) 01281 { 01282 #ifdef ENABLE_DETACH 01283 DEB( fprintf(stderr, "AddList; %5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" : 01284 (which_one == LIST_DETACH) ? "Detach" : 01285 (which_one == LIST_TIMEOUT) ? "Timeout" : 01286 (which_one == LIST_RETRY) ? "Retry" : 01287 (which_one == LIST_CLOSE) ? "Close" : "<undef>", 01288 add ? "Add" : "Remove");) 01289 #else 01290 DEB( fprintf(stderr, "AddList; %5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" : 01291 (which_one == LIST_TIMEOUT) ? "Timeout" : 01292 (which_one == LIST_RETRY) ? "Retry" : 01293 (which_one == LIST_CLOSE) ? "Close" : "<undef>", 01294 add ? "Add" : "Remove");) 01295 #endif 01296 } 01297 if (add) 01298 { 01299 for (socket_v::iterator it = ref.begin(); it != ref.end(); it++) 01300 { 01301 if (*it == s) // already there 01302 { 01303 return; 01304 } 01305 } 01306 ref.push_back(s); 01307 return; 01308 } 01309 // remove 01310 for (socket_v::iterator it = ref.begin(); it != ref.end(); it++) 01311 { 01312 if (*it == s) 01313 { 01314 ref.erase(it); 01315 break; 01316 } 01317 } 01318 //DEB( fprintf(stderr, "/AddList\n");) 01319 }
ISocketHandler::PoolSocket * SocketHandler::FindConnection | ( | int | type, | |
const std::string & | protocol, | |||
SocketAddress & | ||||
) | [virtual] |
Find available open connection (used by connection pool).
Implements ISocketHandler.
Definition at line 1153 of file SocketHandler.cpp.
References m_sockets.
01154 { 01155 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end() && m_sockets.size(); it++) 01156 { 01157 PoolSocket *pools = dynamic_cast<PoolSocket *>(it -> second); 01158 if (pools) 01159 { 01160 if (pools -> GetSocketType() == type && 01161 pools -> GetSocketProtocol() == protocol && 01162 // %! pools -> GetClientRemoteAddress() && 01163 *pools -> GetClientRemoteAddress() == ad) 01164 { 01165 m_sockets.erase(it); 01166 pools -> SetRetain(); // avoid Close in Socket destructor 01167 return pools; // Caller is responsible that this socket is deleted 01168 } 01169 } 01170 } 01171 return NULL; 01172 }
void SocketHandler::EnablePool | ( | bool | x = true |
) | [virtual] |
Enable connection pool (by default disabled).
Implements ISocketHandler.
Definition at line 1175 of file SocketHandler.cpp.
References m_b_enable_pool.
01176 { 01177 m_b_enable_pool = x; 01178 }
bool SocketHandler::PoolEnabled | ( | ) | [virtual] |
Check pool status.
Implements ISocketHandler.
Definition at line 1181 of file SocketHandler.cpp.
References m_b_enable_pool.
01182 { 01183 return m_b_enable_pool; 01184 }
void SocketHandler::SetSocks4Host | ( | ipaddr_t | ) | [virtual] |
Set socks4 server ip that all new tcp sockets should use.
Implements ISocketHandler.
Definition at line 991 of file SocketHandler.cpp.
References m_socks4_host.
00992 { 00993 m_socks4_host = a; 00994 }
void SocketHandler::SetSocks4Host | ( | const std::string & | ) | [virtual] |
Set socks4 server hostname that all new tcp sockets should use.
Implements ISocketHandler.
Definition at line 997 of file SocketHandler.cpp.
References m_socks4_host, and Utility::u2ip().
00998 { 00999 Utility::u2ip(host, m_socks4_host); 01000 }
void SocketHandler::SetSocks4Port | ( | port_t | ) | [virtual] |
Set socks4 server port number that all new tcp sockets should use.
Implements ISocketHandler.
Definition at line 1003 of file SocketHandler.cpp.
References m_socks4_port.
01004 { 01005 m_socks4_port = port; 01006 }
void SocketHandler::SetSocks4Userid | ( | const std::string & | ) | [virtual] |
Set optional socks4 userid.
Implements ISocketHandler.
Definition at line 1009 of file SocketHandler.cpp.
References m_socks4_userid.
01010 { 01011 m_socks4_userid = id; 01012 }
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 1107 of file SocketHandler.cpp.
References m_bTryDirect.
01108 { 01109 m_bTryDirect = x; 01110 }
ipaddr_t SocketHandler::GetSocks4Host | ( | ) | [virtual] |
Get socks4 server ip.
Implements ISocketHandler.
Definition at line 1113 of file SocketHandler.cpp.
References m_socks4_host.
01114 { 01115 return m_socks4_host; 01116 }
port_t SocketHandler::GetSocks4Port | ( | ) | [virtual] |
Get socks4 port number.
Implements ISocketHandler.
Definition at line 1119 of file SocketHandler.cpp.
References m_socks4_port.
01120 { 01121 return m_socks4_port; 01122 }
const std::string & SocketHandler::GetSocks4Userid | ( | ) | [virtual] |
Get socks4 userid (optional).
Implements ISocketHandler.
Definition at line 1125 of file SocketHandler.cpp.
References m_socks4_userid.
01126 { 01127 return m_socks4_userid; 01128 }
bool SocketHandler::Socks4TryDirect | ( | ) | [virtual] |
Check status of socks4 try direct flag.
Implements ISocketHandler.
Definition at line 1131 of file SocketHandler.cpp.
References m_bTryDirect.
01132 { 01133 return m_bTryDirect; 01134 }
void SocketHandler::EnableResolver | ( | port_t | port = 16667 |
) | [virtual] |
Enable asynchronous DNS.
port | Listen port of asynchronous dns server |
Implements ISocketHandler.
Definition at line 1089 of file SocketHandler.cpp.
References m_resolver, and m_resolver_port.
01090 { 01091 if (!m_resolver) 01092 { 01093 m_resolver_port = port; 01094 m_resolver = new ResolvServer(port); 01095 } 01096 }
bool SocketHandler::ResolverEnabled | ( | ) | [virtual] |
Check resolver status.
Implements ISocketHandler.
Definition at line 1139 of file SocketHandler.cpp.
References m_resolver.
01140 { 01141 return m_resolver ? true : false; 01142 }
Queue a dns request.
host | Hostname to be resolved | |
port | Port number will be echoed in Socket::OnResolved callback |
Implements ISocketHandler.
Definition at line 1017 of file SocketHandler.cpp.
References Add(), LOG_LEVEL_FATAL, LogError(), m_resolv_id, m_resolver_port, and Utility::u2ip().
01018 { 01019 // check cache 01020 ResolvSocket *resolv = new ResolvSocket(*this, p, host, port); 01021 resolv -> SetId(++m_resolv_id); 01022 resolv -> SetDeleteByHandler(); 01023 ipaddr_t local; 01024 Utility::u2ip("127.0.0.1", local); 01025 if (!resolv -> Open(local, m_resolver_port)) 01026 { 01027 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); 01028 } 01029 Add(resolv); 01030 return resolv -> GetId(); 01031 }
Do a reverse dns lookup.
Implements ISocketHandler.
Definition at line 1053 of file SocketHandler.cpp.
References Add(), LOG_LEVEL_FATAL, LogError(), m_resolv_id, m_resolver_port, and Utility::u2ip().
01054 { 01055 // check cache 01056 ResolvSocket *resolv = new ResolvSocket(*this, p, a); 01057 resolv -> SetId(++m_resolv_id); 01058 resolv -> SetDeleteByHandler(); 01059 ipaddr_t local; 01060 Utility::u2ip("127.0.0.1", local); 01061 if (!resolv -> Open(local, m_resolver_port)) 01062 { 01063 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL); 01064 } 01065 Add(resolv); 01066 return resolv -> GetId(); 01067 }
port_t SocketHandler::GetResolverPort | ( | ) | [virtual] |
Get listen port of asynchronous dns server.
Implements ISocketHandler.
Definition at line 1145 of file SocketHandler.cpp.
References m_resolver_port.
01146 { 01147 return m_resolver_port; 01148 }
bool SocketHandler::ResolverReady | ( | ) | [virtual] |
Resolver thread ready for queries.
Implements ISocketHandler.
Definition at line 1099 of file SocketHandler.cpp.
References m_resolver.
01100 { 01101 return m_resolver ? m_resolver -> Ready() : false; 01102 }
void SocketHandler::SetSlave | ( | bool | x = true |
) | [virtual] |
Indicates that the handler runs under SocketThread.
Implements ISocketHandler.
Definition at line 190 of file SocketHandler.cpp.
References m_slave.
Referenced by Socket::SocketThread::Run().
00191 { 00192 m_slave = x; 00193 }
bool SocketHandler::IsSlave | ( | ) | [virtual] |
Indicates that the handler runs under SocketThread.
Implements ISocketHandler.
Definition at line 196 of file SocketHandler.cpp.
References m_slave.
00197 { 00198 return m_slave; 00199 }
void SocketHandler::CheckSanity | ( | ) |
Sanity check of those accursed lists.
Definition at line 1224 of file SocketHandler.cpp.
References CheckList(), m_fds, m_fds_callonconnect, m_fds_close, m_fds_detach, m_fds_erase, m_fds_retry, and m_fds_timeout.
01225 { 01226 CheckList(m_fds, "active sockets"); // active sockets 01227 CheckList(m_fds_erase, "sockets to be erased"); // should always be empty anyway 01228 CheckList(m_fds_callonconnect, "checklist CallOnConnect"); 01229 #ifdef ENABLE_DETACH 01230 CheckList(m_fds_detach, "checklist Detach"); 01231 #endif 01232 CheckList(m_fds_timeout, "checklist Timeout"); 01233 CheckList(m_fds_retry, "checklist retry client connect"); 01234 CheckList(m_fds_close, "checklist close and delete"); 01235 }
void SocketHandler::CheckList | ( | socket_v & | , | |
const std::string & | ||||
) | [private] |
Used by CheckSanity.
Definition at line 1238 of file SocketHandler.cpp.
References m_add, m_delete, and m_sockets.
Referenced by CheckSanity().
01239 { 01240 for (socket_v::iterator it = ref.begin(); it != ref.end(); it++) 01241 { 01242 SOCKET s = *it; 01243 if (m_sockets.find(s) != m_sockets.end()) 01244 continue; 01245 if (m_add.find(s) != m_add.end()) 01246 continue; 01247 bool found = false; 01248 for (std::list<Socket *>::iterator it = m_delete.begin(); it != m_delete.end(); it++) 01249 { 01250 Socket *p = *it; 01251 if (p -> GetSocket() == s) 01252 { 01253 found = true; 01254 break; 01255 } 01256 } 01257 if (!found) 01258 { 01259 fprintf(stderr, "CheckList failed for \"%s\": fd %d\n", listname.c_str(), s); 01260 } 01261 } 01262 }
void SocketHandler::Remove | ( | Socket * | ) | [private, virtual] |
Remove socket from socket map, used by Socket class.
Implements ISocketHandler.
Definition at line 1188 of file SocketHandler.cpp.
References LOG_LEVEL_WARNING, LogError(), m_add, m_delete, and m_sockets.
01189 { 01190 if (p -> ErasedByHandler()) 01191 { 01192 return; 01193 } 01194 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++) 01195 { 01196 if (it -> second == p) 01197 { 01198 LogError(p, "Remove", -1, "Socket destructor called while still in use", LOG_LEVEL_WARNING); 01199 m_sockets.erase(it); 01200 return; 01201 } 01202 } 01203 for (socket_m::iterator it2 = m_add.begin(); it2 != m_add.end(); it2++) 01204 { 01205 if ((*it2).second == p) 01206 { 01207 LogError(p, "Remove", -2, "Socket destructor called while still in use", LOG_LEVEL_WARNING); 01208 m_add.erase(it2); 01209 return; 01210 } 01211 } 01212 for (std::list<Socket *>::iterator it3 = m_delete.begin(); it3 != m_delete.end(); it3++) 01213 { 01214 if (*it3 == p) 01215 { 01216 LogError(p, "Remove", -3, "Socket destructor called while still in use", LOG_LEVEL_WARNING); 01217 m_delete.erase(it3); 01218 return; 01219 } 01220 } 01221 }
socket_m SocketHandler::m_sockets [protected] |
Active sockets map.
Definition at line 203 of file SocketHandler.h.
Referenced by CheckList(), FindConnection(), GetCount(), Remove(), Select(), Valid(), and ~SocketHandler().
socket_m SocketHandler::m_add [protected] |
Sockets to be added to sockets map.
Definition at line 204 of file SocketHandler.h.
Referenced by Add(), CheckList(), GetCount(), Remove(), and Select().
std::list<Socket *> SocketHandler::m_delete [protected] |
Sockets to be deleted (failed when Add).
Definition at line 205 of file SocketHandler.h.
Referenced by Add(), CheckList(), GetCount(), Remove(), and Select().
StdLog* SocketHandler::m_stdlog [protected] |
Registered log class, or NULL.
Definition at line 208 of file SocketHandler.h.
Referenced by LogError(), and RegStdLog().
Mutex& SocketHandler::m_mutex [protected] |
Thread safety mutex.
Definition at line 209 of file SocketHandler.h.
Referenced by GetMutex(), Select(), SocketHandler(), and ~SocketHandler().
bool SocketHandler::m_b_use_mutex [protected] |
Mutex correctly initialized.
Definition at line 210 of file SocketHandler.h.
Referenced by Select(), and ~SocketHandler().
SOCKET SocketHandler::m_maxsock [private] |
Highest file descriptor + 1 in active sockets list.
Definition at line 216 of file SocketHandler.h.
Referenced by Select().
fd_set SocketHandler::m_rfds [private] |
file descriptor set monitored for read events
Definition at line 217 of file SocketHandler.h.
Referenced by Get(), Select(), Set(), and SocketHandler().
fd_set SocketHandler::m_wfds [private] |
file descriptor set monitored for write events
Definition at line 218 of file SocketHandler.h.
Referenced by Get(), Select(), Set(), and SocketHandler().
fd_set SocketHandler::m_efds [private] |
file descriptor set monitored for exceptions
Definition at line 219 of file SocketHandler.h.
Referenced by Get(), Select(), Set(), and SocketHandler().
int SocketHandler::m_preverror [private] |
int SocketHandler::m_errcnt [private] |
time_t SocketHandler::m_tlast [private] |
socket_v SocketHandler::m_fds [private] |
Active file descriptor list.
Definition at line 225 of file SocketHandler.h.
Referenced by CheckSanity(), and Select().
socket_v SocketHandler::m_fds_erase [private] |
File descriptors that are to be erased from m_sockets.
Definition at line 226 of file SocketHandler.h.
Referenced by CheckSanity(), and Select().
socket_v SocketHandler::m_fds_callonconnect [private] |
checklist CallOnConnect
Definition at line 227 of file SocketHandler.h.
Referenced by AddList(), CheckSanity(), and Select().
socket_v SocketHandler::m_fds_detach [private] |
checklist Detach
Definition at line 229 of file SocketHandler.h.
Referenced by AddList(), CheckSanity(), and Select().
socket_v SocketHandler::m_fds_timeout [private] |
checklist timeout
Definition at line 231 of file SocketHandler.h.
Referenced by AddList(), CheckSanity(), and Select().
socket_v SocketHandler::m_fds_retry [private] |
checklist retry client connect
Definition at line 232 of file SocketHandler.h.
Referenced by AddList(), CheckSanity(), and Select().
socket_v SocketHandler::m_fds_close [private] |
checklist close and delete
Definition at line 233 of file SocketHandler.h.
Referenced by AddList(), CheckSanity(), and Select().
ipaddr_t SocketHandler::m_socks4_host [private] |
Socks4 server host ip.
Definition at line 236 of file SocketHandler.h.
Referenced by GetSocks4Host(), and SetSocks4Host().
port_t SocketHandler::m_socks4_port [private] |
Socks4 server port number.
Definition at line 237 of file SocketHandler.h.
Referenced by GetSocks4Port(), and SetSocks4Port().
std::string SocketHandler::m_socks4_userid [private] |
Socks4 userid.
Definition at line 238 of file SocketHandler.h.
Referenced by GetSocks4Userid(), and SetSocks4Userid().
bool SocketHandler::m_bTryDirect [private] |
Try direct connection if socks4 server fails.
Definition at line 239 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 243 of file SocketHandler.h.
Referenced by EnableResolver(), ResolverEnabled(), ResolverReady(), and ~SocketHandler().
port_t SocketHandler::m_resolver_port [private] |
Resolver listen port.
Definition at line 244 of file SocketHandler.h.
Referenced by EnableResolver(), GetResolverPort(), and Resolve().
bool SocketHandler::m_b_enable_pool [private] |
Connection pool enabled if true.
Definition at line 247 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 255 of file SocketHandler.h.
Referenced by IsSlave(), Select(), SetSlave(), and ~SocketHandler().