Logo
~Sockets~
~Examples~
~Contact~


SocketHandler Class Reference
[Basic sockets]

Socket container class, event generator. More...

#include <SocketHandler.h>

Inheritance diagram for SocketHandler:
Collaboration diagram for SocketHandler:

List of all members.


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 ISocketHandlerCreate (StdLog *=NULL)
 Return another instance.
virtual ISocketHandlerCreate (IMutex &, ISocketHandler &, StdLog *=NULL)
 Return another instance.
virtual bool ParentHandlerIsValid ()
 Handler created with parent.
virtual ISocketHandlerParentHandler ()
 Get parent sockethandler.
virtual ISocketHandlerGetRandomHandler ()
 Get thread handler with least connections.
virtual ISocketHandlerGetEffectiveHandler ()
 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.
IMutexGetMutex () 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::PoolSocketFindConnection (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).
StdLogm_stdlog
 Registered log class, or NULL.
IMutexm_mutex
 Thread safety mutex.
bool m_b_use_mutex
 Mutex correctly initialized.
ISocketHandlerm_parent
bool m_b_parent_is_valid

Private Member Functions

void RebuildFdset ()
void Set (Socket *, bool, bool)

Private Attributes

std::list< SocketHandlerThread * > m_threads
UdpSocketm_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_tm_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.
ResolvServerm_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

Detailed Description

Socket container class, event generator.

Definition at line 57 of file SocketHandler.h.


Member Typedef Documentation

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.


Constructor & Destructor Documentation

SocketHandler::SocketHandler ( StdLog log = NULL  ) 

SocketHandler constructor.

Parameters:
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::SocketHandler ( IMutex mutex,
StdLog log = NULL 
)

SocketHandler threadsafe constructor.

Parameters:
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 }


Member Function Documentation

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.

Parameters:
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().

00483 {
00484         return m_sockets.size() + m_add.size() + m_delete.size();
00485 }

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().

00127 { return FD_SETSIZE; }

bool SocketHandler::OkToAccept ( Socket p  )  [virtual]

Override and return false to deny all incoming connections.

Parameters:
p ListenSocket class pointer (use GetPort to identify which one)

Implements ISocketHandler.

Definition at line 476 of file SocketHandler.cpp.

00477 {
00478         return true;
00479 }

const std::map<SOCKET, Socket *>& SocketHandler::AllSockets (  )  [inline, virtual]

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.

Returns:
true if connection pool is enabled

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.

Returns:
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.

Returns:
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).

Returns:
socks4 userid

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.

Returns:
true if direct connection should be tried if connection to socks4 server fails

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.

Parameters:
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.

Returns:
true if resolver is enabled

Implements ISocketHandler.

Definition at line 642 of file SocketHandler.cpp.

References m_resolver.

00643 { 
00644         return m_resolver ? true : false; 
00645 }

int SocketHandler::Resolve ( Socket p,
const std::string &  host,
port_t  port 
) [virtual]

Queue a dns request.

Parameters:
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 }

int SocketHandler::Resolve ( Socket p,
ipaddr_t  a 
) [virtual]

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 }


Member Data Documentation

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.

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().

Registered log class, or NULL.

Definition at line 241 of file SocketHandler.h.

Referenced by LogError(), and RegStdLog().

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().

Definition at line 244 of file SocketHandler.h.

Referenced by GetEffectiveHandler(), and ParentHandler().

Definition at line 252 of file SocketHandler.h.

Referenced by EnableRelease(), and Release().

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]

timeout control

Definition at line 258 of file SocketHandler.h.

Referenced by Select().

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().

Definition at line 264 of file SocketHandler.h.

Referenced by AddIncoming(), CheckDetach(), Select(), and SetDetach().

Definition at line 265 of file SocketHandler.h.

Referenced by AddIncoming(), CheckTimeout(), Select(), and SetTimeout().

Definition at line 266 of file SocketHandler.h.

Referenced by AddIncoming(), CheckRetry(), Select(), and SetRetry().

Definition at line 267 of file SocketHandler.h.

Referenced by CheckClose(), Select(), and SetClose().

Socks4 server host ip.

Definition at line 270 of file SocketHandler.h.

Referenced by GetSocks4Host(), and SetSocks4Host().

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().

Try direct connection if socks4 server fails.

Definition at line 273 of file SocketHandler.h.

Referenced by SetSocks4TryDirect(), and Socks4TryDirect().

Resolver id counter.

Definition at line 276 of file SocketHandler.h.

Referenced by Resolve().

Resolver thread pointer.

Definition at line 277 of file SocketHandler.h.

Referenced by EnableResolver(), ResolverEnabled(), ResolverReady(), and ~SocketHandler().

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().

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().


The documentation for this class was generated from the following files:
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4