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