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