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