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 #ifdef _MSC_VER
00032 #pragma warning(disable:4786)
00033 #endif
00034 #include <stdlib.h>
00035 #else
00036 #include <errno.h>
00037 #endif
00038 #include "ISocketHandler.h"
00039 #include <fcntl.h>
00040 #include <assert.h>
00041 #include <stdarg.h>
00042 #ifdef HAVE_OPENSSL
00043 #include <openssl/rand.h>
00044 #include <openssl/err.h>
00045 #endif
00046 #include <map>
00047
00048 #include "TcpSocket.h"
00049 #include "Utility.h"
00050 #include "Ipv4Address.h"
00051 #include "Ipv6Address.h"
00052 #include "IFile.h"
00053 #include "Lock.h"
00054
00055 #ifdef SOCKETS_NAMESPACE
00056 namespace SOCKETS_NAMESPACE {
00057 #endif
00058
00059
00060 #ifdef _DEBUG
00061 #define DEB(x) x
00062 #else
00063 #define DEB(x)
00064 #endif
00065
00066
00067
00068 #ifdef HAVE_OPENSSL
00069 SSLInitializer TcpSocket::m_ssl_init;
00070 Mutex TcpSocket::m_server_ssl_mutex;
00071 std::map<std::string, SSL_CTX *> TcpSocket::m_client_contexts;
00072 std::map<std::string, SSL_CTX *> TcpSocket::m_server_contexts;
00073 #endif
00074
00075
00076
00077 #ifdef _MSC_VER
00078 #pragma warning(disable:4355)
00079 #endif
00080 TcpSocket::TcpSocket(ISocketHandler& h) : StreamSocket(h)
00081 ,ibuf(TCP_BUFSIZE_READ)
00082 ,m_b_input_buffer_disabled(false)
00083 ,m_bytes_sent(0)
00084 ,m_bytes_received(0)
00085 ,m_skip_c(false)
00086 #ifdef SOCKETS_DYNAMIC_TEMP
00087 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00088 #endif
00089 ,m_obuf_top(NULL)
00090 ,m_transfer_limit(0)
00091 ,m_output_length(0)
00092 #ifdef HAVE_OPENSSL
00093 ,m_ssl_ctx(NULL)
00094 ,m_ssl(NULL)
00095 ,m_sbio(NULL)
00096 #endif
00097 #ifdef ENABLE_SOCKS4
00098 ,m_socks4_state(0)
00099 #endif
00100 #ifdef ENABLE_RESOLVER
00101 ,m_resolver_id(0)
00102 #endif
00103 #ifdef ENABLE_RECONNECT
00104 ,m_b_reconnect(false)
00105 ,m_b_is_reconnect(false)
00106 #endif
00107 {
00108 }
00109 #ifdef _MSC_VER
00110 #pragma warning(default:4355)
00111 #endif
00112
00113
00114 #ifdef _MSC_VER
00115 #pragma warning(disable:4355)
00116 #endif
00117 TcpSocket::TcpSocket(ISocketHandler& h,size_t isize,size_t osize) : StreamSocket(h)
00118 ,ibuf(isize)
00119 ,m_b_input_buffer_disabled(false)
00120 ,m_bytes_sent(0)
00121 ,m_bytes_received(0)
00122 ,m_skip_c(false)
00123 #ifdef SOCKETS_DYNAMIC_TEMP
00124 ,m_buf(new char[TCP_BUFSIZE_READ + 1])
00125 #endif
00126 ,m_obuf_top(NULL)
00127 ,m_transfer_limit(0)
00128 ,m_output_length(0)
00129 #ifdef HAVE_OPENSSL
00130 ,m_ssl_ctx(NULL)
00131 ,m_ssl(NULL)
00132 ,m_sbio(NULL)
00133 #endif
00134 #ifdef ENABLE_SOCKS4
00135 ,m_socks4_state(0)
00136 #endif
00137 #ifdef ENABLE_RESOLVER
00138 ,m_resolver_id(0)
00139 #endif
00140 #ifdef ENABLE_RECONNECT
00141 ,m_b_reconnect(false)
00142 ,m_b_is_reconnect(false)
00143 #endif
00144 {
00145 }
00146 #ifdef _MSC_VER
00147 #pragma warning(default:4355)
00148 #endif
00149
00150
00151 TcpSocket::~TcpSocket()
00152 {
00153 #ifdef SOCKETS_DYNAMIC_TEMP
00154 delete[] m_buf;
00155 #endif
00156
00157 while (m_obuf.size())
00158 {
00159 output_l::iterator it = m_obuf.begin();
00160 OUTPUT *p = *it;
00161 delete p;
00162 m_obuf.erase(it);
00163 }
00164 #ifdef HAVE_OPENSSL
00165 if (m_ssl)
00166 {
00167 SSL_free(m_ssl);
00168 }
00169 #endif
00170 }
00171
00172
00173 bool TcpSocket::Open(ipaddr_t ip,port_t port,bool skip_socks)
00174 {
00175 Ipv4Address ad(ip, port);
00176 Ipv4Address local;
00177 return Open(ad, local, skip_socks);
00178 }
00179
00180
00181 #ifdef ENABLE_IPV6
00182 #ifdef IPPROTO_IPV6
00183 bool TcpSocket::Open(in6_addr ip,port_t port,bool skip_socks)
00184 {
00185 Ipv6Address ad(ip, port);
00186 return Open(ad, skip_socks);
00187 }
00188 #endif
00189 #endif
00190
00191
00192 bool TcpSocket::Open(SocketAddress& ad,bool skip_socks)
00193 {
00194 Ipv4Address bind_ad("0.0.0.0", 0);
00195 return Open(ad, bind_ad, skip_socks);
00196 }
00197
00198
00199 bool TcpSocket::Open(SocketAddress& ad,SocketAddress& bind_ad,bool skip_socks)
00200 {
00201 if (!ad.IsValid())
00202 {
00203 Handler().LogError(this, "Open", 0, "Invalid SocketAddress", LOG_LEVEL_FATAL);
00204 SetCloseAndDelete();
00205 return false;
00206 }
00207 if (Handler().GetCount() >= FD_SETSIZE)
00208 {
00209 Handler().LogError(this, "Open", 0, "no space left in fd_set", LOG_LEVEL_FATAL);
00210 SetCloseAndDelete();
00211 return false;
00212 }
00213 SetConnecting(false);
00214 #ifdef ENABLE_SOCKS4
00215 SetSocks4(false);
00216 #endif
00217
00218 #ifdef ENABLE_POOL
00219 if (Handler().PoolEnabled())
00220 {
00221 ISocketHandler::PoolSocket *pools = Handler().FindConnection(SOCK_STREAM, "tcp", ad);
00222 if (pools)
00223 {
00224 CopyConnection( pools );
00225 delete pools;
00226
00227 SetIsClient();
00228 SetCallOnConnect();
00229 Handler().LogError(this, "SetCallOnConnect", 0, "Found pooled connection", LOG_LEVEL_INFO);
00230 return true;
00231 }
00232 }
00233 #endif
00234
00235 SOCKET s = CreateSocket(ad.GetFamily(), SOCK_STREAM, "tcp");
00236 if (s == INVALID_SOCKET)
00237 {
00238 return false;
00239 }
00240
00241 if (!SetNonblocking(true, s))
00242 {
00243 SetCloseAndDelete();
00244 closesocket(s);
00245 return false;
00246 }
00247 #ifdef ENABLE_POOL
00248 SetIsClient();
00249 #endif
00250 SetClientRemoteAddress(ad);
00251 int n = 0;
00252 if (bind_ad.GetPort() != 0)
00253 {
00254 bind(s, bind_ad, bind_ad);
00255 }
00256 #ifdef ENABLE_SOCKS4
00257 if (!skip_socks && GetSocks4Host() && GetSocks4Port())
00258 {
00259 Ipv4Address sa(GetSocks4Host(), GetSocks4Port());
00260 {
00261 std::string sockshost;
00262 Utility::l2ip(GetSocks4Host(), sockshost);
00263 Handler().LogError(this, "Open", 0, "Connecting to socks4 server @ " + sockshost + ":" +
00264 Utility::l2string(GetSocks4Port()), LOG_LEVEL_INFO);
00265 }
00266 SetSocks4();
00267 n = connect(s, sa, sa);
00268 SetRemoteAddress(sa);
00269 }
00270 else
00271 #endif
00272 {
00273 n = connect(s, ad, ad);
00274 SetRemoteAddress(ad);
00275 }
00276 if (n == -1)
00277 {
00278
00279 #ifdef _WIN32
00280 if (Errno == WSAEWOULDBLOCK)
00281 #else
00282 if (Errno == EINPROGRESS)
00283 #endif
00284 {
00285 Attach(s);
00286 SetConnecting( true );
00287 }
00288 else
00289 #ifdef ENABLE_SOCKS4
00290 if (Socks4() && Handler().Socks4TryDirect() )
00291 {
00292 closesocket(s);
00293 return Open(ad, true);
00294 }
00295 else
00296 #endif
00297 #ifdef ENABLE_RECONNECT
00298 if (Reconnect())
00299 {
00300 Handler().LogError(this, "connect: failed, reconnect pending", Errno, StrError(Errno), LOG_LEVEL_INFO);
00301 Attach(s);
00302 SetConnecting( true );
00303 }
00304 else
00305 #endif
00306 {
00307 Handler().LogError(this, "connect: failed", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00308 SetCloseAndDelete();
00309 closesocket(s);
00310 return false;
00311 }
00312 }
00313 else
00314 {
00315 Attach(s);
00316 SetCallOnConnect();
00317 }
00318
00319
00320
00321 return true;
00322 }
00323
00324
00325 bool TcpSocket::Open(const std::string &host,port_t port)
00326 {
00327 #ifdef ENABLE_IPV6
00328 #ifdef IPPROTO_IPV6
00329 if (IsIpv6())
00330 {
00331 #ifdef ENABLE_RESOLVER
00332 if (!Handler().ResolverEnabled() || Utility::isipv6(host) )
00333 {
00334 #endif
00335 in6_addr a;
00336 if (!Utility::u2ip(host, a))
00337 {
00338 SetCloseAndDelete();
00339 return false;
00340 }
00341 Ipv6Address ad(a, port);
00342 Ipv6Address local;
00343 return Open(ad, local);
00344 #ifdef ENABLE_RESOLVER
00345 }
00346 m_resolver_id = Resolve6(host, port);
00347 return true;
00348 #endif
00349 }
00350 #endif
00351 #endif
00352 #ifdef ENABLE_RESOLVER
00353 if (!Handler().ResolverEnabled() || Utility::isipv4(host) )
00354 {
00355 #endif
00356 ipaddr_t l;
00357 if (!Utility::u2ip(host,l))
00358 {
00359 SetCloseAndDelete();
00360 return false;
00361 }
00362 Ipv4Address ad(l, port);
00363 Ipv4Address local;
00364 return Open(ad, local);
00365 #ifdef ENABLE_RESOLVER
00366 }
00367
00368 m_resolver_id = Resolve(host, port);
00369 return true;
00370 #endif
00371 }
00372
00373
00374 #ifdef ENABLE_RESOLVER
00375 void TcpSocket::OnResolved(int id,ipaddr_t a,port_t port)
00376 {
00377 DEB( fprintf(stderr, "TcpSocket::OnResolved id %d addr %x port %d\n", id, a, port);)
00378 if (id == m_resolver_id)
00379 {
00380 if (a && port)
00381 {
00382 Ipv4Address ad(a, port);
00383 Ipv4Address local;
00384 if (Open(ad, local))
00385 {
00386 if (!Handler().Valid(this))
00387 {
00388 Handler().Add(this);
00389 }
00390 }
00391 }
00392 else
00393 {
00394 Handler().LogError(this, "OnResolved", 0, "Resolver failed", LOG_LEVEL_FATAL);
00395 SetCloseAndDelete();
00396 }
00397 }
00398 else
00399 {
00400 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL);
00401 SetCloseAndDelete();
00402 }
00403 }
00404
00405
00406 #ifdef ENABLE_IPV6
00407 void TcpSocket::OnResolved(int id,in6_addr& a,port_t port)
00408 {
00409 if (id == m_resolver_id)
00410 {
00411 Ipv6Address ad(a, port);
00412 if (ad.IsValid())
00413 {
00414 Ipv6Address local;
00415 if (Open(ad, local))
00416 {
00417 if (!Handler().Valid(this))
00418 {
00419 Handler().Add(this);
00420 }
00421 }
00422 }
00423 }
00424 else
00425 {
00426 Handler().LogError(this, "OnResolved", id, "Resolver returned wrong job id", LOG_LEVEL_FATAL);
00427 SetCloseAndDelete();
00428 }
00429 }
00430 #endif
00431 #endif
00432
00433
00434 void TcpSocket::OnRead()
00435 {
00436 int n = 0;
00437 #ifdef SOCKETS_DYNAMIC_TEMP
00438 char *buf = m_buf;
00439 #else
00440 char buf[TCP_BUFSIZE_READ];
00441 #endif
00442 #ifdef HAVE_OPENSSL
00443 if (IsSSL())
00444 {
00445 if (!Ready())
00446 return;
00447 n = SSL_read(m_ssl, buf, TCP_BUFSIZE_READ);
00448 if (n == -1)
00449 {
00450 n = SSL_get_error(m_ssl, n);
00451 switch (n)
00452 {
00453 case SSL_ERROR_NONE:
00454 case SSL_ERROR_WANT_READ:
00455 case SSL_ERROR_WANT_WRITE:
00456 break;
00457 case SSL_ERROR_ZERO_RETURN:
00458 DEB( fprintf(stderr, "SSL_read() returns zero - closing socket\n");)
00459 OnDisconnect();
00460 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n);
00461 SetCloseAndDelete(true);
00462 SetFlushBeforeClose(false);
00463 SetLost();
00464 break;
00465 default:
00466 DEB( fprintf(stderr, "SSL read problem, errcode = %d\n",n);)
00467 OnDisconnect();
00468 OnDisconnect(TCP_DISCONNECT_SSL|TCP_DISCONNECT_ERROR, n);
00469 SetCloseAndDelete(true);
00470 SetFlushBeforeClose(false);
00471 SetLost();
00472 }
00473 return;
00474 }
00475 else
00476 if (!n)
00477 {
00478 OnDisconnect();
00479 OnDisconnect(TCP_DISCONNECT_SSL, 0);
00480 SetCloseAndDelete(true);
00481 SetFlushBeforeClose(false);
00482 SetLost();
00483 SetShutdown(SHUT_WR);
00484 return;
00485 }
00486 else
00487 if (n > 0 && n <= TCP_BUFSIZE_READ)
00488 {
00489 m_bytes_received += n;
00490 if (GetTrafficMonitor())
00491 {
00492 GetTrafficMonitor() -> fwrite(buf, 1, n);
00493 }
00494 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00495 {
00496 Handler().LogError(this, "OnRead(ssl)", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00497 }
00498 }
00499 else
00500 {
00501 Handler().LogError(this, "OnRead(ssl)", n, "abnormal value from SSL_read", LOG_LEVEL_ERROR);
00502 }
00503 }
00504 else
00505 #endif // HAVE_OPENSSL
00506 {
00507 n = recv(GetSocket(), buf, TCP_BUFSIZE_READ, MSG_NOSIGNAL);
00508 if (n == -1)
00509 {
00510 Handler().LogError(this, "read", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00511 OnDisconnect();
00512 OnDisconnect(TCP_DISCONNECT_ERROR, Errno);
00513 SetCloseAndDelete(true);
00514 SetFlushBeforeClose(false);
00515 SetLost();
00516 return;
00517 }
00518 else
00519 if (!n)
00520 {
00521 OnDisconnect();
00522 OnDisconnect(0, 0);
00523 SetCloseAndDelete(true);
00524 SetFlushBeforeClose(false);
00525 SetLost();
00526 SetShutdown(SHUT_WR);
00527 return;
00528 }
00529 else
00530 if (n > 0 && n <= TCP_BUFSIZE_READ)
00531 {
00532 m_bytes_received += n;
00533 if (GetTrafficMonitor())
00534 {
00535 GetTrafficMonitor() -> fwrite(buf, 1, n);
00536 }
00537 if (!m_b_input_buffer_disabled && !ibuf.Write(buf,n))
00538 {
00539 Handler().LogError(this, "OnRead", 0, "ibuf overflow", LOG_LEVEL_WARNING);
00540 }
00541 }
00542 else
00543 {
00544 Handler().LogError(this, "OnRead", n, "abnormal value from recv", LOG_LEVEL_ERROR);
00545 }
00546 }
00547
00548 OnRead( buf, n );
00549 }
00550
00551
00552 void TcpSocket::OnRead( char *buf, size_t n )
00553 {
00554
00555 if (n > 0 && n <= TCP_BUFSIZE_READ)
00556 {
00557 if (LineProtocol())
00558 {
00559 buf[n] = 0;
00560 size_t i = 0;
00561 if (m_skip_c && (buf[i] == 13 || buf[i] == 10) && buf[i] != m_c)
00562 {
00563 m_skip_c = false;
00564 i++;
00565 }
00566 size_t x = i;
00567 for (; i < n && LineProtocol(); i++)
00568 {
00569 while ((buf[i] == 13 || buf[i] == 10) && LineProtocol())
00570 {
00571 char c = buf[i];
00572 buf[i] = 0;
00573 if (buf[x])
00574 {
00575 m_line += (buf + x);
00576 }
00577 OnLine( m_line );
00578 i++;
00579 m_skip_c = true;
00580 m_c = c;
00581 if (i < n && (buf[i] == 13 || buf[i] == 10) && buf[i] != c)
00582 {
00583 m_skip_c = false;
00584 i++;
00585 }
00586 x = i;
00587 m_line = "";
00588 }
00589 if (!LineProtocol())
00590 {
00591 break;
00592 }
00593 }
00594 if (!LineProtocol())
00595 {
00596 if (i < n)
00597 {
00598 OnRawData(buf + i, n - i);
00599 }
00600 }
00601 else
00602 if (buf[x])
00603 {
00604 m_line += (buf + x);
00605 }
00606 }
00607 else
00608 {
00609 OnRawData(buf, n);
00610 }
00611 }
00612 if (m_b_input_buffer_disabled)
00613 {
00614 return;
00615 }
00616
00617 #ifdef ENABLE_SOCKS4
00618 if (Socks4())
00619 {
00620 bool need_more = false;
00621 while (GetInputLength() && !need_more && !CloseAndDelete())
00622 {
00623 need_more = OnSocks4Read();
00624 }
00625 }
00626 #endif
00627 }
00628
00629
00630 void TcpSocket::OnWriteComplete()
00631 {
00632 }
00633
00634
00635 void TcpSocket::OnWrite()
00636 {
00637 if (Connecting())
00638 {
00639 int err = SoError();
00640
00641
00642 if (!err)
00643 {
00644 Set(!IsDisableRead(), false);
00645 SetConnecting(false);
00646 SetCallOnConnect();
00647 return;
00648 }
00649 Handler().LogError(this, "tcp: connect failed", err, StrError(err), LOG_LEVEL_FATAL);
00650 Set(false, false);
00651
00652
00653 #ifdef ENABLE_SOCKS4
00654 if (Socks4())
00655 {
00656
00657 OnSocks4ConnectFailed();
00658 return;
00659 }
00660 #endif
00661 if (GetConnectionRetry() == -1 ||
00662 (GetConnectionRetry() && GetConnectionRetries() < GetConnectionRetry()) )
00663 {
00664
00665
00666
00667
00668 return;
00669 }
00670 SetConnecting(false);
00671 SetCloseAndDelete( true );
00673 OnConnectFailed();
00674 return;
00675 }
00676
00677
00678
00679
00680 bool repeat = false;
00681 size_t sz = m_transfer_limit ? GetOutputLength() : 0;
00682 do
00683 {
00684 output_l::iterator it = m_obuf.begin();
00685 OUTPUT *p = *it;
00686 repeat = false;
00687 int n = TryWrite(p -> Buf(), p -> Len());
00688 if (n > 0)
00689 {
00690 size_t left = p -> Remove(n);
00691 m_output_length -= n;
00692 if (!left)
00693 {
00694 delete p;
00695 m_obuf.erase(it);
00696 if (!m_obuf.size())
00697 {
00698 m_obuf_top = NULL;
00699 OnWriteComplete();
00700 }
00701 else
00702 {
00703 repeat = true;
00704 }
00705 }
00706 }
00707 } while (repeat);
00708
00709 if (m_transfer_limit && sz > m_transfer_limit && GetOutputLength() < m_transfer_limit)
00710 {
00711 OnTransferLimit();
00712 }
00713
00714
00715 {
00716 bool br;
00717 bool bw;
00718 bool bx;
00719 Handler().Get(GetSocket(), br, bw, bx);
00720 if (m_obuf.size())
00721 Set(br, true);
00722 else
00723 Set(br, false);
00724 }
00725 }
00726
00727
00728 int TcpSocket::TryWrite(const char *buf, size_t len)
00729 {
00730 int n = 0;
00731 #ifdef HAVE_OPENSSL
00732 if (IsSSL())
00733 {
00734 n = SSL_write(m_ssl, buf, (int)len);
00735 if (n == -1)
00736 {
00737 int errnr = SSL_get_error(m_ssl, n);
00738 if ( errnr != SSL_ERROR_WANT_READ && errnr != SSL_ERROR_WANT_WRITE )
00739 {
00740 OnDisconnect();
00741 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR|TCP_DISCONNECT_SSL, errnr);
00742 SetCloseAndDelete(true);
00743 SetFlushBeforeClose(false);
00744 SetLost();
00745 {
00746 char errbuf[256];
00747 ERR_error_string_n(errnr, errbuf, 256);
00748 Handler().LogError(this, "OnWrite/SSL_write", errnr, errbuf, LOG_LEVEL_FATAL);
00749 }
00750 }
00751 return 0;
00752 }
00753 else
00754 if (!n)
00755 {
00756 OnDisconnect();
00757 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_SSL, 0);
00758 SetCloseAndDelete(true);
00759 SetFlushBeforeClose(false);
00760 SetLost();
00761 DEB( {
00762 int errnr = SSL_get_error(m_ssl, n);
00763 char errbuf[256];
00764 ERR_error_string_n(errnr, errbuf, 256);
00765 fprintf(stderr, "SSL_write() returns 0: %d : %s\n",errnr, errbuf);
00766 })
00767 }
00768 }
00769 else
00770 #endif
00771 {
00772 n = send(GetSocket(), buf, (int)len, MSG_NOSIGNAL);
00773 if (n == -1)
00774 {
00775
00776
00777
00778 #ifdef _WIN32
00779 if (Errno != WSAEWOULDBLOCK)
00780 #else
00781 if (Errno != EWOULDBLOCK)
00782 #endif
00783 {
00784 Handler().LogError(this, "send", Errno, StrError(Errno), LOG_LEVEL_FATAL);
00785 OnDisconnect();
00786 OnDisconnect(TCP_DISCONNECT_WRITE|TCP_DISCONNECT_ERROR, Errno);
00787 SetCloseAndDelete(true);
00788 SetFlushBeforeClose(false);
00789 SetLost();
00790 }
00791 return 0;
00792 }
00793 }
00794 if (n > 0)
00795 {
00796 m_bytes_sent += n;
00797 if (GetTrafficMonitor())
00798 {
00799 GetTrafficMonitor() -> fwrite(buf, 1, n);
00800 }
00801 }
00802 return n;
00803 }
00804
00805
00806 void TcpSocket::Buffer(const char *buf, size_t len)
00807 {
00808 size_t ptr = 0;
00809 m_output_length += len;
00810 while (ptr < len)
00811 {
00812
00813 size_t space = 0;
00814 if (m_obuf_top && (space = m_obuf_top -> Space()) > 0)
00815 {
00816 const char *pbuf = buf + ptr;
00817 size_t sz = len - ptr;
00818 if (space >= sz)
00819 {
00820 m_obuf_top -> Add(pbuf, sz);
00821 ptr += sz;
00822 }
00823 else
00824 {
00825 m_obuf_top -> Add(pbuf, space);
00826 ptr += space;
00827 }
00828 }
00829 else
00830 {
00831 m_obuf_top = new OUTPUT;
00832 m_obuf.push_back( m_obuf_top );
00833 }
00834 }
00835 }
00836
00837
00838 void TcpSocket::Send(const std::string &str,int i)
00839 {
00840 SendBuf(str.c_str(),str.size(),i);
00841 }
00842
00843
00844 void TcpSocket::SendBuf(const char *buf,size_t len,int)
00845 {
00846 if (!Ready() && !Connecting())
00847 {
00848 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-ready socket" );
00849 if (GetSocket() == INVALID_SOCKET)
00850 Handler().LogError(this, "SendBuf", 0, " * GetSocket() == INVALID_SOCKET", LOG_LEVEL_INFO);
00851 if (Connecting())
00852 Handler().LogError(this, "SendBuf", 0, " * Connecting()", LOG_LEVEL_INFO);
00853 if (CloseAndDelete())
00854 Handler().LogError(this, "SendBuf", 0, " * CloseAndDelete()", LOG_LEVEL_INFO);
00855 return;
00856 }
00857 if (!IsConnected())
00858 {
00859 Handler().LogError(this, "SendBuf", -1, "Attempt to write to a non-connected socket, will be sent on connect" );
00860 Buffer(buf, len);
00861 return;
00862 }
00863 if (m_obuf_top)
00864 {
00865 Buffer(buf, len);
00866 return;
00867 }
00868 int n = TryWrite(buf, len);
00869 if (n >= 0 && n < (int)len)
00870 {
00871 Buffer(buf + n, len - n);
00872 }
00873
00874
00875
00876
00877
00878
00879
00880
00881
00882 {
00883 bool br;
00884 bool bw;
00885 bool bx;
00886 Handler().Get(GetSocket(), br, bw, bx);
00887 if (