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 #include "ISocketHandler.h"
00037 #include <fcntl.h>
00038 #include <assert.h>
00039 #include <stdarg.h>
00040 #ifdef HAVE_OPENSSL
00041 #include <openssl/rand.h>
00042 #include <openssl/err.h>
00043 #endif
00044
00045 #include "TcpSocket.h"
00046 #include "Utility.h"
00047 #include "Ipv4Address.h"
00048 #include "Ipv6Address.h"
00049 #include "Mutex.h"
00050 #include "IFile.h"
00051
00052 #ifdef SOCKETS_NAMESPACE
00053 namespace SOCKETS_NAMESPACE {
00054 #endif
00055
00056
00057 #ifdef _DEBUG
00058 #define DEB(x) x
00059 #else
00060 #define DEB(x)
00061 #endif
00062
00063
00064
00065 #ifdef HAVE_OPENSSL
00066 SSLInitializer TcpSocket::m_ssl_init;
00067 #endif
00068
00069
00070
00071 #ifdef _WIN32
00072 #pragma warning(disable:4355)
00073 #endif
00074 TcpSocket::TcpSocket(ISocketHandler& h) : StreamSocket(h)
00075 ,ibuf(TCP_BUFSIZE_READ)
00076 ,m_b_input_buffer_disabled(false)
00077 ,m_bytes_sent(0)
00078 ,m_bytes_received(0)
00079 ,m_skip_c(false)
00080 #ifdef SOCKETS_DYNAMIC_TEMP
00081 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00082 #endif
00083 ,m_obuf_top(NULL)
00084 ,m_transfer_limit(0)
00085 ,m_output_length(0)
00086 #ifdef HAVE_OPENSSL
00087 ,m_ssl_ctx(NULL)
00088 ,m_ssl(NULL)
00089 ,m_sbio(NULL)
00090 #endif
00091 #ifdef ENABLE_SOCKS4
00092 ,m_socks4_state(0)
00093 #endif
00094 #ifdef ENABLE_RESOLVER
00095 ,m_resolver_id(0)
00096 #endif
00097 #ifdef ENABLE_RECONNECT
00098 ,m_b_reconnect(false)
00099 ,m_b_is_reconnect(false)
00100 #endif
00101 {
00102 }
00103 #ifdef _WIN32
00104 #pragma warning(default:4355)
00105 #endif
00106
00107
00108 #ifdef _WIN32
00109 #pragma warning(disable:4355)
00110 #endif
00111 TcpSocket::TcpSocket(ISocketHandler& h,size_t isize,size_t osize) : StreamSocket(h)
00112 ,ibuf(isize)
00113 ,m_b_input_buffer_disabled(false)
00114 ,m_bytes_sent(0)
00115 ,m_bytes_received(0)
00116 ,m_skip_c(false)
00117 #ifdef SOCKETS_DYNAMIC_TEMP
00118 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00119 #endif
00120 ,m_obuf_top(NULL)
00121 ,m_transfer_limit(0)
00122 ,m_output_length(0)
00123 #ifdef HAVE_OPENSSL
00124 ,m_ssl_ctx(NULL)
00125 ,m_ssl(NULL)
00126 ,m_sbio(NULL)
00127 #endif
00128 #ifdef ENABLE_SOCKS4
00129 ,m_socks4_state(0)
00130 #endif
00131 #ifdef ENABLE_RESOLVER
00132 ,m_resolver_id(0)
00133 #endif
00134 #ifdef ENABLE_RECONNECT
00135 ,m_b_reconnect(false)
00136 ,m_b_is_reconnect(false)
00137 #endif
00138 {
00139 }
00140 #ifdef _WIN32
00141 #pragma warning(default:4355)
00142 #endif
00143
00144
00145 TcpSocket::~TcpSocket()
00146 {
00147 #ifdef SOCKETS_DYNAMIC_TEMP
00148 delete[] m_buf;
00149 #endif
00150
00151 #ifdef HAVE_OPENSSL
00152 if (m_ssl)
00153 {
00154 SSL_free(m_ssl);
00155 }
00156 #endif
00157 }
00158
00159
00160 bool TcpSocket::Open(ipaddr_t ip,port_t port,bool skip_socks)
00161 {
00162 Ipv4Address ad(ip, port);
00163 Ipv4Address local;
00164 return Open(ad, local, skip_socks);
00165 }
00166
00167
00168 #ifdef ENABLE_IPV6
00169 #ifdef IPPROTO_IPV6
00170 bool TcpSocket::Open(in6_addr ip,port_t port,bool skip_socks)
00171 {
00172 Ipv6Address ad(ip, port);
00173 return Open(ad, skip_socks);
00174 }
00175 #endif
00176 #endif
00177
00178
00179 bool TcpSocket::Open(SocketAddress& ad,bool skip_socks)
00180 {
00181 Ipv4Address bind_ad("0.0.0.0", 0);
00182 return Open(ad, bind_ad, skip_socks);
00183 }
00184
00185
00186 bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks)
00187 {
00188 if (!ad.IsValid())
00189 {
00190 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL);
00191 SetCloseAndDelete();
00192 return false;
00193 }
00194 if (Handler().GetCount() >= FD_SETSIZE)
00195 {
00196 Handler().LogError(this, "Open", 0, "no space left in fd_set", LOG_LEVEL_FATAL);
00197 SetCloseAndDelete();
00198 return false;
00199 }
00200 SetConnecting(false);
00201 #ifdef ENABLE_SOCKS4
00202 SetSocks4(false);
00203 #endif
00204
00205 #ifdef ENABLE_POOL
00206 if (Handler().PoolEnabled())
00207 {
00208 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad);
00209 if (pools)
00210 {
00211 CopyConnection( pools );
00212 delete pools;
00213
00214 SetIsClient();
00215 SetCallOnConnect();
00216 Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO);
00217 return true;
00218 }
00219 }
00220 #endif
00221
00222 SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp");
00223 if (s == INVALID_SOCKET)
00224 {
00225 return false;
00226 }
00227
00228 if (!SetNonblocking(true, s))
00229 {
00230 SetCloseAndDelete();
00231 closesocket(s);
00232 return false;
00233 }
00234 #ifdef ENABLE_POOL
00235 SetIsClient();
00236 #endif
00237 SetClientRemoteAddress(ad);
00238 int n = 0;
00239 if (bind_ad.GetPort() != 0)
00240 {
00241 bind(s, bind_ad, bind_ad);
00242 }
00243 #ifdef ENABLE_SOCKS4
00244 if (!skip_socks && GetSocks4Host() && GetSocks4Port())
00245 {
00246 Ipv4Address sa(GetSocks4Host(), GetSocks4Port());
00247 {
00248 std::string sockshost;
00249 Utility::l2ip(GetSocks4Host(), sockshost);
00250 Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" +
00251 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO);
00252 }
00253 SetSocks4();
00254 n = connect(s, sa, sa);
00255 SetRemoteAddress(sa);
00256 }
00257 else
00258 #endif
00259 {
00260 n = connect(s, ad, ad);
00261 SetRemoteAddress(ad);
00262 }
00263 if (n == -1)
00264 {
00265
00266 #ifdef _WIN32
00267 if (Errno == WSAEWOULDBLOCK)
00268 #else
00269 if (Errno == EINPROGRESS)
00270 #endif
00271 {
00272 Attach(s);
00273 SetConnecting( true );
00274 }
00275 else
00276 #ifdef ENABLE_SOCKS4
00277 if (Socks4() && Handler().Socks4TryDirect() )
00278 {
00279 closesocket(s);
00280 return Open(ad, true);
00281 }
00282 else
00283 #endif
00284 #ifdef ENABLE_RECONNECT
00285 if (Reconnect())
00286 {
00287 Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
00288 Attach(s);
00289 SetConnecting( true );
00290 }
00291 else
00292 #endif
00293 {
00294 Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00295 SetCloseAndDelete();
00296 closesocket(s);
00297 return false;
00298 }
00299 }
00300 else
00301 {
00302 Attach(s);
00303 SetCallOnConnect();
00304 }
00305
00306
00307
00308 return true;
00309 }
00310
00311
00312 bool TcpSocket::Open(const std::string &host,port_t port)
00313 {
00314 #ifdef ENABLE_IPV6
00315 #ifdef IPPROTO_IPV6
00316 if (IsIpv6())
00317 {
00318 #ifdef ENABLE_RESOLVER
00319 if (!Handler().ResolverEnabled() || Utility::isipv6(host) )
00320 {
00321 #endif
00322 in6_addr a;
00323 if (!Utility::u2ip(host, a))
00324 {
00325 SetCloseAndDelete();
00326 return false;
00327 }
00328 Ipv6Address ad(a, port);
00329 Ipv6Address local;
00330 return Open(ad, local);
00331 #ifdef ENABLE_RESOLVER
00332 }
00333 m_resolver_id = Resolve6(host, port);
00334 return true;
00335 #endif
00336 }
00337 #endif
00338 #endif
00339 #ifdef ENABLE_RESOLVER
00340 if (!Handler().ResolverEnabled() || Utility::isipv4(host) )
00341 {
00342 #endif
00343 ipaddr_t l;
00344 if (!Utility::u2ip(host,l))
00345 {
00346 SetCloseAndDelete();
00347 return false;
00348 }
00349 Ipv4Address ad(l, port);
00350 Ipv4Address local;
00351 return Open(ad, local);
00352 #ifdef ENABLE_RESOLVER
00353 }
00354
00355 m_resolver_id = Resolve(host, port);
00356 return true;
00357 #endif
00358 }
00359
00360
00361 #ifdef ENABLE_RESOLVER
00362 void TcpSocket::OnResolved(int id,ipaddr_t a,port_t port)
00363 {
00364 if (id == m_resolver_id)
00365 {
00366 if (a && port)
00367 {
00368 Ipv4Address ad(a, port);
00369 Ipv4Address local;
00370 if (Open(ad, local))
00371 {
00372 if (!Handler().Valid(this))
00373 {
00374 Handler().Add(this);
00375 }
00376 }
00377 }
00378 else
00379 {
00380 Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL);
00381 SetCloseAndDelete();
00382 }
00383 }
00384 else
00385 {
00386 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL);
00387 SetCloseAndDelete();
00388 }
00389 }
00390
00391
00392 #ifdef ENABLE_IPV6
00393 void TcpSocket::OnResolved(int id,in6_addr& a,port_t port)
00394 {
00395 if (id == m_resolver_id)
00396 {
00397 Ipv6Address ad(a, port);
00398 if (ad.IsValid())
00399 {
00400 Ipv6Address local;
00401 if (Open(ad, local))
00402 {
00403 if (!Handler().Valid(this))
00404 {
00405 Handler().Add(this);
00406 }
00407 }
00408 }
00409 }
00410 else
00411 {
00412 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL);
00413 SetCloseAndDelete();
00414 }
00415 }
00416 #endif
00417 #endif
00418
00419
00420 void TcpSocket::OnRead()
00421 {
00422 int n = 0;
00423 #ifdef SOCKETS_DYNAMIC_TEMP
00424 char *buf = m_buf;
00425 #else
00426 char buf[TCP_BUFSIZE_READ];
00427 #endif
00428 #ifdef HAVE_OPENSSL
00429 if (IsSSL())
00430 {
00431 if (!Ready())
00432 return;
00433 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ);
00434 if (n == -1)
00435 {
00436 n = SSL_get_error(m_ssl, n);
00437 switch (n)
00438 {
00439 case SSL_ERROR_NONE:
00440 case SSL_ERROR_WANT_READ:
00441 case SSL_ERROR_WANT_WRITE:
00442 break;
00443 case SSL_ERROR_ZERO_RETURN:
00444 DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");)
00445 SetCloseAndDelete(true);
00446 SetFlushBeforeClose(false);
00447 #ifdef ENABLE_POOL
00448 SetLost();
00449 #endif
00450 break;
00451 default:
00452 DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);)
00453 SetCloseAndDelete(true);
00454 SetFlushBeforeClose(false);
00455 #ifdef ENABLE_POOL
00456 SetLost();
00457 #endif
00458 }
00459 return;
00460 }
00461 else
00462 if (!n)
00463 {
00464 OnDisconnect();
00465 SetCloseAndDelete(true);
00466 SetFlushBeforeClose(false);
00467 #ifdef ENABLE_POOL
00468 SetLost();
00469 #endif
00470 SetShutdown(SHUT_WR);
00471 return;
00472 }
00473 else
00474 if (n > 0 && n <= TCP_BUFSIZE_READ)
00475 {
00476 m_bytes_received += n;
00477 if (GetTrafficMonitor())
00478 {
00479 GetTrafficMonitor() -> fwrite(buf, 1, n);
00480 }
00481 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00482 {
00483 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00484 }
00485 }
00486 else
00487 {
00488 Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR);
00489 }
00490 }
00491 else
00492 #endif // HAVE_OPENSSL
00493 {
00494 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL);
00495 if (n == -1)
00496 {
00497 Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00498 SetCloseAndDelete(true);
00499 SetFlushBeforeClose(false);
00500 #ifdef ENABLE_POOL
00501 SetLost();
00502 #endif
00503 return;
00504 }
00505 else
00506 if (!n)
00507 {
00508 OnDisconnect();
00509 SetCloseAndDelete(true);
00510 SetFlushBeforeClose(false);
00511 #ifdef ENABLE_POOL
00512 SetLost();
00513 #endif
00514 SetShutdown(SHUT_WR);
00515 return;
00516 }
00517 else
00518 if (n > 0 && n <= TCP_BUFSIZE_READ)
00519 {
00520 m_bytes_received += n;
00521 if (GetTrafficMonitor())
00522 {
00523 GetTrafficMonitor() -> fwrite(buf, 1, n);
00524 }
00525 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00526 {
00527 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00528 }
00529 }
00530 else
00531 {
00532 Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR);
00533 }
00534 }
00535
00536 if (n > 0 && n <= TCP_BUFSIZE_READ)
00537 {
00538 if (LineProtocol())
00539 {
00540 buf[n] = 0;
00541 int i = 0;
00542 if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c)
00543 {
00544 m_skip_c = false;
00545 i++;
00546 }
00547 size_t x = i;
00548 for (; i < n && LineProtocol(); i++)
00549 {
00550 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol())
00551 {
00552 char c = buf[i];
00553 buf[i] = 0;
00554 if (buf[x])
00555 {
00556 m_line += (buf + x);
00557 }
00558 OnLine( m_line );
00559 i++;
00560 m_skip_c = true;
00561 m_c = c;
00562 if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c)
00563 {
00564 m_skip_c = false;
00565 i++;
00566 }
00567 x = i;
00568 m_line = "";
00569 }
00570 if (!LineProtocol())
00571 {
00572 break;
00573 }
00574 }
00575 if (!LineProtocol())
00576 {
00577 if (i < n)
00578 {
00579 OnRawData(buf + i, n - i);
00580 }
00581 }
00582 else
00583 if (buf[x])
00584 {
00585 m_line += (buf + x);
00586 }
00587 }
00588 else
00589 {
00590 OnRawData(buf, n);
00591 }
00592 }
00593 if (m_b_input_buffer_disabled)
00594 {
00595 return;
00596 }
00597
00598 #ifdef ENABLE_SOCKS4
00599 if (Socks4())
00600 {
00601 bool need_more = false;
00602 while (GetInputLength() && !need_more && !CloseAndDelete())
00603 {
00604 need_more = OnSocks4Read();
00605 }
00606 }
00607 #endif
00608 }
00609
00610
00611 void TcpSocket::OnWriteComplete()
00612 {
00613 }
00614
00615
00616 void TcpSocket::OnWrite()
00617 {
00618 if (Connecting())
00619 {
00620 int err = SoError();
00621
00622
00623 if (!err)
00624 {
00625 Set(!IsDisableRead(), false);
00626 SetConnecting(false);
00627 SetCallOnConnect();
00628 return;
00629 }
00630 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL);
00631 Set(false, false);
00632
00633
00634 #ifdef ENABLE_SOCKS4
00635 if (Socks4())
00636 {
00637
00638 OnSocks4ConnectFailed();
00639 return;
00640 }
00641 #endif
00642 if (GetConnectionRetry() == -1 ||
00643 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
00644 {
00645
00646
00647
00648
00649 return;
00650 }
00651 SetConnecting(false);
00652 SetCloseAndDelete( true );
00654 OnConnectFailed();
00655 return;
00656 }
00657
00658
00659
00660
00661 bool repeat = false;
00662 size_t sz = m_transfer_limit ? GetOutputLength() : 0;
00663 do
00664 {
00665 output_l::iterator it = m_obuf.begin();
00666 OUTPUT *p = *it;
00667 repeat = false;
00668 int n = TryWrite(p -> Buf(), p -> Len());
00669 if (n > 0)
00670 {
00671 size_t left = p -> Remove(n);
00672 m_output_length -= n;
00673 if (!left)
00674 {
00675 delete p;
00676 m_obuf.erase(it);
00677 if (!m_obuf.size())
00678 {
00679 m_obuf_top = NULL;
00680 OnWriteComplete();
00681 }
00682 else
00683 {
00684 repeat = true;
00685 }
00686 }
00687 }
00688 } while (repeat);
00689
00690 if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit)
00691 {
00692 OnTransferLimit();
00693 }
00694
00695
00696 {
00697 bool br;
00698 bool bw;
00699 bool bx;
00700 Handler().Get(GetSocket(), br, bw, bx);
00701 if (m_obuf.size())
00702 Set(br, true);
00703 else
00704 Set(br, false);
00705 }
00706 }
00707
00708
00709 int TcpSocket::TryWrite(const char *buf, size_t len)
00710 {
00711 int n = 0;
00712 #ifdef HAVE_OPENSSL
00713 if (IsSSL())
00714 {
00715 n = SSL_write(m_ssl, buf, len);
00716 if (n == -1)
00717 {
00718 int errnr = SSL_get_error(m_ssl, n);
00719 if ( errnr != SSL_ERROR_WANT_READ && errnr != SSL_ERROR_WANT_WRITE )
00720 {
00721 SetCloseAndDelete(true);
00722 SetFlushBeforeClose(false);
00723 #ifdef ENABLE_POOL
00724 SetLost();
00725 #endif
00726 const char *errbuf = ERR_error_string(errnr, NULL);
00727 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL);
00728 }
00729 }
00730 else
00731 if (!n)
00732 {
00733 SetCloseAndDelete(true);
00734 SetFlushBeforeClose(false);
00735 #ifdef ENABLE_POOL
00736 SetLost();
00737 #endif
00738 DEB( int errnr = SSL_get_error(m_ssl, n);
00739 const char *errbuf = ERR_error_string(errnr, NULL);
00740 fprintf(stderr, "SSL_write() returns 0: %d : %s\n",errnr, errbuf);)
00741 }
00742 }
00743 else
00744 #endif
00745 {
00746 n = send(GetSocket(), buf, len, MSG_NOSIGNAL);
00747 if (n == -1)
00748 {
00749
00750
00751
00752 #ifdef _WIN32
00753 if (Errno != WSAEWOULDBLOCK)
00754 #else
00755 if (Errno != EWOULDBLOCK)
00756 #endif
00757 {
00758 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00759 SetCloseAndDelete(true);
00760 SetFlushBeforeClose(false);
00761 #ifdef ENABLE_POOL
00762 SetLost();
00763 #endif
00764 }
00765 }
00766 }
00767 if (n > 0)
00768 {
00769 m_bytes_sent += n;
00770 if (GetTrafficMonitor())
00771 {
00772 GetTrafficMonitor() -> fwrite(buf, 1, n);
00773 }
00774 }
00775 return n;
00776 }
00777
00778
00779 void TcpSocket::Buffer(const char *buf, size_t len)
00780 {
00781 size_t ptr = 0;
00782 m_output_length += len;
00783 while (ptr < len)
00784 {
00785
00786 size_t space = 0;
00787 if (m_obuf_top && (space = m_obuf_top -> Space()) > 0)
00788 {
00789 const char *pbuf = buf + ptr;
00790 size_t sz = len - ptr;
00791 if (space >= sz)
00792 {
00793 m_obuf_top -> Add(pbuf, sz);
00794 ptr += sz;
00795 }
00796 else
00797 {
00798 m_obuf_top -> Add(pbuf, space);
00799 ptr += space;
00800 }
00801 }
00802 else
00803 {
00804 m_obuf_top = new OUTPUT;
00805 m_obuf.push_back( m_obuf_top );
00806 }
00807 }
00808 }
00809
00810
00811 void TcpSocket::Send(const std::string &str,int i)
00812 {
00813 SendBuf(str.c_str(),str.size(),i);
00814 }
00815
00816
00817 void TcpSocket::SendBuf(const char *buf,size_t len,int)
00818 {
00819 if (!Ready() && !Connecting())
00820 {
00821 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" );
00822 if (GetSocket() == INVALID_SOCKET)
00823 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO);
00824 if (Connecting())
00825 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO);
00826 if (CloseAndDelete())
00827 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO);
00828 return;
00829 }
00830 if (!IsConnected())
00831 {
00832 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" );
00833 Buffer(buf, len);
00834 return;
00835 }
00836 if (m_obuf_top)
00837 {
00838 Buffer(buf, len);
00839 return;
00840 }
00841 int n = TryWrite(buf, len);
00842 if (n > 0 && n < (int)len)
00843 {
00844 Buffer(buf + n, len - n);
00845 }
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855 {
00856 bool br;
00857 bool bw;
00858 bool bx;
00859 Handler().Get(GetSocket(), br, bw, bx);
00860 if (m_obuf.size())
00861 Set(br, true);
00862 else
00863 Set(br, false);
00864 }
00865 }
00866
00867
00868 void TcpSocket::OnLine(const std::string& )
00869 {
00870 }
00871
00872
00873 #ifdef _WIN32
00874 #pragma warning(disable:4355)
00875 #endif
00876 TcpSocket::TcpSocket(const TcpSocket& s)
00877 :StreamSocket(s)
00878 ,ibuf(0)
00879 {
00880 }
00881 #ifdef _WIN32
00882 #pragma warning(default:4355)
00883 #endif
00884
00885
00886 #ifdef ENABLE_SOCKS4
00887 void TcpSocket::OnSocks4Connect()
00888 {
00889 char request[1000];
00890 memset(request, 0, sizeof(request));
00891 request[0] = 4;
00892 request[1] = 1;
00893 {
00894 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress();
00895 if (ad.get())
00896 {
00897 struct sockaddr *p0 = (struct sockaddr *)*ad;
00898 struct sockaddr_in *p = (struct sockaddr_in *)p0;
00899 if (p -> sin_family == AF_INET)
00900 {
00901 memcpy(request + 2, &p -> sin_port, 2);
00902 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr));
00903 }
00904 else
00905 {
00907 }
00908 }
00909 else
00910 {
00912 }
00913 }
00914 strcpy(request + 8, GetSocks4Userid().c_str());
00915 size_t length = GetSocks4Userid().size() + 8 + 1;
00916 SendBuf(request, length);
00917 m_socks4_state = 0;
00918 }
00919
00920
00921 void TcpSocket::OnSocks4ConnectFailed()
00922 {
00923 Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING);
00924 if (!Handler().Socks4TryDirect())
00925 {
00926 SetConnecting(false);
00927 SetCloseAndDelete();
00928 OnConnectFailed();
00929 }
00930 else
00931 {
00932 SetRetryClientConnect();
00933 }
00934 }
00935
00936
00937 bool TcpSocket::OnSocks4Read()
00938 {
00939 switch (m_socks4_state)
00940 {
00941 case 0:
00942 ibuf.Read(&m_socks4_vn, 1);
00943 m_socks4_state = 1;
00944 break;
00945 case 1:
00946 ibuf.Read(&m_socks4_cd, 1);
00947 m_socks4_state = 2;
00948 break;
00949 case 2:
00950 if (GetInputLength() > 1)
00951 {
00952 ibuf.Read( (char *)&m_socks4_dstport, 2);
00953 m_socks4_state = 3;
00954 }
00955 else
00956 {
00957 return true;
00958 }
00959 break;
00960 case 3:
00961 if (GetInputLength() > 3)
00962 {
00963 ibuf.Read( (char *)&m_socks4_dstip, 4);
00964 SetSocks4(false);
00965
00966 switch (m_socks4_cd)
00967 {
00968 case 90:
00969 OnConnect();
00970 Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO);
00971 break;
00972 case 91:
00973 case 92:
00974 case 93:
00975 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL);
00976 SetConnecting(false);
00977 SetCloseAndDelete();
00978 OnConnectFailed();
00979 break;
00980 default:
00981 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL);
00982 SetCloseAndDelete();
00983 break;
00984 }
00985 }
00986 else
00987 {
00988 return true;
00989 }
00990 break;
00991 }
00992 return false;
00993 }
00994 #endif
00995
00996
00997 void TcpSocket::Sendf(const char *format, ...)
00998 {
00999 va_list ap;
01000 va_start(ap, format);
01001 char slask[5000];
01002 #ifdef _WIN32
01003 vsprintf(slask, format, ap);
01004 #else
01005 vsnprintf(slask, 5000, format, ap);
01006 #endif
01007 va_end(ap);
01008 Send( slask );
01009 }
01010
01011
01012 #ifdef HAVE_OPENSSL
01013 void TcpSocket::OnSSLConnect()
01014 {
01015 SetNonblocking(true);
01016 {
01017 if (m_ssl_ctx)
01018 {
01019 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");)
01020 SetCloseAndDelete(true);
01021 return;
01022 }
01023 InitSSLClient();
01024 }
01025 if (m_ssl_ctx)
01026 {
01027
01028 m_ssl = SSL_new(m_ssl_ctx);
01029 if (!m_ssl)
01030 {
01031 DEB( fprintf(stderr, " m_ssl is NULL\n");)
01032 SetCloseAndDelete(true);
01033 return;
01034 }
01035 SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY);
01036 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE);
01037 if (!m_sbio)
01038 {
01039 DEB( fprintf(stderr, " m_sbio is NULL\n");)
01040 SetCloseAndDelete(true);
01041 return;
01042 }
01043 SSL_set_bio(m_ssl, m_sbio, m_sbio);
01044
01045 {
01046 SetSSLNegotiate();
01047 }
01048 }
01049 else
01050 {
01051 SetCloseAndDelete();
01052 }
01053 }
01054
01055
01056 void TcpSocket::OnSSLAccept()
01057 {
01058 SetNonblocking(true);
01059 {
01060 if (m_ssl_ctx)
01061 {
01062 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");)
01063 SetCloseAndDelete(true);
01064 return;
01065 }
01066 InitSSLServer();
01067 SetSSLServer();
01068 }
01069 if (m_ssl_ctx)
01070 {
01071 m_ssl = SSL_new(m_ssl_ctx);
01072 if (!m_ssl)
01073 {
01074 DEB( fprintf(stderr, " m_ssl is NULL\n");)
01075 SetCloseAndDelete(true);
01076 return;
01077 }
01078 SSL_set_mode(m_ssl, SSL_MODE_AUTO_RETRY);
01079 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE);
01080 if (!m_sbio)
01081 {
01082 DEB( fprintf(stderr, " m_sbio is NULL\n");)
01083 SetCloseAndDelete(true);
01084 return;
01085 }
01086 SSL_set_bio(m_ssl, m_sbio, m_sbio);
01087
01088 {
01089 SetSSLNegotiate();
01090 }
01091 }
01092 }
01093
01094
01095 bool TcpSocket::SSLNegotiate()
01096 {
01097 if (!IsSSLServer())
01098 {
01099 int r = SSL_connect(m_ssl);
01100 if (r > 0)
01101 {
01102 SetSSLNegotiate(false);
01104
01105 SetNonblocking(false);
01106
01107 {
01108 SetConnected();
01109 if (GetOutputLength())
01110 {
01111 OnWrite();
01112 }
01113 }
01114 #ifdef ENABLE_RECONNECT
01115 if (IsReconnect())
01116 OnReconnect();
01117 else
01118 #endif
01119 {
01120 OnConnect();
01121 }
01122 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO);
01123 return true;
01124 }
01125 else
01126 if (!r)
01127 {
01128 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO);
01129 SetSSLNegotiate(false);
01130 SetCloseAndDelete();
01131 OnSSLConnectFailed();
01132 }
01133 else
01134 {
01135 r = SSL_get_error(m_ssl, r);
01136 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
01137 {
01138 Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO);
01139 DEB( fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);)
01140 SetSSLNegotiate(false);
01141 SetCloseAndDelete(true);
01142 OnSSLConnectFailed();
01143 }
01144 }
01145 }
01146 else
01147 {
01148 int r = SSL_accept(m_ssl);
01149 if (r > 0)
01150 {
01151 SetSSLNegotiate(false);
01153
01154 SetNonblocking(false);
01155
01156 {
01157 SetConnected();
01158 if (GetOutputLength())
01159 {
01160 OnWrite();
01161 }
01162 }
01163 OnAccept();
01164 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO);
01165 return true;
01166 }
01167 else
01168 if (!r)
01169 {
01170 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO);
01171 SetSSLNegotiate(false);
01172 SetCloseAndDelete();
01173 OnSSLAcceptFailed();
01174 }
01175 else
01176 {
01177 r = SSL_get_error(m_ssl, r);
01178 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
01179 {
01180 Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO);
01181 DEB( fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);)
01182 SetSSLNegotiate(false);
01183 SetCloseAndDelete(true);
01184 OnSSLAcceptFailed();
01185 }
01186 }
01187 }
01188 return false;
01189 }
01190
01191
01192 void TcpSocket::InitSSLClient()
01193 {
01194 InitializeContext("", SSLv23_method());
01195 }
01196
01197
01198 void TcpSocket::InitSSLServer()
01199 {
01200 Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL);
01201 SetCloseAndDelete();
01202 }
01203
01204
01205 void TcpSocket::InitializeContext(const std::string& context, SSL_METHOD *meth_in)
01206 {
01207
01208 static std::map<std::string, SSL_CTX *> client_contexts;
01209 if (client_contexts.find(context) == client_contexts.end())
01210 {
01211 SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01212 m_ssl_ctx = client_contexts[context] = SSL_CTX_new(meth);
01213 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY);
01214 }
01215 else
01216 {
01217 m_ssl_ctx = client_contexts[context];
01218 }
01219 }
01220
01221
01222 void TcpSocket::InitializeContext(const std::string& context,const std::string& keyfile,const std::string& password,SSL_METHOD *meth_in)
01223 {
01224
01225 static std::map<std::string, SSL_CTX *> server_contexts;
01226 if (server_contexts.find(context) == server_contexts.end())
01227 {
01228 SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01229 m_ssl_ctx = server_contexts[context] = SSL_CTX_new(meth);
01230 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY);
01231
01232 if (context.size())
01233 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size());
01234 else
01235 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9);
01236 }
01237 else
01238 {
01239 m_ssl_ctx = server_contexts[context];
01240 }
01241
01242
01243 if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01244 {
01245 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL);
01246 }
01247
01248 m_password = password;
01249 SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb);
01250 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this);
01251 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01252 {
01253 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL);
01254 }
01255 }
01256
01257
01258 int TcpSocket::SSL_password_cb(char *buf,int num,int rwflag,void *userdata)
01259 {
01260 Socket *p0 = static_cast<Socket *>(userdata);
01261 TcpSocket *p = dynamic_cast<TcpSocket *>(p0);
01262 std::string pw = p ? p -> GetPassword() : "";
01263 if ( (size_t)num < pw.size() + 1)
01264 {
01265 return 0;
01266 }
01267 strcpy(buf,pw.c_str());
01268 return (int)pw.size();
01269 }
01270 #endif // HAVE_OPENSSL
01271
01272
01273 int TcpSocket::Close()
01274 {
01275 if (GetSocket() == INVALID_SOCKET)
01276 {
01277 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING);
01278 return 0;
01279 }
01280 int n;
01281 SetNonblocking(true);
01282 if (IsConnected() && !(GetShutdown() & SHUT_WR))
01283 {
01284 if (shutdown(GetSocket(), SHUT_WR) == -1)
01285 {
01286
01287 Handler().LogError(this, "shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR);
01288 }
01289 }
01290
01291 char tmp[1000];
01292 if ((n = recv(GetSocket(),tmp,1000,0)) >= 0)
01293 {
01294 if (n)
01295 {
01296 Handler().LogError(this, "read() after shutdown", n, "bytes read", LOG_LEVEL_WARNING);
01297 }
01298 }
01299 #ifdef HAVE_OPENSSL
01300 if (IsSSL() && m_ssl)
01301 SSL_shutdown(m_ssl);
01302 if (m_ssl)
01303 {
01304 SSL_free(m_ssl);
01305 m_ssl = NULL;
01306 }
01307 #endif
01308 return Socket::Close();
01309 }
01310
01311
01312 #ifdef HAVE_OPENSSL
01313 SSL_CTX *TcpSocket::GetSslContext()
01314 {
01315 if (!m_ssl_ctx)
01316 Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01317 return m_ssl_ctx;
01318 }
01319
01320 SSL *TcpSocket::GetSsl()
01321 {
01322 if (!m_ssl)
01323 Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01324 return m_ssl;
01325 }
01326 #endif
01327
01328
01329 #ifdef ENABLE_RECONNECT
01330 void TcpSocket::SetReconnect(bool x)
01331 {
01332 m_b_reconnect = x;
01333 }
01334 #endif
01335
01336
01337 void TcpSocket::OnRawData(const char *buf_in,size_t len)
01338 {
01339 }
01340
01341
01342 size_t TcpSocket::GetInputLength()
01343 {
01344 return ibuf.GetLength();
01345 }
01346
01347
01348 size_t TcpSocket::GetOutputLength()
01349 {
01350 return m_output_length;
01351
01352
01353
01354
01355
01356
01357 }
01358
01359
01360 uint64_t TcpSocket::GetBytesReceived(bool clear)
01361 {
01362 uint64_t z = m_bytes_received;
01363 if (clear)
01364 m_bytes_received = 0;
01365 return z;
01366 }
01367
01368
01369 uint64_t TcpSocket::GetBytesSent(bool clear)
01370 {
01371 uint64_t z = m_bytes_sent;
01372 if (clear)
01373 m_bytes_sent = 0;
01374 return z;
01375 }
01376
01377
01378 #ifdef ENABLE_RECONNECT
01379 bool TcpSocket::Reconnect()
01380 {
01381 return m_b_reconnect;
01382 }
01383
01384
01385 void TcpSocket::SetIsReconnect(bool x)
01386 {
01387 m_b_is_reconnect = x;
01388 }
01389
01390
01391 bool TcpSocket::IsReconnect()
01392 {
01393 return m_b_is_reconnect;
01394 }
01395 #endif
01396
01397
01398 #ifdef HAVE_OPENSSL
01399 const std::string& TcpSocket::GetPassword()
01400 {
01401 return m_password;
01402 }
01403 #endif
01404
01405
01406 void TcpSocket::DisableInputBuffer(bool x)
01407 {
01408 m_b_input_buffer_disabled = x;
01409 }
01410
01411
01412 void TcpSocket::OnOptions(int family,int type,int protocol,SOCKET s)
01413 {
01414 DEB( fprintf(stderr, "Socket::OnOptions()\n");)
01415 #ifdef SO_NOSIGPIPE
01416 SetSoNosigpipe(true);
01417 #endif
01418 SetSoReuseaddr(true);
01419 SetSoKeepalive(true);
01420 }
01421
01422
01423 void TcpSocket::SetLineProtocol(bool x)
01424 {
01425 StreamSocket::SetLineProtocol(x);
01426 DisableInputBuffer(x);
01427 }
01428
01429
01430 bool TcpSocket::SetTcpNodelay(bool x)
01431 {
01432 #ifdef TCP_NODELAY
01433 int optval = x ? 1 : 0;
01434 if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1)
01435 {
01436 Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
01437 return false;
01438 }
01439 return true;
01440 #else
01441 Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO);
01442 return false;
01443 #endif
01444 }
01445
01446
01447 TcpSocket::CircularBuffer::CircularBuffer(size_t size)
01448 :buf(new char[2 * size])
01449 ,m_max(size)
01450 ,m_q(0)
01451 ,m_b(0)
01452 ,m_t(0)
01453 ,m_count(0)
01454 {
01455 }
01456
01457
01458 TcpSocket::CircularBuffer::~CircularBuffer()
01459 {
01460 delete[] buf;
01461 }
01462
01463
01464 bool TcpSocket::CircularBuffer::Write(const char *s,size_t l)
01465 {
01466 if (m_q + l > m_max)
01467 {
01468 return false;
01469 }
01470 m_count += (unsigned long)l;
01471 if (m_t + l > m_max)
01472 {
01473 size_t l1 = m_max - m_t;
01474
01475
01476 memcpy(buf + m_t, s, l);
01477 memcpy(buf, s + l1, l - l1);
01478 m_t = l - l1;
01479 m_q += l;
01480 }
01481 else
01482 {
01483 memcpy(buf + m_t, s, l);
01484 memcpy(buf + m_max + m_t, s, l);
01485 m_t += l;
01486 if (m_t >= m_max)
01487 m_t -= m_max;
01488 m_q += l;
01489 }
01490 return true;
01491 }
01492
01493
01494 bool TcpSocket::CircularBuffer::Read(char *s,size_t l)
01495 {
01496 if (l > m_q)
01497 {
01498 return false;
01499 }
01500 if (m_b + l > m_max)
01501 {
01502 size_t l1 = m_max - m_b;
01503 if (s)
01504 {
01505 memcpy(s, buf + m_b, l1);
01506 memcpy(s + l1, buf, l - l1);
01507 }
01508 m_b = l - l1;
01509 m_q -= l;
01510 }
01511 else
01512 {
01513 if (s)
01514 {
01515 memcpy(s, buf + m_b, l);
01516 }
01517 m_b += l;
01518 if (m_b >= m_max)
01519 m_b -= m_max;
01520 m_q -= l;
01521 }
01522 if (!m_q)
01523 {
01524 m_b = m_t = 0;
01525 }
01526 return true;
01527 }
01528
01529
01530 bool TcpSocket::CircularBuffer::Remove(size_t l)
01531 {
01532 return Read(NULL, l);
01533 }
01534
01535
01536 size_t TcpSocket::CircularBuffer::GetLength()
01537 {
01538 return m_q;
01539 }
01540
01541
01542 const char *TcpSocket::CircularBuffer::GetStart()
01543 {
01544 return buf + m_b;
01545 }
01546
01547
01548 size_t TcpSocket::CircularBuffer::GetL()
01549 {
01550 return (m_b + m_q > m_max) ? m_max - m_b : m_q;
01551 }
01552
01553
01554 size_t TcpSocket::CircularBuffer::Space()
01555 {
01556 return m_max - m_q;
01557 }
01558
01559
01560 unsigned long TcpSocket::CircularBuffer::ByteCounter(bool clear)
01561 {
01562 if (clear)
01563 {
01564 unsigned long x = m_count;
01565 m_count = 0;
01566 return x;
01567 }
01568 return m_count;
01569 }
01570
01571
01572 std::string TcpSocket::CircularBuffer::ReadString(size_t l)
01573 {
01574 char *sz = new char[l + 1];
01575 if (!Read(sz, l))
01576 {
01577 delete[] sz;
01578 return "";
01579 }
01580 sz[l] = 0;
01581 std::string tmp = sz;
01582 delete[] sz;
01583 return tmp;
01584 }
01585
01586
01587 void TcpSocket::OnConnectTimeout()
01588 {
01589 Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL);
01590 #ifdef ENABLE_SOCKS4
01591 if (Socks4())
01592 {
01593 OnSocks4ConnectFailed();
01594
01595 }
01596 else
01597 #endif
01598 if (GetConnectionRetry() == -1 ||
01599 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
01600 {
01601 IncreaseConnectionRetries();
01602
01603 if (OnConnectRetry())
01604 {
01605 SetRetryClientConnect();
01606 }
01607 else
01608 {
01609 SetCloseAndDelete( true );
01611 OnConnectFailed();
01612 }
01613 }
01614 else
01615 {
01616 SetCloseAndDelete(true);
01618 OnConnectFailed();
01619 }
01620
01621 SetConnecting(false);
01622 }
01623
01624
01625 #ifdef _WIN32
01626 void TcpSocket::OnException()
01627 {
01628 if (Connecting())
01629 {
01630 #ifdef ENABLE_SOCKS4
01631 if (Socks4())
01632 OnSocks4ConnectFailed();
01633 else
01634 #endif
01635 if (GetConnectionRetry() == -1 ||
01636 (GetConnectionRetry() &&
01637 GetConnectionRetries() < GetConnectionRetry() ))
01638 {
01639
01640
01641
01642
01643 }
01644 else
01645 {
01646 SetConnecting(false);
01647 SetCloseAndDelete();
01648 OnConnectFailed();
01649 }
01650 return;
01651 }
01652
01653
01654 int err = SoError();
01655 Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL);
01656 SetCloseAndDelete();
01657 }
01658 #endif // _WIN32
01659
01660
01661 int TcpSocket::Protocol()
01662 {
01663 return IPPROTO_TCP;
01664 }
01665
01666
01667 void TcpSocket::SetTransferLimit(size_t sz)
01668 {
01669 m_transfer_limit = sz;
01670 }
01671
01672
01673 void TcpSocket::OnTransferLimit()
01674 {
01675 }
01676
01677
01678 #ifdef SOCKETS_NAMESPACE
01679 }
01680 #endif