00001
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifdef _WIN32
00031 #pragma warning(disable:4786)
00032 #include <stdlib.h>
00033 #else
00034 #include <errno.h>
00035 #endif
00036
00037 #include "SocketHandler.h"
00038 #include "UdpSocket.h"
00039 #include "ResolvSocket.h"
00040 #include "ResolvServer.h"
00041 #include "TcpSocket.h"
00042 #include "Mutex.h"
00043 #include "Utility.h"
00044 #include "SocketAddress.h"
00045
00046 #ifdef SOCKETS_NAMESPACE
00047 namespace SOCKETS_NAMESPACE {
00048 #endif
00049
00050
00051 #ifdef _DEBUG
00052 #define DEB(x) x; fflush(stderr);
00053 #else
00054 #define DEB(x)
00055 #endif
00056
00057
00058 SocketHandler::SocketHandler(StdLog *p)
00059 :ISocketHandler(p)
00060 ,m_maxsock(0)
00061 ,m_preverror(-1)
00062 ,m_errcnt(0)
00063 #ifdef ENABLE_SOCKS4
00064 ,m_socks4_host(0)
00065 ,m_socks4_port(0)
00066 ,m_bTryDirect(false)
00067 #endif
00068 #ifdef ENABLE_RESOLVER
00069 ,m_resolv_id(0)
00070 ,m_resolver(NULL)
00071 #endif
00072 #ifdef ENABLE_POOL
00073 ,m_b_enable_pool(false)
00074 #endif
00075 {
00076 FD_ZERO(&m_rfds);
00077 FD_ZERO(&m_wfds);
00078 FD_ZERO(&m_efds);
00079 }
00080
00081
00082 SocketHandler::SocketHandler(Mutex& mutex,StdLog *p)
00083 :ISocketHandler(mutex, p)
00084 ,m_maxsock(0)
00085 ,m_preverror(-1)
00086 ,m_errcnt(0)
00087 #ifdef ENABLE_SOCKS4
00088 ,m_socks4_host(0)
00089 ,m_socks4_port(0)
00090 ,m_bTryDirect(false)
00091 #endif
00092 #ifdef ENABLE_RESOLVER
00093 ,m_resolv_id(0)
00094 ,m_resolver(NULL)
00095 #endif
00096 #ifdef ENABLE_POOL
00097 ,m_b_enable_pool(false)
00098 #endif
00099 {
00100 m_mutex.Lock();
00101 FD_ZERO(&m_rfds);
00102 FD_ZERO(&m_wfds);
00103 FD_ZERO(&m_efds);
00104 }
00105
00106
00107 SocketHandler::~SocketHandler()
00108 {
00109 #ifdef ENABLE_RESOLVER
00110 if (m_resolver)
00111 {
00112 m_resolver -> Quit();
00113 }
00114 #endif
00115 {
00116 while (m_sockets.size())
00117 {
00118 DEB( fprintf(stderr, "Emptying sockets list in SocketHandler destructor, %d instances\n", m_sockets.size());)
00119 socket_m::iterator it = m_sockets.begin();
00120 Socket *p = it -> second;
00121 if (p)
00122 {
00123 DEB( fprintf(stderr, " fd %d\n", p -> GetSocket());)
00124 p -> Close();
00125 DEB( fprintf(stderr, " fd closed %d\n", p -> GetSocket());)
00126
00127
00128
00129
00130
00131
00132
00133 if (p -> DeleteByHandler()
00134 #ifdef ENABLE_DETACH
00135 && !(m_slave ^ p -> IsDetached())
00136 #endif
00137 )
00138 {
00139 p -> SetErasedByHandler();
00140 delete p;
00141 }
00142 m_sockets.erase(it);
00143 }
00144 else
00145 {
00146 m_sockets.erase(it);
00147 }
00148 DEB( fprintf(stderr, "next\n");)
00149 }
00150 DEB( fprintf(stderr, "/Emptying sockets list in SocketHandler destructor, %d instances\n", m_sockets.size());)
00151 }
00152 #ifdef ENABLE_RESOLVER
00153 if (m_resolver)
00154 {
00155 delete m_resolver;
00156 }
00157 #endif
00158 if (m_b_use_mutex)
00159 {
00160 m_mutex.Unlock();
00161 }
00162 }
00163
00164
00165 void SocketHandler::Add(Socket *p)
00166 {
00167 if (p -> GetSocket() == INVALID_SOCKET)
00168 {
00169 LogError(p, "Add", -1, "Invalid socket", LOG_LEVEL_WARNING);
00170 if (p -> CloseAndDelete())
00171 {
00172 m_delete.push_back(p);
00173 }
00174 return;
00175 }
00176 if (m_add.find(p -> GetSocket()) != m_add.end())
00177 {
00178 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in add queue", LOG_LEVEL_FATAL);
00179 m_delete.push_back(p);
00180 return;
00181 }
00182 m_add[p -> GetSocket()] = p;
00183 }
00184
00185
00186 void SocketHandler::Get(SOCKET s,bool& r,bool& w,bool& e)
00187 {
00188 if (s >= 0)
00189 {
00190 r = FD_ISSET(s, &m_rfds) ? true : false;
00191 w = FD_ISSET(s, &m_wfds) ? true : false;
00192 e = FD_ISSET(s, &m_efds) ? true : false;
00193 }
00194 }
00195
00196
00197 void SocketHandler::Set(SOCKET s,bool bRead,bool bWrite,bool bException)
00198 {
00199 DEB(fprintf(stderr, "Set(%d, %s, %s, %s)\n", s, bRead ? "true" : "false", bWrite ? "true" : "false", bException ? "true" : "false");)
00200 if (s >= 0)
00201 {
00202 if (bRead)
00203 {
00204 if (!FD_ISSET(s, &m_rfds))
00205 {
00206 FD_SET(s, &m_rfds);
00207 }
00208 }
00209 else
00210 {
00211 FD_CLR(s, &m_rfds);
00212 }
00213 if (bWrite)
00214 {
00215 if (!FD_ISSET(s, &m_wfds))
00216 {
00217 FD_SET(s, &m_wfds);
00218 }
00219 }
00220 else
00221 {
00222 FD_CLR(s, &m_wfds);
00223 }
00224 if (bException)
00225 {
00226 if (!FD_ISSET(s, &m_efds))
00227 {
00228 FD_SET(s, &m_efds);
00229 }
00230 }
00231 else
00232 {
00233 FD_CLR(s, &m_efds);
00234 }
00235 }
00236 }
00237
00238
00239 int SocketHandler::Select(long sec,long usec)
00240 {
00241 struct timeval tv;
00242 tv.tv_sec = sec;
00243 tv.tv_usec = usec;
00244 return Select(&tv);
00245 }
00246
00247
00248 int SocketHandler::Select()
00249 {
00250 if (m_fds_callonconnect.size() ||
00251 #ifdef ENABLE_DETACH
00252 (!m_slave && m_fds_detach.size()) ||
00253 #endif
00254 m_fds_connecting.size() ||
00255 m_fds_retry.size() ||
00256 m_fds_close.size() ||
00257 m_fds_erase.size())
00258 {
00259 return Select(0, 200000);
00260 }
00261 return Select(NULL);
00262 }
00263
00264
00265 int SocketHandler::Select(struct timeval *tsel)
00266 {
00267 size_t ignore = 0;
00268 while (m_add.size() > ignore)
00269 {
00270 if (m_sockets.size() >= FD_SETSIZE)
00271 {
00272 LogError(NULL, "Select", (int)m_sockets.size(), "FD_SETSIZE reached", LOG_LEVEL_WARNING);
00273 break;
00274 }
00275 socket_m::iterator it = m_add.begin();
00276 SOCKET s = it -> first;
00277 Socket *p = it -> second;
00278 DEB(fprintf(stderr, "Trying to add fd %d, m_add.size() %d, ignore %d\n", s, m_add.size(), ignore);)
00279
00280 if (m_sockets.find(p -> GetSocket()) != m_sockets.end())
00281 {
00282 LogError(p, "Add", (int)p -> GetSocket(), "Attempt to add socket already in controlled queue", LOG_LEVEL_FATAL);
00283
00284
00285
00286 ignore++;
00287 continue;
00288 }
00289 if (!p -> CloseAndDelete())
00290 {
00291 if (p -> Connecting())
00292 {
00293 Set(s,false,true);
00294 }
00295 else
00296 {
00297 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p);
00298 bool bWrite = tcp ? tcp -> GetOutputLength() != 0 : false;
00299 if (p -> IsDisableRead())
00300 {
00301 Set(s, false, bWrite);
00302 }
00303 else
00304 {
00305 Set(s, true, bWrite);
00306 }
00307 }
00308 m_maxsock = (s > m_maxsock) ? s : m_maxsock;
00309 }
00310 else
00311 {
00312 LogError(p, "Add", (int)p -> GetSocket(), "Trying to add socket with SetCloseAndDelete() true", LOG_LEVEL_WARNING);
00313 }
00314
00315
00316
00317 #ifdef ENABLE_DETACH
00318 if (!(m_slave ^ p -> IsDetach()))
00319 #endif
00320 {
00321 m_fds.push_back(s);
00322 }
00323 m_sockets[s] = p;
00324
00325 m_add.erase(it);
00326 }
00327 #ifdef MACOSX
00328 fd_set rfds;
00329 fd_set wfds;
00330 fd_set efds;
00331 FD_COPY(&m_rfds, &rfds);
00332 FD_COPY(&m_wfds, &wfds);
00333 FD_COPY(&m_efds, &efds);
00334 #else
00335 fd_set rfds = m_rfds;
00336 fd_set wfds = m_wfds;
00337 fd_set efds = m_efds;
00338 #endif
00339 int n;
00340 if (m_b_use_mutex)
00341 {
00342 m_mutex.Unlock();
00343 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel);
00344 m_mutex.Lock();
00345 }
00346 else
00347 {
00348 n = select( (int)(m_maxsock + 1),&rfds,&wfds,&efds,tsel);
00349 }
00350 if (n == -1)
00351 {
00352
00353
00354
00355
00356
00357
00358 if (Errno != m_preverror || m_errcnt++ % 10000 == 0)
00359 {
00360 LogError(NULL, "select", Errno, StrError(Errno));
00361 DEB( fprintf(stderr, "m_maxsock: %d\n", m_maxsock);
00362 fprintf(stderr, "%s\n", Errno == EINVAL ? "EINVAL" :
00363 Errno == EINTR ? "EINTR" :
00364 Errno == EBADF ? "EBADF" :
00365 Errno == ENOMEM ? "ENOMEM" : "<another>");
00366
00367 for (SOCKET i = 0; i <= m_maxsock; i++)
00368 {
00369 bool t = false;
00370 FD_ZERO(&rfds);
00371 FD_ZERO(&wfds);
00372 FD_ZERO(&efds);
00373 if (FD_ISSET(i, &m_rfds))
00374 {
00375 FD_SET(i, &rfds);
00376 t = true;
00377 }
00378 if (FD_ISSET(i, &m_wfds))
00379 {
00380 FD_SET(i, &wfds);
00381 t = true;
00382 }
00383 if (FD_ISSET(i, &m_efds))
00384 {
00385 FD_SET(i, &efds);
00386 t = true;
00387 }
00388 if (t && m_sockets.find(i) == m_sockets.end())
00389 {
00390 fprintf(stderr, "Bad fd in fd_set: %d\n", i);
00391 }
00392 }
00393 )
00394 m_preverror = Errno;
00395 }
00397 }
00398 else
00399 if (!n)
00400 {
00401 m_preverror = -1;
00402 }
00403 else
00404 if (n > 0)
00405 {
00406 for (socket_v::iterator it2 = m_fds.begin(); it2 != m_fds.end() && n; it2++)
00407 {
00408 SOCKET i = *it2;
00409 if (FD_ISSET(i, &rfds))
00410 {
00411 socket_m::iterator itmp = m_sockets.find(i);
00412 if (itmp != m_sockets.end())
00413 {
00414 Socket *p = itmp -> second;
00415
00416 #ifdef HAVE_OPENSSL
00417 if (p -> IsSSLNegotiate())
00418 {
00419 p -> SSLNegotiate();
00420 }
00421 else
00422 #endif
00423 {
00424 p -> OnRead();
00425 }
00426 }
00427 else
00428 {
00429 LogError(NULL, "GetSocket/handler/1", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00430 }
00431 n--;
00432 }
00433 if (FD_ISSET(i, &wfds))
00434 {
00435 socket_m::iterator itmp = m_sockets.find(i);
00436 if (itmp != m_sockets.end())
00437 {
00438 Socket *p = itmp -> second;
00439
00440 #ifdef HAVE_OPENSSL
00441 if (p -> IsSSLNegotiate())
00442 {
00443 p -> SSLNegotiate();
00444 }
00445 else
00446 #endif
00447 {
00448 p -> OnWrite();
00449 }
00450 }
00451 else
00452 {
00453 LogError(NULL, "GetSocket/handler/2", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00454 }
00455 n--;
00456 }
00457 if (FD_ISSET(i, &efds))
00458 {
00459 socket_m::iterator itmp = m_sockets.find(i);
00460 if (itmp != m_sockets.end())
00461 {
00462 Socket *p = itmp -> second;
00463 p -> OnException();
00464 }
00465 else
00466 {
00467 LogError(NULL, "GetSocket/handler/3", (int)i, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00468 }
00469 n--;
00470 }
00471 }
00472 m_preverror = -1;
00473 }
00474
00475
00476 if (m_fds_callonconnect.size())
00477 {
00478 socket_v tmp = m_fds_callonconnect;
00479 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++)
00480 {
00481 Socket *p = NULL;
00482 {
00483 socket_m::iterator itmp = m_sockets.find(*it);
00484 if (itmp != m_sockets.end())
00485 {
00486 p = itmp -> second;
00487 }
00488 else
00489 {
00490 LogError(NULL, "GetSocket/handler/4", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00491 }
00492 }
00493 if (p)
00494 {
00495 if (p -> CallOnConnect() && p -> Ready() )
00496 {
00497 p -> SetConnected();
00498 #ifdef HAVE_OPENSSL
00499 if (p -> IsSSL())
00500 p -> OnSSLConnect();
00501 else
00502 #endif
00503 #ifdef ENABLE_SOCKS4
00504 if (p -> Socks4())
00505 p -> OnSocks4Connect();
00506 else
00507 #endif
00508 {
00509 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p);
00510 if (tcp)
00511 {
00512 if (tcp -> GetOutputLength())
00513 {
00514 p -> OnWrite();
00515 }
00516 }
00517 #ifdef ENABLE_RECONNECT
00518 if (tcp && tcp -> IsReconnect())
00519 p -> OnReconnect();
00520 else
00521 #endif
00522 {
00523
00524 p -> OnConnect();
00525 }
00526 }
00527 p -> SetCallOnConnect( false );
00528 }
00529 }
00530 }
00531 }
00532 #ifdef ENABLE_DETACH
00533 if (!m_slave && m_fds_detach.size())
00534 {
00535 for (socket_v::iterator it = m_fds_detach.begin(); it != m_fds_detach.end(); it++)
00536 {
00537 Socket *p = NULL;
00538 {
00539 socket_m::iterator itmp = m_sockets.find(*it);
00540 if (itmp != m_sockets.end())
00541 {
00542 p = itmp -> second;
00543 }
00544 else
00545 {
00546 LogError(NULL, "GetSocket/handler/5", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00547 }
00548 }
00549 if (p)
00550 {
00551 if (p -> IsDetach())
00552 {
00553 Set(p -> GetSocket(), false, false, false);
00554
00555
00556 p -> DetachSocket();
00557
00558
00559 m_fds_erase.push_back(p -> GetSocket());
00560 }
00561 }
00562 }
00563 }
00564 #endif
00565
00566 if (m_fds_connecting.size())
00567 {
00568 socket_v tmp = m_fds_connecting;
00569 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++)
00570 {
00571 Socket *p = NULL;
00572 {
00573 socket_m::iterator itmp = m_sockets.find(*it);
00574 if (itmp != m_sockets.end())
00575 {
00576 p = itmp -> second;
00577 }
00578 else
00579 {
00580 itmp = m_add.find(*it);
00581 if (itmp != m_add.end())
00582 {
00583 p = itmp -> second;
00584 }
00585 else
00586 {
00587 LogError(NULL, "GetSocket/handler/6", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00588 }
00589 }
00590 }
00591 if (p)
00592 {
00593 if (p -> Connecting() && p -> GetConnectTime() >= p -> GetConnectTimeout() )
00594 {
00595 LogError(p, "connect", -1, "connect timeout", LOG_LEVEL_FATAL);
00596 #ifdef ENABLE_SOCKS4
00597 if (p -> Socks4())
00598 {
00599 p -> OnSocks4ConnectFailed();
00600
00601 }
00602 else
00603 #endif
00604 if (p -> GetConnectionRetry() == -1 ||
00605 (p -> GetConnectionRetry() && p -> GetConnectionRetries() < p -> GetConnectionRetry()) )
00606 {
00607 p -> IncreaseConnectionRetries();
00608
00609 if (p -> OnConnectRetry())
00610 {
00611 p -> SetRetryClientConnect();
00612 }
00613 else
00614 {
00615 p -> SetCloseAndDelete( true );
00617 p -> OnConnectFailed();
00618 }
00619 }
00620 else
00621 {
00622 p -> SetCloseAndDelete(true);
00624 p -> OnConnectFailed();
00625 }
00626
00627 p -> SetConnecting(false);
00628 }
00629 }
00630 }
00631 }
00632
00633 if (m_fds_retry.size())
00634 {
00635 socket_v tmp = m_fds_retry;
00636 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++)
00637 {
00638 Socket *p = NULL;
00639 {
00640 socket_m::iterator itmp = m_sockets.find(*it);
00641 if (itmp != m_sockets.end())
00642 {
00643 p = itmp -> second;
00644 }
00645 else
00646 {
00647 LogError(NULL, "GetSocket/handler/7", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00648 }
00649 }
00650 if (p)
00651 {
00652 if (p -> RetryClientConnect())
00653 {
00654 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p);
00655 SOCKET nn = *it;
00656 p -> SetRetryClientConnect(false);
00657 DEB( fprintf(stderr, "Close() before retry client connect\n");)
00658 p -> Close();
00659 std::auto_ptr<SocketAddress> ad = p -> GetClientRemoteAddress();
00660 if (ad.get())
00661 {
00662 tcp -> Open(*ad);
00663 }
00664 else
00665 {
00666 LogError(p, "RetryClientConnect", 0, "no address", LOG_LEVEL_ERROR);
00667 }
00668 Add(p);
00669 m_fds_erase.push_back(nn);
00670 }
00671 }
00672 }
00673 }
00674
00675 if (m_fds_close.size())
00676 {
00677 socket_v tmp = m_fds_close;
00678 DEB(fprintf(stderr, "m_fds_close.size() == %d\n", m_fds_close.size());)
00679 for (socket_v::iterator it = tmp.begin(); it != tmp.end(); it++)
00680 {
00681 Socket *p = NULL;
00682 {
00683 socket_m::iterator itmp = m_sockets.find(*it);
00684 if (itmp != m_sockets.end())
00685 {
00686 p = itmp -> second;
00687 }
00688 else
00689 {
00690 itmp = m_add.find(*it);
00691 if (itmp != m_add.end())
00692 {
00693 p = itmp -> second;
00694 }
00695 else
00696 {
00697 LogError(NULL, "GetSocket/handler/8", (int)*it, "Did not find expected socket using file descriptor", LOG_LEVEL_WARNING);
00698 }
00699 }
00700 }
00701 if (p)
00702 {
00703 if (p -> CloseAndDelete() )
00704 {
00705 TcpSocket *tcp = dynamic_cast<TcpSocket *>(p);
00706
00707 if (tcp && p -> IsConnected() && tcp -> GetFlushBeforeClose() &&
00708 #ifdef HAVE_OPENSSL
00709 !tcp -> IsSSL() &&
00710 #endif
00711 p -> TimeSinceClose() < 5)
00712 {
00713 DEB(fprintf(stderr, " close(1)\n");)
00714 if (tcp -> GetOutputLength())
00715 {
00716 LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Sending all data before closing", LOG_LEVEL_INFO);
00717 }
00718 else
00719 if (!(p -> GetShutdown() & SHUT_WR))
00720 {
00721 SOCKET nn = *it;
00722 if (nn != INVALID_SOCKET && shutdown(nn, SHUT_WR) == -1)
00723 {
00724 LogError(p, "graceful shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR);
00725 }
00726 p -> SetShutdown(SHUT_WR);
00727 }
00728 }
00729 else
00730 #ifdef ENABLE_RECONNECT
00731 if (tcp && p -> IsConnected() && tcp -> Reconnect())
00732 {
00733 SOCKET nn = *it;
00734 DEB(fprintf(stderr, " close(2) fd %d\n", nn);)
00735 p -> SetCloseAndDelete(false);
00736 tcp -> SetIsReconnect();
00737 p -> SetConnected(false);
00738 DEB( fprintf(stderr, "Close() before reconnect\n");)
00739 p -> Close();
00740 p -> OnDisconnect();
00741 std::auto_ptr<SocketAddress> ad = p -> GetClientRemoteAddress();
00742 if (ad.get())
00743 {
00744 tcp -> Open(*ad);
00745 }
00746 else
00747 {
00748 LogError(p, "Reconnect", 0, "no address", LOG_LEVEL_ERROR);
00749 }
00750 tcp -> ResetConnectionRetries();
00751 Add(p);
00752 m_fds_erase.push_back(nn);
00753 }
00754 else
00755 #endif
00756 {
00757 SOCKET nn = *it;
00758 DEB(fprintf(stderr, " close(3) fd %d GetSocket() %d\n", nn, p -> GetSocket());)
00759 if (tcp && p -> IsConnected() && tcp -> GetOutputLength())
00760 {
00761 LogError(p, "Closing", (int)tcp -> GetOutputLength(), "Closing socket while data still left to send", LOG_LEVEL_WARNING);
00762 }
00763 #ifdef ENABLE_POOL
00764 if (p -> Retain() && !p -> Lost())
00765 {
00766 PoolSocket *p2 = new PoolSocket(*this, p);
00767 p2 -> SetDeleteByHandler();
00768 Add(p2);
00769
00770 p -> SetCloseAndDelete(false);
00771 }
00772 else
00773 #endif // ENABLE_POOL
00774 {
00775 Set(p -> GetSocket(),false,false,false);
00776 DEB( fprintf(stderr, "Close() before OnDelete\n");)
00777 p -> Close();
00778 }
00779 p -> OnDelete();
00780 if (p -> DeleteByHandler())
00781 {
00782 p -> SetErasedByHandler();
00783 }
00784 m_fds_erase.push_back(nn);
00785 }
00786 }
00787 }
00788 }
00789 }
00790
00791
00792 bool check_max_fd = false;
00793 while (m_fds_erase.size())
00794 {
00795 socket_v::iterator it = m_fds_erase.begin();
00796 SOCKET nn = *it;
00797 #ifdef ENABLE_DETACH
00798 {
00799 for (socket_v::iterator it = m_fds_detach.begin(); it != m_fds_detach.end(); it++)
00800 {
00801 if (*it == nn)
00802 {
00803 m_fds_detach.erase(it);
00804 break;
00805 }
00806 }
00807 }
00808 #endif
00809 {
00810 for (socket_v::iterator it = m_fds.begin(); it != m_fds.end(); it++)
00811 {
00812 if (*it == nn)
00813 {
00814 m_fds.erase(it);
00815 break;
00816 }
00817 }
00818 }
00819 {
00820 socket_m::iterator it = m_sockets.find(nn);
00821 if (it != m_sockets.end())
00822 {
00823 Socket *p = it -> second;
00824
00825
00826
00827
00828
00829
00830
00831 if (p -> ErasedByHandler()
00832 #ifdef ENABLE_DETACH
00833 && !(m_slave ^ p -> IsDetached())
00834 #endif
00835 )
00836 {
00837 delete p;
00838 }
00839 m_sockets.erase(it);
00840 }
00841 }
00842 m_fds_erase.erase(it);
00843 check_max_fd = true;
00844 }
00845
00846 if (check_max_fd)
00847 {
00848 m_maxsock = 0;
00849 for (socket_v::iterator it = m_fds.begin(); it != m_fds.end(); it++)
00850 {
00851 SOCKET s = *it;
00852 m_maxsock = s > m_maxsock ? s : m_maxsock;
00853 }
00854 }
00855
00856 while (m_delete.size())
00857 {
00858 std::list<Socket *>::iterator it = m_delete.begin();
00859 Socket *p = *it;
00860 p -> OnDelete();
00861 m_delete.erase(it);
00862 if (p -> DeleteByHandler()
00863 #ifdef ENABLE_DETACH
00864 && !(m_slave ^ p -> IsDetached())
00865 #endif
00866 )
00867 {
00868 p -> SetErasedByHandler();
00869 delete p;
00870 }
00871 }
00872 return n;
00873 }
00874
00875
00876 bool SocketHandler::Valid(Socket *p0)
00877 {
00878 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
00879 {
00880 Socket *p = it -> second;
00881 if (p0 == p)
00882 return true;
00883 }
00884 return false;
00885 }
00886
00887
00888 bool SocketHandler::OkToAccept(Socket *)
00889 {
00890 return true;
00891 }
00892
00893
00894 size_t SocketHandler::GetCount()
00895 {
00896 return m_sockets.size() + m_add.size() + m_delete.size();
00897 }
00898
00899
00900 #ifdef ENABLE_SOCKS4
00901 void SocketHandler::SetSocks4Host(ipaddr_t a)
00902 {
00903 m_socks4_host = a;
00904 }
00905
00906
00907 void SocketHandler::SetSocks4Host(const std::string& host)
00908 {
00909 Utility::u2ip(host, m_socks4_host);
00910 }
00911
00912
00913 void SocketHandler::SetSocks4Port(port_t port)
00914 {
00915 m_socks4_port = port;
00916 }
00917
00918
00919 void SocketHandler::SetSocks4Userid(const std::string& id)
00920 {
00921 m_socks4_userid = id;
00922 }
00923 #endif
00924
00925
00926 #ifdef ENABLE_RESOLVER
00927 int SocketHandler::Resolve(Socket *p,const std::string& host,port_t port)
00928 {
00929
00930 ResolvSocket *resolv = new ResolvSocket(*this, p);
00931 resolv -> SetId(++m_resolv_id);
00932 resolv -> SetHost(host);
00933 resolv -> SetPort(port);
00934 resolv -> SetDeleteByHandler();
00935 ipaddr_t local;
00936 Utility::u2ip("127.0.0.1", local);
00937 if (!resolv -> Open(local, m_resolver_port))
00938 {
00939 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
00940 }
00941 Add(resolv);
00942 return m_resolv_id;
00943 }
00944
00945
00946 #ifdef ENABLE_IPV6
00947 int SocketHandler::Resolve6(Socket *p,const std::string& host,port_t port)
00948 {
00949
00950 ResolvSocket *resolv = new ResolvSocket(*this, p);
00951 resolv -> SetId(++m_resolv_id);
00952 resolv -> SetHost(host);
00953 resolv -> SetPort(port);
00954 resolv -> SetResolveIpv6();
00955 resolv -> SetDeleteByHandler();
00956 ipaddr_t local;
00957 Utility::u2ip("127.0.0.1", local);
00958 if (!resolv -> Open(local, m_resolver_port))
00959 {
00960 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
00961 }
00962 Add(resolv);
00963 return m_resolv_id;
00964 }
00965 #endif
00966
00967
00968 int SocketHandler::Resolve(Socket *p,ipaddr_t a)
00969 {
00970
00971 ResolvSocket *resolv = new ResolvSocket(*this, p);
00972 resolv -> SetId(++m_resolv_id);
00973 resolv -> SetAddress(a);
00974 resolv -> SetDeleteByHandler();
00975 ipaddr_t local;
00976 Utility::u2ip("127.0.0.1", local);
00977 if (!resolv -> Open(local, m_resolver_port))
00978 {
00979 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
00980 }
00981 Add(resolv);
00982 return m_resolv_id;
00983 }
00984
00985
00986 #ifdef ENABLE_IPV6
00987 int SocketHandler::Resolve(Socket *p,in6_addr& a)
00988 {
00989
00990 ResolvSocket *resolv = new ResolvSocket(*this, p);
00991 resolv -> SetId(++m_resolv_id);
00992 resolv -> SetAddress(a);
00993 resolv -> SetDeleteByHandler();
00994 ipaddr_t local;
00995 Utility::u2ip("127.0.0.1", local);
00996 if (!resolv -> Open(local, m_resolver_port))
00997 {
00998 LogError(resolv, "Resolve", -1, "Can't connect to local resolve server", LOG_LEVEL_FATAL);
00999 }
01000 Add(resolv);
01001 return m_resolv_id;
01002 }
01003 #endif
01004
01005
01006 void SocketHandler::EnableResolver(port_t port)
01007 {
01008 if (!m_resolver)
01009 {
01010 m_resolver_port = port;
01011 m_resolver = new ResolvServer(port);
01012 }
01013 }
01014
01015
01016 bool SocketHandler::ResolverReady()
01017 {
01018 return m_resolver ? m_resolver -> Ready() : false;
01019 }
01020 #endif
01021
01022
01023 #ifdef ENABLE_SOCKS4
01024 void SocketHandler::SetSocks4TryDirect(bool x)
01025 {
01026 m_bTryDirect = x;
01027 }
01028
01029
01030 ipaddr_t SocketHandler::GetSocks4Host()
01031 {
01032 return m_socks4_host;
01033 }
01034
01035
01036 port_t SocketHandler::GetSocks4Port()
01037 {
01038 return m_socks4_port;
01039 }
01040
01041
01042 const std::string& SocketHandler::GetSocks4Userid()
01043 {
01044 return m_socks4_userid;
01045 }
01046
01047
01048 bool SocketHandler::Socks4TryDirect()
01049 {
01050 return m_bTryDirect;
01051 }
01052 #endif
01053
01054
01055 #ifdef ENABLE_RESOLVER
01056 bool SocketHandler::ResolverEnabled()
01057 {
01058 return m_resolver ? true : false;
01059 }
01060
01061
01062 port_t SocketHandler::GetResolverPort()
01063 {
01064 return m_resolver_port;
01065 }
01066 #endif
01067
01068
01069 #ifdef ENABLE_POOL
01070 ISocketHandler::PoolSocket *SocketHandler::FindConnection(int type,const std::string& protocol,SocketAddress& ad)
01071 {
01072 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end() && m_sockets.size(); it++)
01073 {
01074 PoolSocket *pools = dynamic_cast<PoolSocket *>(it -> second);
01075 if (pools)
01076 {
01077 if (pools -> GetSocketType() == type &&
01078 pools -> GetSocketProtocol() == protocol &&
01079
01080 *pools -> GetClientRemoteAddress() == ad)
01081 {
01082 m_sockets.erase(it);
01083 pools -> SetRetain();
01084 return pools;
01085 }
01086 }
01087 }
01088 return NULL;
01089 }
01090
01091
01092 void SocketHandler::EnablePool(bool x)
01093 {
01094 m_b_enable_pool = x;
01095 }
01096
01097
01098 bool SocketHandler::PoolEnabled()
01099 {
01100 return m_b_enable_pool;
01101 }
01102 #endif
01103
01104
01105 void SocketHandler::Remove(Socket *p)
01106 {
01107 if (p -> ErasedByHandler())
01108 {
01109 return;
01110 }
01111 for (socket_m::iterator it = m_sockets.begin(); it != m_sockets.end(); it++)
01112 {
01113 if (it -> second == p)
01114 {
01115 LogError(p, "Remove", -1, "Socket destructor called while still in use", LOG_LEVEL_WARNING);
01116 m_sockets.erase(it);
01117 return;
01118 }
01119 }
01120 for (socket_m::iterator it2 = m_add.begin(); it2 != m_add.end(); it2++)
01121 {
01122 if ((*it2).second == p)
01123 {
01124 LogError(p, "Remove", -2, "Socket destructor called while still in use", LOG_LEVEL_WARNING);
01125 m_add.erase(it2);
01126 return;
01127 }
01128 }
01129 for (std::list<Socket *>::iterator it3 = m_delete.begin(); it3 != m_delete.end(); it3++)
01130 {
01131 if (*it3 == p)
01132 {
01133 LogError(p, "Remove", -3, "Socket destructor called while still in use", LOG_LEVEL_WARNING);
01134 m_delete.erase(it3);
01135 return;
01136 }
01137 }
01138 }
01139
01140
01141 void SocketHandler::CheckSanity()
01142 {
01143 CheckList(m_fds, "active sockets");
01144 CheckList(m_fds_erase, "sockets to be erased");
01145 CheckList(m_fds_callonconnect, "checklist CallOnConnect");
01146 #ifdef ENABLE_DETACH
01147 CheckList(m_fds_detach, "checklist Detach");
01148 #endif
01149 CheckList(m_fds_connecting, "checklist Connecting");
01150 CheckList(m_fds_retry, "checklist retry client connect");
01151 CheckList(m_fds_close, "checklist close and delete");
01152 }
01153
01154
01155 void SocketHandler::CheckList(socket_v& ref,const std::string& listname)
01156 {
01157 for (socket_v::iterator it = ref.begin(); it != ref.end(); it++)
01158 {
01159 SOCKET s = *it;
01160 if (m_sockets.find(s) != m_sockets.end())
01161 continue;
01162 if (m_add.find(s) != m_add.end())
01163 continue;
01164 bool found = false;
01165 for (std::list<Socket *>::iterator it = m_delete.begin(); it != m_delete.end(); it++)
01166 {
01167 Socket *p = *it;
01168 if (p -> GetSocket() == s)
01169 {
01170 found = true;
01171 break;
01172 }
01173 }
01174 if (!found)
01175 {
01176 fprintf(stderr, "CheckList failed for \"%s\": fd %d\n", listname.c_str(), s);
01177 }
01178 }
01179 }
01180
01181
01182 void SocketHandler::AddList(SOCKET s,list_t which_one,bool add)
01183 {
01184 if (s == INVALID_SOCKET)
01185 {
01186 return;
01187 }
01188 socket_v& ref =
01189 (which_one == LIST_CALLONCONNECT) ? m_fds_callonconnect :
01190 #ifdef ENABLE_DETACH
01191 (which_one == LIST_DETACH) ? m_fds_detach :
01192 #endif
01193 (which_one == LIST_CONNECTING) ? m_fds_connecting :
01194 (which_one == LIST_RETRY) ? m_fds_retry :
01195 (which_one == LIST_CLOSE) ? m_fds_close : m_fds_close;
01196 #ifdef ENABLE_DETACH
01197 DEB(
01198 fprintf(stderr, "%5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" :
01199 (which_one == LIST_DETACH) ? "Detach" :
01200 (which_one == LIST_CONNECTING) ? "Connecting" :
01201 (which_one == LIST_RETRY) ? "Retry" :
01202 (which_one == LIST_CLOSE) ? "Close" : "<undef>",
01203 add ? "Add" : "Remove");
01204 )
01205 #else
01206 DEB(
01207 fprintf(stderr, "%5d: %s: %s\n", s, (which_one == LIST_CALLONCONNECT) ? "CallOnConnect" :
01208 (which_one == LIST_CONNECTING) ? "Connecting" :
01209 (which_one == LIST_RETRY) ? "Retry" :
01210 (which_one == LIST_CLOSE) ? "Close" : "<undef>",
01211 add ? "Add" : "Remove");
01212 )
01213 #endif
01214 if (add)
01215 {
01216 for (socket_v::iterator it = ref.begin(); it != ref.end(); it++)
01217 {
01218 if (*it == s)
01219 {
01220 ref.erase(it);
01221 break;
01222 }
01223 }
01224 ref.push_back(s);
01225 return;
01226 }
01227
01228 for (socket_v::iterator it = ref.begin(); it != ref.end(); it++)
01229 {
01230 if (*it == s)
01231 {
01232 ref.erase(it);
01233 break;
01234 }
01235 }
01236 DEB( fprintf(stderr, "/AddList\n");)
01237 }
01238
01239
01240 #ifdef SOCKETS_NAMESPACE
01241 }
01242 #endif