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
00051 #include "TcpSocket.h"
00052 #include "Utility.h"
00053 #include "Ipv4Address.h"
00054 #include "Ipv6Address.h"
00055 #include "IFile.h"
00056 #include "Lock.h"
00057
00058 #ifdef SOCKETS_NAMESPACE
00059 namespace SOCKETS_NAMESPACE {
00060 #endif
00061
00062
00063 #ifdef _DEBUG
00064 #define DEB(x) x
00065 #else
00066 #define DEB(x)
00067 #endif
00068
00069
00070
00071 #ifdef HAVE_OPENSSL
00072 SSLInitializer TcpSocket::m_ssl_init;
00073 Mutex TcpSocket::m_server_ssl_mutex;
00074 std::map<std::string, SSL_CTX *> TcpSocket::m_client_contexts;
00075 std::map<std::string, SSL_CTX *> TcpSocket::m_server_contexts;
00076 #endif
00077
00078
00079
00080 #ifdef _MSC_VER
00081 #pragma warning(disable:4355)
00082 #endif
00083 TcpSocket::TcpSocket(ISocketHandler& h) : StreamSocket(h)
00084 ,ibuf(TCP_BUFSIZE_READ)
00085 ,m_b_input_buffer_disabled(false)
00086 ,m_bytes_sent(0)
00087 ,m_bytes_received(0)
00088 ,m_skip_c(false)
00089 ,m_line(Handler().MaxTcpLineSize())
00090 ,m_line_ptr(0)
00091 #ifdef SOCKETS_DYNAMIC_TEMP
00092 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00093 #endif
00094 ,m_obuf_top(NULL)
00095 ,m_transfer_limit(0)
00096 ,m_output_length(0)
00097 ,m_repeat_length(0)
00098 #ifdef HAVE_OPENSSL
00099 ,m_ssl_ctx(NULL)
00100 ,m_ssl(NULL)
00101 ,m_sbio(NULL)
00102 #endif
00103 #ifdef ENABLE_SOCKS4
00104 ,m_socks4_state(0)
00105 #endif
00106 #ifdef ENABLE_RESOLVER
00107 ,m_resolver_id(0)
00108 #endif
00109 #ifdef ENABLE_RECONNECT
00110 ,m_b_reconnect(false)
00111 ,m_b_is_reconnect(false)
00112 #endif
00113 {
00114 }
00115 #ifdef _MSC_VER
00116 #pragma warning(default:4355)
00117 #endif
00118
00119
00120 #ifdef _MSC_VER
00121 #pragma warning(disable:4355)
00122 #endif
00123 TcpSocket::TcpSocket(ISocketHandler& h,size_t isize,size_t osize) : StreamSocket(h)
00124 ,ibuf(isize)
00125 ,m_b_input_buffer_disabled(false)
00126 ,m_bytes_sent(0)
00127 ,m_bytes_received(0)
00128 ,m_skip_c(false)
00129 ,m_line(Handler().MaxTcpLineSize())
00130 ,m_line_ptr(0)
00131 #ifdef SOCKETS_DYNAMIC_TEMP
00132 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00133 #endif
00134 ,m_obuf_top(NULL)
00135 ,m_transfer_limit(0)
00136 ,m_output_length(0)
00137 ,m_repeat_length(0)
00138 #ifdef HAVE_OPENSSL
00139 ,m_ssl_ctx(NULL)
00140 ,m_ssl(NULL)
00141 ,m_sbio(NULL)
00142 #endif
00143 #ifdef ENABLE_SOCKS4
00144 ,m_socks4_state(0)
00145 #endif
00146 #ifdef ENABLE_RESOLVER
00147 ,m_resolver_id(0)
00148 #endif
00149 #ifdef ENABLE_RECONNECT
00150 ,m_b_reconnect(false)
00151 ,m_b_is_reconnect(false)
00152 #endif
00153 {
00154 }
00155 #ifdef _MSC_VER
00156 #pragma warning(default:4355)
00157 #endif
00158
00159
00160 TcpSocket::~TcpSocket()
00161 {
00162 #ifdef SOCKETS_DYNAMIC_TEMP
00163 delete[] m_buf;
00164 #endif
00165
00166 while (m_obuf.size())
00167 {
00168 output_l::iterator it = m_obuf.begin();
00169 OUTPUT *p = *it;
00170 delete p;
00171 m_obuf.erase(it);
00172 }
00173 #ifdef HAVE_OPENSSL
00174 if (m_ssl)
00175 {
00176 SSL_free(m_ssl);
00177 }
00178 #endif
00179 }
00180
00181
00182 bool TcpSocket::Open(ipaddr_t ip,port_t port,bool skip_socks)
00183 {
00184 Ipv4Address ad(ip, port);
00185 Ipv4Address local;
00186 return Open(ad, local, skip_socks);
00187 }
00188
00189
00190 #ifdef ENABLE_IPV6
00191 #ifdef IPPROTO_IPV6
00192 bool TcpSocket::Open(in6_addr ip,port_t port,bool skip_socks)
00193 {
00194 Ipv6Address ad(ip, port);
00195 return Open(ad, skip_socks);
00196 }
00197 #endif
00198 #endif
00199
00200
00201 bool TcpSocket::Open(SocketAddress& ad,bool skip_socks)
00202 {
00203 Ipv4Address bind_ad("0.0.0.0", 0);
00204 return Open(ad, bind_ad, skip_socks);
00205 }
00206
00207
00208 bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks)
00209 {
00210 if (!ad.IsValid())
00211 {
00212 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL);
00213 SetCloseAndDelete();
00214 return false;
00215 }
00216 if (Handler().GetCount() >= Handler().MaxCount())
00217 {
00218 Handler().LogError(this, "Open", 0, "no space left for more sockets", LOG_LEVEL_FATAL);
00219 SetCloseAndDelete();
00220 return false;
00221 }
00222 SetConnecting(false);
00223 #ifdef ENABLE_SOCKS4
00224 SetSocks4(false);
00225 #endif
00226
00227 #ifdef ENABLE_POOL
00228 if (Handler().PoolEnabled())
00229 {
00230 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad);
00231 if (pools)
00232 {
00233 CopyConnection( pools );
00234 delete pools;
00235
00236 SetIsClient();
00237 SetCallOnConnect();
00238 Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO);
00239 return true;
00240 }
00241 }
00242 #endif
00243
00244 SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp");
00245 if (s == INVALID_SOCKET)
00246 {
00247 return false;
00248 }
00249
00250 if (!SetNonblocking(true, s))
00251 {
00252 SetCloseAndDelete();
00253 closesocket(s);
00254 return false;
00255 }
00256 #ifdef ENABLE_POOL
00257 SetIsClient();
00258 #endif
00259 SetClientRemoteAddress(ad);
00260 int n = 0;
00261 if (bind_ad.GetPort() != 0)
00262 {
00263 bind(s, bind_ad, bind_ad);
00264 }
00265 #ifdef ENABLE_SOCKS4
00266 if (!skip_socks && GetSocks4Host() && GetSocks4Port())
00267 {
00268 Ipv4Address sa(GetSocks4Host(), GetSocks4Port());
00269 {
00270 std::string sockshost;
00271 Utility::l2ip(GetSocks4Host(), sockshost);
00272 Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" +
00273 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO);
00274 }
00275 SetSocks4();
00276 n = connect(s, sa, sa);
00277 SetRemoteAddress(sa);
00278 }
00279 else
00280 #endif
00281 {
00282 n = connect(s, ad, ad);
00283 SetRemoteAddress(ad);
00284 }
00285 if (n == -1)
00286 {
00287
00288 #ifdef _WIN32
00289 if (Errno == WSAEWOULDBLOCK)
00290 #else
00291 if (Errno == EINPROGRESS)
00292 #endif
00293 {
00294 Attach(s);
00295 SetConnecting( true );
00296 }
00297 else
00298 #ifdef ENABLE_SOCKS4
00299 if (Socks4() && Handler().Socks4TryDirect() )
00300 {
00301 closesocket(s);
00302 return Open(ad, true);
00303 }
00304 else
00305 #endif
00306 #ifdef ENABLE_RECONNECT
00307 if (Reconnect())
00308 {
00309 Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
00310 Attach(s);
00311 SetConnecting( true );
00312 }
00313 else
00314 #endif
00315 {
00316 Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00317 SetCloseAndDelete();
00318 closesocket(s);
00319 return false;
00320 }
00321 }
00322 else
00323 {
00324 Attach(s);
00325 SetCallOnConnect();
00326 }
00327
00328
00329
00330 return true;
00331 }
00332
00333
00334 bool TcpSocket::Open(const std::string &host,port_t port)
00335 {
00336 #ifdef ENABLE_IPV6
00337 #ifdef IPPROTO_IPV6
00338 if (IsIpv6())
00339 {
00340 #ifdef ENABLE_RESOLVER
00341 if (!Handler().ResolverEnabled() || Utility::isipv6(host) )
00342 {
00343 #endif
00344 in6_addr a;
00345 if (!Utility::u2ip(host, a))
00346 {
00347 SetCloseAndDelete();
00348 return false;
00349 }
00350 Ipv6Address ad(a, port);
00351 Ipv6Address local;
00352 return Open(ad, local);
00353 #ifdef ENABLE_RESOLVER
00354 }
00355 m_resolver_id = Resolve6(host, port);
00356 return true;
00357 #endif
00358 }
00359 #endif
00360 #endif
00361 #ifdef ENABLE_RESOLVER
00362 if (!Handler().ResolverEnabled() || Utility::isipv4(host) )
00363 {
00364 #endif
00365 ipaddr_t l;
00366 if (!Utility::u2ip(host,l))
00367 {
00368 SetCloseAndDelete();
00369 return false;
00370 }
00371 Ipv4Address ad(l, port);
00372 Ipv4Address local;
00373 return Open(ad, local);
00374 #ifdef ENABLE_RESOLVER
00375 }
00376
00377 m_resolver_id = Resolve(host, port);
00378 return true;
00379 #endif
00380 }
00381
00382
00383 #ifdef ENABLE_RESOLVER
00384 void TcpSocket::OnResolved(int id,ipaddr_t a,port_t port)
00385 {
00386 DEB( fprintf(stderr, "TcpSocket::OnResolved id %d addr %x port %d\n", id, a, port);)
00387 if (id == m_resolver_id)
00388 {
00389 if (a && port)
00390 {
00391 Ipv4Address ad(a, port);
00392 Ipv4Address local;
00393 if (Open(ad, local))
00394 {
00395 if (!Handler().Valid(this))
00396 {
00397 Handler().Add(this);
00398 }
00399 }
00400 }
00401 else
00402 {
00403 Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL);
00404 SetCloseAndDelete();
00405 }
00406 }
00407 else
00408 {
00409 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL);
00410 SetCloseAndDelete();
00411 }
00412 }
00413
00414
00415 #ifdef ENABLE_IPV6
00416 void TcpSocket::OnResolved(int id,in6_addr& a,port_t port)
00417 {
00418 if (id == m_resolver_id)
00419 {
00420 Ipv6Address ad(a, port);
00421 if (ad.IsValid())
00422 {
00423 Ipv6Address local;
00424 if (Open(ad, local))
00425 {
00426 if (!Handler().Valid(this))
00427 {
00428 Handler().Add(this);
00429 }
00430 }
00431 }
00432 }
00433 else
00434 {
00435 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL);
00436 SetCloseAndDelete();
00437 }
00438 }
00439 #endif
00440 #endif
00441
00442
00443 void TcpSocket::OnRead()
00444 {
00445 int n = 0;
00446 #ifdef SOCKETS_DYNAMIC_TEMP
00447 char *buf = m_buf;
00448 #else
00449 char buf[TCP_BUFSIZE_READ];
00450 #endif
00451 #ifdef HAVE_OPENSSL
00452 if (IsSSL())
00453 {
00454 if (!Ready())
00455 return;
00456 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ);
00457 if (n == -1)
00458 {
00459 n = SSL_get_error(m_ssl, n);
00460 switch (n)
00461 {
00462 case SSL_ERROR_NONE:
00463 case SSL_ERROR_WANT_READ:
00464 case SSL_ERROR_WANT_WRITE:
00465 break;
00466 case SSL_ERROR_ZERO_RETURN:
00467 DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");)
00468 OnDisconnect();
00469 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n);
00470 SetCloseAndDelete(true);
00471 SetFlushBeforeClose(false);
00472 SetLost();
00473 break;
00474 default:
00475 DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);)
00476 OnDisconnect();
00477 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n);
00478 SetCloseAndDelete(true);
00479 SetFlushBeforeClose(false);
00480 SetLost();
00481 }
00482 return;
00483 }
00484 else
00485 if (!n)
00486 {
00487 DEB( n = SSL_get_error(m_ssl, n);
00488 fprintf(stderr, "SSL_read returns 0, SSL_get_error: %d\n", n);
00489 if (n == SSL_ERROR_SYSCALL)
00490 {
00491 fprintf(stderr, "ERR_get_error() returns %ld\n", ERR_get_error());
00492 perror("errno: SSL_read");
00493 })
00494 OnDisconnect();
00495 OnDisconnect(TCP_DISCONNECT_SSL, 0);
00496 SetCloseAndDelete(true);
00497 SetFlushBeforeClose(false);
00498 SetLost();
00499 SetShutdown(SHUT_WR);
00500 return;
00501 }
00502 else
00503 if (n > 0 && n <= TCP_BUFSIZE_READ)
00504 {
00505 m_bytes_received += n;
00506 if (GetTrafficMonitor())
00507 {
00508 GetTrafficMonitor() -> fwrite(buf, 1, n);
00509 }
00510 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00511 {
00512 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00513 }
00514 }
00515 else
00516 {
00517 Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR);
00518 }
00519 }
00520 else
00521 #endif // HAVE_OPENSSL
00522 {
00523 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL);
00524 if (n == -1)
00525 {
00526 Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00527 OnDisconnect();
00528 OnDisconnect(TCP_DISCONNECT_ERROR, Errno);
00529 SetCloseAndDelete(true);
00530 SetFlushBeforeClose(false);
00531 SetLost();
00532 return;
00533 }
00534 else
00535 if (!n)
00536 {
00537 OnDisconnect();
00538 OnDisconnect(0, 0);
00539 SetCloseAndDelete(true);
00540 SetFlushBeforeClose(false);
00541 SetLost();
00542 SetShutdown(SHUT_WR);
00543 return;
00544 }
00545 else
00546 if (n > 0 && n <= TCP_BUFSIZE_READ)
00547 {
00548 m_bytes_received += n;
00549 if (GetTrafficMonitor())
00550 {
00551 GetTrafficMonitor() -> fwrite(buf, 1, n);
00552 }
00553 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00554 {
00555 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00556 }
00557 }
00558 else
00559 {
00560 Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR);
00561 }
00562 }
00563
00564 OnRead( buf, n );
00565 }
00566
00567
00568 void TcpSocket::OnRead( char *buf, size_t n )
00569 {
00570
00571 if (n > 0 && n <= TCP_BUFSIZE_READ)
00572 {
00573 if (LineProtocol())
00574 {
00575 buf[n] = 0;
00576 size_t i = 0;
00577 if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c)
00578 {
00579 m_skip_c = false;
00580 i++;
00581 }
00582 size_t x = i;
00583 for (; i < n && LineProtocol(); i++)
00584 {
00585 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol())
00586 {
00587 char c = buf[i];
00588 buf[i] = 0;
00589 if (buf[x])
00590 {
00591 size_t sz = strlen(&buf[x]);
00592 if (m_line_ptr + sz < Handler().MaxTcpLineSize())
00593 {
00594 memcpy(&m_line[m_line_ptr], &buf[x], sz);
00595 m_line_ptr += sz;
00596 }
00597 else
00598 {
00599 Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL);
00600 SetCloseAndDelete();
00601 }
00602 }
00603 if (m_line_ptr > 0)
00604 OnLine( std::string(&m_line[0], m_line_ptr) );
00605 else
00606 OnLine( "" );
00607 i++;
00608 m_skip_c = true;
00609 m_c = c;
00610 if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c)
00611 {
00612 m_skip_c = false;
00613 i++;
00614 }
00615 x = i;
00616 m_line_ptr = 0;
00617 }
00618 if (!LineProtocol())
00619 {
00620 break;
00621 }
00622 }
00623 if (!LineProtocol())
00624 {
00625 if (i < n)
00626 {
00627 OnRawData(buf + i, n - i);
00628 }
00629 }
00630 else
00631 if (buf[x])
00632 {
00633 size_t sz = strlen(&buf[x]);
00634 if (m_line_ptr + sz < Handler().MaxTcpLineSize())
00635 {
00636 memcpy(&m_line[m_line_ptr], &buf[x], sz);
00637 m_line_ptr += sz;
00638 }
00639 else
00640 {
00641 Handler().LogError(this, "TcpSocket::OnRead", (int)(m_line_ptr + sz), "maximum tcp_line_size exceeded, connection closed", LOG_LEVEL_FATAL);
00642 SetCloseAndDelete();
00643 }
00644 }
00645 }
00646 else
00647 {
00648 OnRawData(buf, n);
00649 }
00650 }
00651 if (m_b_input_buffer_disabled)
00652 {
00653 return;
00654 }
00655
00656 #ifdef ENABLE_SOCKS4
00657 if (Socks4())
00658 {
00659 bool need_more = false;
00660 while (GetInputLength() && !need_more && !CloseAndDelete())
00661 {
00662 need_more = OnSocks4Read();
00663 }
00664 }
00665 #endif
00666 }
00667
00668
00669 void TcpSocket::OnWriteComplete()
00670 {
00671 }
00672
00673
00674 void TcpSocket::OnWrite()
00675 {
00676 if (Connecting())
00677 {
00678 int err = SoError();
00679
00680
00681 if (!err)
00682 {
00683 Handler().ISocketHandler_Mod(this, !IsDisableRead(), false);
00684 SetConnecting(false);
00685 SetCallOnConnect();
00686 return;
00687 }
00688 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL);
00689 Handler().ISocketHandler_Mod(this, false, false);
00690
00691
00692 #ifdef ENABLE_SOCKS4
00693 if (Socks4())
00694 {
00695
00696 OnSocks4ConnectFailed();
00697 return;
00698 }
00699 #endif
00700 if (GetConnectionRetry() == -1 ||
00701 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
00702 {
00703
00704
00705
00706
00707 return;
00708 }
00709 SetConnecting(false);
00710 SetCloseAndDelete( true );
00712 OnConnectFailed();
00713 return;
00714 }
00715
00716 SendFromOutputBuffer();
00717 }
00718
00719
00720 void TcpSocket::SendFromOutputBuffer()
00721 {
00722
00723
00724
00725
00726 bool repeat = false;
00727 size_t sz = m_transfer_limit ? GetOutputLength() : 0;
00728 do
00729 {
00730 if (m_obuf.empty())
00731 {
00732 Handler().LogError(this, "OnWrite", (int)m_output_length, "Empty output buffer in OnWrite", LOG_LEVEL_ERROR);
00733 break;
00734 }
00735 output_l::iterator it = m_obuf.begin();
00736 OUTPUT *p = *it;
00737 repeat = false;
00738 int n = TryWrite(p -> Buf(), p -> Len());
00739 if (n > 0)
00740 {
00741 size_t left = p -> Remove(n);
00742 m_output_length -= n;
00743 if (!left)
00744 {
00745 delete p;
00746 m_obuf.erase(it);
00747 if (!m_obuf.size())
00748 {
00749 m_obuf_top = NULL;
00750 OnWriteComplete();
00751 }
00752 else
00753 {
00754 repeat = true;
00755 }
00756 }
00757 }
00758 } while (repeat);
00759
00760 if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit)
00761 {
00762 OnTransferLimit();
00763 }
00764
00765
00766 {
00767 bool br = !IsDisableRead();
00768 if (m_obuf.size())
00769 Handler().ISocketHandler_Mod(this, br, true);
00770 else
00771 Handler().ISocketHandler_Mod(this, br, false);
00772 }
00773 }
00774
00775
00776 int TcpSocket::TryWrite(const char *buf, size_t len)
00777 {
00778 int n = 0;
00779 #ifdef HAVE_OPENSSL
00780 if (IsSSL())
00781 {
00782 n = SSL_write(m_ssl, buf, (int)(m_repeat_length ? m_repeat_length : len));
00783 if (n == -1)
00784 {
00785 int errnr = SSL_get_error(m_ssl, n);
00786 if ( errnr == SSL_ERROR_WANT_READ || errnr == SSL_ERROR_WANT_WRITE )
00787 {
00788 m_repeat_length = m_repeat_length ? m_repeat_length : len;
00789 }
00790 else
00791 {
00792 OnDisconnect();
00793 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR|TCP_DISCONNECT_SSL, errnr);
00794 SetCloseAndDelete(true);
00795 SetFlushBeforeClose(false);
00796 SetLost();
00797 {
00798 char errbuf[256];
00799 ERR_error_string_n(errnr, errbuf, 256);
00800 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL);
00801 }
00802 }
00803 return 0;
00804 }
00805 else
00806 if (!n)
00807 {
00808 OnDisconnect();
00809 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_SSL, 0);
00810 SetCloseAndDelete(true);
00811 SetFlushBeforeClose(false);
00812 SetLost();
00813 }
00814 m_repeat_length = 0;
00815 }
00816 else
00817 #endif // HAVE_OPENSSL
00818 {
00819 n = send(GetSocket(), buf, (int)len, MSG_NOSIGNAL);
00820 if (n == -1)
00821 {
00822
00823
00824
00825 #ifdef _WIN32
00826 if (Errno != WSAEWOULDBLOCK)
00827 #else
00828 if (Errno != EWOULDBLOCK)
00829 #endif
00830 {
00831 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00832 OnDisconnect();
00833 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR, Errno);
00834 SetCloseAndDelete(true);
00835 SetFlushBeforeClose(false);
00836 SetLost();
00837 }
00838 return 0;
00839 }
00840 }
00841 if (n > 0)
00842 {
00843 m_bytes_sent += n;
00844 if (GetTrafficMonitor())
00845 {
00846 GetTrafficMonitor() -> fwrite(buf, 1, n);
00847 }
00848 }
00849 return n;
00850 }
00851
00852
00853 void TcpSocket::Buffer(const char *buf, size_t len)
00854 {
00855 size_t ptr = 0;
00856 m_output_length += len;
00857 while (ptr < len)
00858 {
00859
00860 size_t space = 0;
00861 if ((space = m_obuf_top ? m_obuf_top -> Space() : 0) > 0)
00862 {
00863 const char *pbuf = buf + ptr;
00864 size_t sz = len - ptr;
00865 if (space >= sz)
00866 {
00867 m_obuf_top -> Add(pbuf, sz);
00868 ptr += sz;
00869 }
00870 else
00871 {
00872 m_obuf_top -> Add(pbuf, space);
00873 ptr += space;
00874 }
00875 }
00876 else
00877 {
00878 m_obuf_top = new OUTPUT;
00879 m_obuf.push_back( m_obuf_top );
00880 }
00881 }
00882 }
00883
00884
00885 void TcpSocket::Send(const std::string &str,int i)
00886 {
00887 SendBuf(str.c_str(),str.size(),i);
00888 }
00889
00890
00891 void TcpSocket::SendBuf(const char *buf,size_t len,int)
00892 {
00893 if (!Ready() && !Connecting())
00894 {
00895 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" );
00896 if (GetSocket() == INVALID_SOCKET)
00897 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO);
00898 if (Connecting())
00899 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO);
00900 if (CloseAndDelete())
00901 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO);
00902 return;
00903 }
00904 if (!IsConnected())
00905 {
00906 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" );
00907 Buffer(buf, len);
00908 return;
00909 }
00910 if (m_obuf_top)
00911 {
00912 Buffer(buf, len);
00913 return;
00914 }
00915 #ifdef HAVE_OPENSSL
00916 if (IsSSL())
00917 {
00918 Buffer(buf, len);
00919 SendFromOutputBuffer();
00920 return;
00921 }
00922 #endif
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 = !IsDisableRead();
00939 if (m_obuf.size())
00940 Handler().ISocketHandler_Mod(this, br, true);
00941 else
00942 Handler().ISocketHandler_Mod(this, br, false);
00943 }
00944 }
00945
00946
00947 void TcpSocket::OnLine(const std::string& )
00948 {
00949 }
00950
00951
00952 #ifdef _MSC_VER
00953 #pragma warning(disable:4355)
00954 #endif
00955 TcpSocket::TcpSocket(const TcpSocket& s)
00956 :StreamSocket(s)
00957 ,ibuf(0)
00958 {
00959 }
00960 #ifdef _MSC_VER
00961 #pragma warning(default:4355)
00962 #endif
00963
00964
00965 #ifdef ENABLE_SOCKS4
00966 void TcpSocket::OnSocks4Connect()
00967 {
00968 char request[1000];
00969 memset(request, 0, sizeof(request));
00970 request[0] = 4;
00971 request[1] = 1;
00972 {
00973 std::auto_ptr<SocketAddress> ad = GetClientRemoteAddress();
00974 if (ad.get())
00975 {
00976 struct sockaddr *p0 = (struct sockaddr *)*ad;
00977 struct sockaddr_in *p = (struct sockaddr_in *)p0;
00978 if (p -> sin_family == AF_INET)
00979 {
00980 memcpy(request + 2, &p -> sin_port, 2);
00981 memcpy(request + 4, &p -> sin_addr, sizeof(struct in_addr));
00982 }
00983 else
00984 {
00986 }
00987 }
00988 else
00989 {
00991 }
00992 }
00993 #if defined( _WIN32) && !defined(__CYGWIN__)
00994 strcpy_s(request + 8, sizeof(request) - 8, GetSocks4Userid().c_str());
00995 #else
00996 strcpy(request + 8, GetSocks4Userid().c_str());
00997 #endif
00998 size_t length = GetSocks4Userid().size() + 8 + 1;
00999 SendBuf(request, length);
01000 m_socks4_state = 0;
01001 }
01002
01003
01004 void TcpSocket::OnSocks4ConnectFailed()
01005 {
01006 Handler().LogError(this,"OnSocks4ConnectFailed",0,"connection to socks4 server failed, trying direct connection",LOG_LEVEL_WARNING);
01007 if (!Handler().Socks4TryDirect())
01008 {
01009 SetConnecting(false);
01010 SetCloseAndDelete();
01011 OnConnectFailed();
01012 }
01013 else
01014 {
01015 SetRetryClientConnect();
01016 }
01017 }
01018
01019
01020 bool TcpSocket::OnSocks4Read()
01021 {
01022 switch (m_socks4_state)
01023 {
01024 case 0:
01025 ibuf.Read(&m_socks4_vn, 1);
01026 m_socks4_state = 1;
01027 break;
01028 case 1:
01029 ibuf.Read(&m_socks4_cd, 1);
01030 m_socks4_state = 2;
01031 break;
01032 case 2:
01033 if (GetInputLength() > 1)
01034 {
01035 ibuf.Read( (char *)&m_socks4_dstport, 2);
01036 m_socks4_state = 3;
01037 }
01038 else
01039 {
01040 return true;
01041 }
01042 break;
01043 case 3:
01044 if (GetInputLength() > 3)
01045 {
01046 ibuf.Read( (char *)&m_socks4_dstip, 4);
01047 SetSocks4(false);
01048
01049 switch (m_socks4_cd)
01050 {
01051 case 90:
01052 OnConnect();
01053 Handler().LogError(this, "OnSocks4Read", 0, "Connection established", LOG_LEVEL_INFO);
01054 break;
01055 case 91:
01056 case 92:
01057 case 93:
01058 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server reports connect failed",LOG_LEVEL_FATAL);
01059 SetConnecting(false);
01060 SetCloseAndDelete();
01061 OnConnectFailed();
01062 break;
01063 default:
01064 Handler().LogError(this,"OnSocks4Read",m_socks4_cd,"socks4 server unrecognized response",LOG_LEVEL_FATAL);
01065 SetCloseAndDelete();
01066 break;
01067 }
01068 }
01069 else
01070 {
01071 return true;
01072 }
01073 break;
01074 }
01075 return false;
01076 }
01077 #endif
01078
01079
01080 void TcpSocket::Sendf(const char *format, ...)
01081 {
01082 va_list ap;
01083 va_start(ap, format);
01084 char slask[5000];
01085 vsnprintf(slask, sizeof(slask), format, ap);
01086 va_end(ap);
01087 Send( slask );
01088 }
01089
01090
01091 #ifdef HAVE_OPENSSL
01092 void TcpSocket::OnSSLConnect()
01093 {
01094 SetNonblocking(true);
01095 {
01096 if (m_ssl_ctx)
01097 {
01098 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");)
01099 SetCloseAndDelete(true);
01100 return;
01101 }
01102 InitSSLClient();
01103 }
01104 if (m_ssl_ctx)
01105 {
01106
01107 m_ssl = SSL_new(m_ssl_ctx);
01108 if (!m_ssl)
01109 {
01110 DEB( fprintf(stderr, " m_ssl is NULL\n");)
01111 SetCloseAndDelete(true);
01112 return;
01113 }
01114 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE);
01115 if (!m_sbio)
01116 {
01117 DEB( fprintf(stderr, " m_sbio is NULL\n");)
01118 SetCloseAndDelete(true);
01119 return;
01120 }
01121 SSL_set_bio(m_ssl, m_sbio, m_sbio);
01122 if (!SSLNegotiate())
01123 {
01124 SetSSLNegotiate();
01125 }
01126 }
01127 else
01128 {
01129 SetCloseAndDelete();
01130 }
01131 }
01132
01133
01134 void TcpSocket::OnSSLAccept()
01135 {
01136 SetNonblocking(true);
01137 {
01138 if (m_ssl_ctx)
01139 {
01140 DEB( fprintf(stderr, "SSL Context already initialized - closing socket\n");)
01141 SetCloseAndDelete(true);
01142 return;
01143 }
01144 InitSSLServer();
01145 SetSSLServer();
01146 }
01147 if (m_ssl_ctx)
01148 {
01149 m_ssl = SSL_new(m_ssl_ctx);
01150 if (!m_ssl)
01151 {
01152 DEB( fprintf(stderr, " m_ssl is NULL\n");)
01153 SetCloseAndDelete(true);
01154 return;
01155 }
01156 m_sbio = BIO_new_socket((int)GetSocket(), BIO_NOCLOSE);
01157 if (!m_sbio)
01158 {
01159 DEB( fprintf(stderr, " m_sbio is NULL\n");)
01160 SetCloseAndDelete(true);
01161 return;
01162 }
01163 SSL_set_bio(m_ssl, m_sbio, m_sbio);
01164
01165 {
01166 SetSSLNegotiate();
01167 }
01168 }
01169 }
01170
01171
01172 bool TcpSocket::SSLNegotiate()
01173 {
01174 if (!IsSSLServer())
01175 {
01176 int r = SSL_connect(m_ssl);
01177 if (r > 0)
01178 {
01179 SetSSLNegotiate(false);
01181
01182 SetConnected();
01183 if (GetOutputLength())
01184 {
01185 OnWrite();
01186 }
01187 #ifdef ENABLE_RECONNECT
01188 if (IsReconnect())
01189 {
01190 OnReconnect();
01191 }
01192 else
01193 #endif
01194 {
01195 OnConnect();
01196 }
01197 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection established", LOG_LEVEL_INFO);
01198 return true;
01199 }
01200 else
01201 if (!r)
01202 {
01203 Handler().LogError(this, "SSLNegotiate/SSL_connect", 0, "Connection failed", LOG_LEVEL_INFO);
01204 SetSSLNegotiate(false);
01205 SetCloseAndDelete();
01206 OnSSLConnectFailed();
01207 }
01208 else
01209 {
01210 r = SSL_get_error(m_ssl, r);
01211 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
01212 {
01213 Handler().LogError(this, "SSLNegotiate/SSL_connect", -1, "Connection failed", LOG_LEVEL_INFO);
01214 DEB( fprintf(stderr, "SSL_connect() failed - closing socket, return code: %d\n",r);)
01215 SetSSLNegotiate(false);
01216 SetCloseAndDelete(true);
01217 OnSSLConnectFailed();
01218 }
01219 }
01220 }
01221 else
01222 {
01223 int r = SSL_accept(m_ssl);
01224 if (r > 0)
01225 {
01226 SetSSLNegotiate(false);
01228
01229 SetConnected();
01230 if (GetOutputLength())
01231 {
01232 OnWrite();
01233 }
01234 OnAccept();
01235 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection established", LOG_LEVEL_INFO);
01236 return true;
01237 }
01238 else
01239 if (!r)
01240 {
01241 Handler().LogError(this, "SSLNegotiate/SSL_accept", 0, "Connection failed", LOG_LEVEL_INFO);
01242 SetSSLNegotiate(false);
01243 SetCloseAndDelete();
01244 OnSSLAcceptFailed();
01245 }
01246 else
01247 {
01248 r = SSL_get_error(m_ssl, r);
01249 if (r != SSL_ERROR_WANT_READ && r != SSL_ERROR_WANT_WRITE)
01250 {
01251 Handler().LogError(this, "SSLNegotiate/SSL_accept", -1, "Connection failed", LOG_LEVEL_INFO);
01252 DEB( fprintf(stderr, "SSL_accept() failed - closing socket, return code: %d\n",r);)
01253 SetSSLNegotiate(false);
01254 SetCloseAndDelete(true);
01255 OnSSLAcceptFailed();
01256 }
01257 }
01258 }
01259 return false;
01260 }
01261
01262
01263 void TcpSocket::InitSSLClient()
01264 {
01265 InitializeContext("", SSLv23_method());
01266 }
01267
01268
01269 void TcpSocket::InitSSLServer()
01270 {
01271 Handler().LogError(this, "InitSSLServer", 0, "You MUST implement your own InitSSLServer method", LOG_LEVEL_FATAL);
01272 SetCloseAndDelete();
01273 }
01274
01275
01276 void TcpSocket::InitializeContext(const std::string& context, const SSL_METHOD *meth_in)
01277 {
01278 static Mutex mutex;
01279 Lock lock(mutex);
01280
01281 if (m_client_contexts.find(context) == m_client_contexts.end())
01282 {
01283 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01284 m_ssl_ctx = m_client_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(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 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01301 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(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 const SSL_METHOD *meth = meth_in ? meth_in : SSLv3_method();
01337 m_ssl_ctx = m_server_contexts[context] = SSL_CTX_new(const_cast<SSL_METHOD *>(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