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