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() >= FD_SETSIZE)
00216 {
00217 Handler().LogError(this, "Open", 0, "no space left in fd_set", 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", 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", 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 Set(!IsDisableRead(), false);
00683 SetConnecting(false);
00684 SetCallOnConnect();
00685 return;
00686 }
00687 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL);
00688 Set(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", 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;
00767 bool bw;
00768 bool bx;
00769 Handler().Get(GetSocket(), br, bw, bx);
00770 if (m_obuf.size())
00771 Set(br, true);
00772 else
00773 Set(br, false);
00774 }
00775 }
00776
00777
00778 int TcpSocket::TryWrite(const char *buf, size_t len)
00779 {
00780 int n = 0;
00781 #ifdef HAVE_OPENSSL
00782 if (IsSSL())
00783 {
00784 n = SSL_write(m_ssl, buf, (int)(m_repeat_length ? m_repeat_length : len));
00785 if (n == -1)
00786 {
00787 int errnr = SSL_get_error(m_ssl, n);
00788 if ( errnr == SSL_ERROR_WANT_READ || errnr == SSL_ERROR_WANT_WRITE )
00789 {
00790 m_repeat_length = m_repeat_length ? m_repeat_length : len;
00791 }
00792 else
00793 {
00794 OnDisconnect();
00795 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR|TCP_DISCONNECT_SSL, errnr);
00796 SetCloseAndDelete(true);
00797 SetFlushBeforeClose(false);
00798 SetLost();
00799 {
00800 char errbuf[256];
00801 ERR_error_string_n(errnr, errbuf, 256);
00802 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL);
00803 }
00804 }
00805 return 0;
00806 }
00807 else
00808 if (!n)
00809 {
00810 OnDisconnect();
00811 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_SSL, 0);
00812 SetCloseAndDelete(true);
00813 SetFlushBeforeClose(false);
00814 SetLost();
00815 }
00816 m_repeat_length = 0;
00817 }
00818 else
00819 #endif // HAVE_OPENSSL
00820 {
00821 n = send(GetSocket(), buf, (int)len, MSG_NOSIGNAL);
00822 if (n == -1)
00823 {
00824
00825
00826
00827 #ifdef _WIN32
00828 if (Errno != WSAEWOULDBLOCK)
00829 #else
00830 if (Errno != EWOULDBLOCK)
00831 #endif
00832 {
00833 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00834 OnDisconnect();
00835 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR, Errno);
00836 SetCloseAndDelete(true);
00837 SetFlushBeforeClose(false);
00838 SetLost();
00839 }
00840 return 0;
00841 }
00842 }
00843 if (n > 0)
00844 {
00845 m_bytes_sent += n;
00846 if (GetTrafficMonitor())
00847 {
00848 GetTrafficMonitor() -> fwrite(buf, 1, n);
00849 }
00850 }
00851 return n;
00852 }
00853
00854
00855 void TcpSocket::Buffer(const char *buf, size_t len)
00856 {
00857 size_t ptr = 0;
00858 m_output_length += len;
00859 while (ptr < len)
00860 {
00861
00862 size_t space = 0;
00863 if (m_obuf_top && (space = m_obuf_top -> Space()) > 0)
00864 {
00865 const char *pbuf = buf + ptr;
00866 size_t sz = len - ptr;
00867 if (space >= sz)
00868 {
00869 m_obuf_top -> Add(pbuf, sz);
00870 ptr += sz;
00871 }
00872 else
00873 {
00874 m_obuf_top -> Add(pbuf, space);
00875 ptr += space;
00876 }
00877 }
00878 else
00879 {
00880 m_obuf_top = new OUTPUT;
00881 m_obuf.push_back( m_obuf_top );
00882 }
00883 }
00884 }
00885
00886
00887 void TcpSocket::Send(const std::string &str,int i)
00888 {
00889 SendBuf(str.c_str(),str.size(),i);
00890 }
00891
00892
00893 void TcpSocket::SendBuf(const char *buf,size_t len,int)
00894 {
00895 if (!Ready() && !Connecting())
00896 {
00897 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" );
00898 if (GetSocket() == INVALID_SOCKET)
00899 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO);
00900 if (Connecting())
00901 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO);
00902 if (CloseAndDelete())
00903 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO);
00904 return;
00905 }
00906 if (!IsConnected())
00907 {
00908 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" );
00909 Buffer(buf, len);
00910 return;
00911 }
00912 if (m_obuf_top)
00913 {
00914 Buffer(buf, len);
00915 return;
00916 }
00917 if (IsSSL())
00918 {
00919 Buffer(buf, len);
00920 SendFromOutputBuffer();
00921 return;
00922 }
00923 int n = TryWrite(buf, len);
00924 if (n >= 0 && n < (int)len)
00925 {
00926 Buffer(buf + n, len - n);
00927 }
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937 {
00938 bool br;
00939 bool bw;
00940 bool bx;
00941 Handler().Get(GetSocket(), br, bw, bx);
00942 if (m_obuf.size())
00943 Set(br, true);
00944 else
00945 Set(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 strcpy(request + 8, GetSocks4Userid().c_str());
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 #ifdef _WIN32
01085 vsprintf(slask, format, ap);
01086 #else
01087 vsnprintf(slask, 5000, format, ap);
01088 #endif
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 SSL_METHOD *meth = meth_in ? const_cast<SSL_METHOD *>(meth_in) : SSLv3_method();
01287 m_ssl_ctx = m_client_contexts[context] = SSL_CTX_new(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 Lock lock(m_server_ssl_mutex);
01300
01301 if (m_server_contexts.find(context) == m_server_contexts.end())
01302 {
01303 SSL_METHOD *meth = meth_in ? const_cast<SSL_METHOD *>(meth_in) : SSLv3_method();
01304 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(meth);
01305 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE);
01306
01307 if (context.size())
01308 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size());
01309 else
01310 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9);
01311 }
01312 else
01313 {
01314 m_ssl_ctx = m_server_contexts[context];
01315 }
01316
01317
01318 if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01319 {
01320 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL);
01321 }
01322
01323 m_password = password;
01324 SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb);
01325 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this);
01326 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01327 {
01328 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL);
01329 }
01330 }
01331
01332
01333 void TcpSocket::InitializeContext(const std::string& context,const std::string& certfile,const std::string& keyfile,const std::string& password,const SSL_METHOD *meth_in)
01334 {
01335 Lock lock(m_server_ssl_mutex);
01336
01337 if (m_server_contexts.find(context) == m_server_contexts.end())
01338 {
01339 SSL_METHOD *meth = meth_in ? const_cast<SSL_METHOD *>(meth_in) : SSLv3_method();
01340 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(meth);
01341 SSL_CTX_set_mode(m_ssl_ctx, SSL_MODE_AUTO_RETRY|SSL_MODE_ENABLE_PARTIAL_WRITE);
01342
01343 if (context.size())
01344 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)context.c_str(), (unsigned int)context.size());
01345 else
01346 SSL_CTX_set_session_id_context(m_ssl_ctx, (const unsigned char *)"--empty--", 9);
01347 }
01348 else
01349 {
01350 m_ssl_ctx = m_server_contexts[context];
01351 }
01352
01353
01354 if (!(SSL_CTX_use_certificate_file(m_ssl_ctx, certfile.c_str(), SSL_FILETYPE_PEM)))
01355 {
01356 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read certificate file " + keyfile, LOG_LEVEL_FATAL);
01357 }
01358
01359 m_password = password;
01360 SSL_CTX_set_default_passwd_cb(m_ssl_ctx, SSL_password_cb);
01361 SSL_CTX_set_default_passwd_cb_userdata(m_ssl_ctx, this);
01362 if (!(SSL_CTX_use_PrivateKey_file(m_ssl_ctx, keyfile.c_str(), SSL_FILETYPE_PEM)))
01363 {
01364 Handler().LogError(this, "TcpSocket InitializeContext", 0, "Couldn't read private key file " + keyfile, LOG_LEVEL_FATAL);
01365 }
01366 }
01367
01368
01369 int TcpSocket::SSL_password_cb(char *buf,int num,int rwflag,void *userdata)
01370 {
01371 Socket *p0 = static_cast<Socket *>(userdata);
01372 TcpSocket *p = dynamic_cast<TcpSocket *>(p0);
01373 std::string pw = p ? p -> GetPassword() : "";
01374 if ( (size_t)num < pw.size() + 1)
01375 {
01376 return 0;
01377 }
01378 strcpy(buf,pw.c_str());
01379 return (int)pw.size();
01380 }
01381 #endif // HAVE_OPENSSL
01382
01383
01384 int TcpSocket::Close()
01385 {
01386 if (GetSocket() == INVALID_SOCKET)
01387 {
01388 Handler().LogError(this, "Socket::Close", 0, "file descriptor invalid", LOG_LEVEL_WARNING);
01389 return 0;
01390 }
01391 int n;
01392 SetNonblocking(true);
01393 if (!Lost() && IsConnected() && !(GetShutdown() & SHUT_WR))
01394 {
01395 if (shutdown(GetSocket(), SHUT_WR) == -1)
01396 {
01397
01398 Handler().LogError(this, "shutdown", Errno, StrError(Errno), LOG_LEVEL_ERROR);
01399 }
01400 }
01401
01402 char tmp[1000];
01403 if (!Lost() && (n = recv(GetSocket(),tmp,1000,0)) >= 0)
01404 {
01405 if (n)
01406 {
01407 Handler().LogError(this, "read() after shutdown", n, "bytes read", LOG_LEVEL_WARNING);
01408 }
01409 }
01410 #ifdef HAVE_OPENSSL
01411 if (IsSSL() && m_ssl)
01412 SSL_shutdown(m_ssl);
01413 if (m_ssl)
01414 {
01415 SSL_free(m_ssl);
01416 m_ssl = NULL;
01417 }
01418 #endif
01419 return Socket::Close();
01420 }
01421
01422
01423 #ifdef HAVE_OPENSSL
01424 SSL_CTX *TcpSocket::GetSslContext()
01425 {
01426 if (!m_ssl_ctx)
01427 Handler().LogError(this, "GetSslContext", 0, "SSL Context is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01428 return m_ssl_ctx;
01429 }
01430
01431 SSL *TcpSocket::GetSsl()
01432 {
01433 if (!m_ssl)
01434 Handler().LogError(this, "GetSsl", 0, "SSL is NULL; check InitSSLServer/InitSSLClient", LOG_LEVEL_WARNING);
01435 return m_ssl;
01436 }
01437 #endif
01438
01439
01440 #ifdef ENABLE_RECONNECT
01441 void TcpSocket::SetReconnect(bool x)
01442 {
01443 m_b_reconnect = x;
01444 }
01445 #endif
01446
01447
01448 void TcpSocket::OnRawData(const char *buf_in,size_t len)
01449 {
01450 }
01451
01452
01453 size_t TcpSocket::GetInputLength()
01454 {
01455 return ibuf.GetLength();
01456 }
01457
01458
01459 size_t TcpSocket::ReadInput(char *buf, size_t max_sz)
01460 {
01461 size_t sz = max_sz < GetInputLength() ? max_sz : GetInputLength();
01462 ibuf.Read(buf, sz);
01463 return sz;
01464 }
01465
01466
01467 size_t TcpSocket::GetOutputLength()
01468 {
01469 return m_output_length;
01470 }
01471
01472
01473 uint64_t TcpSocket::GetBytesReceived(bool clear)
01474 {
01475 uint64_t z = m_bytes_received;
01476 if (clear)
01477 m_bytes_received = 0;
01478 return z;
01479 }
01480
01481
01482 uint64_t TcpSocket::GetBytesSent(bool clear)
01483 {
01484 uint64_t z = m_bytes_sent;
01485 if (clear)
01486 m_bytes_sent = 0;
01487 return z;
01488 }
01489
01490
01491 #ifdef ENABLE_RECONNECT
01492 bool TcpSocket::Reconnect()
01493 {
01494 return m_b_reconnect;
01495 }
01496
01497
01498 void TcpSocket::SetIsReconnect(bool x)
01499 {
01500 m_b_is_reconnect = x;
01501 }
01502
01503
01504 bool TcpSocket::IsReconnect()
01505 {
01506 return m_b_is_reconnect;
01507 }
01508 #endif
01509
01510
01511 #ifdef HAVE_OPENSSL
01512 const std::string& TcpSocket::GetPassword()
01513 {
01514 return m_password;
01515 }
01516 #endif
01517
01518
01519 void TcpSocket::DisableInputBuffer(bool x)
01520 {
01521 m_b_input_buffer_disabled = x;
01522 }
01523
01524
01525 void TcpSocket::OnOptions(int family,int type,int protocol,SOCKET s)
01526 {
01527 DEB( fprintf(stderr, "Socket::OnOptions()\n");)
01528 #ifdef SO_NOSIGPIPE
01529 SetSoNosigpipe(true);
01530 #endif
01531 SetSoReuseaddr(true);
01532 SetSoKeepalive(true);
01533 }
01534
01535
01536 void TcpSocket::SetLineProtocol(bool x)
01537 {
01538 StreamSocket::SetLineProtocol(x);
01539 DisableInputBuffer(x);
01540 }
01541
01542
01543 const std::string TcpSocket::GetLine() const
01544 {
01545 if (!m_line_ptr)
01546 return "";
01547 return std::string(&m_line[0], m_line_ptr);
01548 }
01549
01550
01551 bool TcpSocket::SetTcpNodelay(bool x)
01552 {
01553 #ifdef TCP_NODELAY
01554 int optval = x ? 1 : 0;
01555 if (setsockopt(GetSocket(), IPPROTO_TCP, TCP_NODELAY, (char *)&optval, sizeof(optval)) == -1)
01556 {
01557 Handler().LogError(this, "setsockopt(IPPROTO_TCP, TCP_NODELAY)", Errno, StrError(Errno), LOG_LEVEL_FATAL);
01558 return false;
01559 }
01560 return true;
01561 #else
01562 Handler().LogError(this, "socket option not available", 0, "TCP_NODELAY", LOG_LEVEL_INFO);
01563 return false;
01564 #endif
01565 }
01566
01567
01568 TcpSocket::CircularBuffer::CircularBuffer(size_t size)
01569 :buf(new char[2 * size])
01570 ,m_max(size)
01571 ,m_q(0)
01572 ,m_b(0)
01573 ,m_t(0)
01574 ,m_count(0)
01575 {
01576 }
01577
01578
01579 TcpSocket::CircularBuffer::~CircularBuffer()
01580 {
01581 delete[] buf;
01582 }
01583
01584
01585 bool TcpSocket::CircularBuffer::Write(const char *s,size_t l)
01586 {
01587 if (m_q + l > m_max)
01588 {
01589 return false;
01590 }
01591 m_count += (unsigned long)l;
01592 if (m_t + l > m_max)
01593 {
01594 size_t l1 = m_max - m_t;
01595
01596
01597 memcpy(buf + m_t, s, l);
01598 memcpy(buf, s + l1, l - l1);
01599 m_t = l - l1;
01600 m_q += l;
01601 }
01602 else
01603 {
01604 memcpy(buf + m_t, s, l);
01605 memcpy(buf + m_max + m_t, s, l);
01606 m_t += l;
01607 if (m_t >= m_max)
01608 m_t -= m_max;
01609 m_q += l;
01610 }
01611 return true;
01612 }
01613
01614
01615 bool TcpSocket::CircularBuffer::Read(char *s,size_t l)
01616 {
01617 if (l > m_q)
01618 {
01619 return false;
01620 }
01621 if (m_b + l > m_max)
01622 {
01623 size_t l1 = m_max - m_b;
01624 if (s)
01625 {
01626 memcpy(s, buf + m_b, l1);
01627 memcpy(s + l1, buf, l - l1);
01628 }
01629 m_b = l - l1;
01630 m_q -= l;
01631 }
01632 else
01633 {
01634 if (s)
01635 {
01636 memcpy(s, buf + m_b, l);
01637 }
01638 m_b += l;
01639 if (m_b >= m_max)
01640 m_b -= m_max;
01641 m_q -= l;
01642 }
01643 if (!m_q)
01644 {
01645 m_b = m_t = 0;
01646 }
01647 return true;
01648 }
01649
01650
01651 bool TcpSocket::CircularBuffer::Remove(size_t l)
01652 {
01653 return Read(NULL, l);
01654 }
01655
01656
01657 size_t TcpSocket::CircularBuffer::GetLength()
01658 {
01659 return m_q;
01660 }
01661
01662
01663 const char *TcpSocket::CircularBuffer::GetStart()
01664 {
01665 return buf + m_b;
01666 }
01667
01668
01669 size_t TcpSocket::CircularBuffer::GetL()
01670 {
01671 return (m_b + m_q > m_max) ? m_max - m_b : m_q;
01672 }
01673
01674
01675 size_t TcpSocket::CircularBuffer::Space()
01676 {
01677 return m_max - m_q;
01678 }
01679
01680
01681 unsigned long TcpSocket::CircularBuffer::ByteCounter(bool clear)
01682 {
01683 if (clear)
01684 {
01685 unsigned long x = m_count;
01686 m_count = 0;
01687 return x;
01688 }
01689 return m_count;
01690 }
01691
01692
01693 std::string TcpSocket::CircularBuffer::ReadString(size_t l)
01694 {
01695 char *sz = new char[l + 1];
01696 if (!Read(sz, l))
01697 {
01698 delete[] sz;
01699 return "";
01700 }
01701 sz[l] = 0;
01702 std::string tmp = sz;
01703 delete[] sz;
01704 return tmp;
01705 }
01706
01707
01708 void TcpSocket::OnConnectTimeout()
01709 {
01710 Handler().LogError(this, "connect", -1, "connect timeout", LOG_LEVEL_FATAL);
01711 #ifdef ENABLE_SOCKS4
01712 if (Socks4())
01713 {
01714 OnSocks4ConnectFailed();
01715
01716 }
01717 else
01718 #endif
01719 if (GetConnectionRetry() == -1 ||
01720 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
01721 {
01722 IncreaseConnectionRetries();
01723
01724 if (OnConnectRetry())
01725 {
01726 SetRetryClientConnect();
01727 }
01728 else
01729 {
01730 SetCloseAndDelete( true );
01732 OnConnectFailed();
01733 }
01734 }
01735 else
01736 {
01737 SetCloseAndDelete(true);
01739 OnConnectFailed();
01740 }
01741
01742 SetConnecting(false);
01743 }
01744
01745
01746 #ifdef _WIN32
01747 void TcpSocket::OnException()
01748 {
01749 if (Connecting())
01750 {
01751 #ifdef ENABLE_SOCKS4
01752 if (Socks4())
01753 OnSocks4ConnectFailed();
01754 else
01755 #endif
01756 if (GetConnectionRetry() == -1 ||
01757 (GetConnectionRetry() &&
01758 GetConnectionRetries() < GetConnectionRetry() ))
01759 {
01760
01761
01762
01763
01764 }
01765 else
01766 {
01767 SetConnecting(false);
01768 SetCloseAndDelete();
01769 OnConnectFailed();
01770 }
01771 return;
01772 }
01773
01774
01775 int err = SoError();
01776 Handler().LogError(this, "exception on select", err, StrError(err), LOG_LEVEL_FATAL);
01777 SetCloseAndDelete();
01778 }
01779 #endif // _WIN32
01780
01781
01782 int TcpSocket::Protocol()
01783 {
01784 return IPPROTO_TCP;
01785 }
01786
01787
01788 void TcpSocket::SetTransferLimit(size_t sz)
01789 {
01790 m_transfer_limit = sz;
01791 }
01792
01793
01794 void TcpSocket::OnTransferLimit()
01795 {
01796 }
01797
01798
01799 TcpSocket::OUTPUT::OUTPUT() : _b(0), _t(0), _q(0)
01800 {
01801 }
01802
01803
01804 TcpSocket::OUTPUT::OUTPUT(const char *buf, size_t len) : _b(0), _t(len), _q(len)
01805 {
01806 memcpy(_buf, buf, len);
01807 }
01808
01809
01810 size_t TcpSocket::OUTPUT::Space()
01811 {
01812 return TCP_OUTPUT_CAPACITY - _t;
01813 }
01814
01815
01816 void TcpSocket::OUTPUT::Add(const char *buf, size_t len)
01817 {
01818 memcpy(_buf + _t, buf, len);
01819 _t += len;
01820 _q += len;
01821 }
01822
01823
01824 size_t TcpSocket::OUTPUT::Remove(size_t len)
01825 {
01826 _b += len;
01827 _q -= len;
01828 return _q;
01829 }
01830
01831
01832 const char *TcpSocket::OUTPUT::Buf()
01833 {
01834 return _buf + _b;
01835 }
01836
01837
01838 size_t TcpSocket::OUTPUT::Len()
01839 {
01840 return _q;
01841 }
01842
01843
01844 #ifdef SOCKETS_NAMESPACE
01845 }
01846 #endif
01847